648540858
2022-06-02 9ae0691c806b6b56306c2cda5509b0a0444cec06
优化快照的存储与显示
5个文件已修改
120 ■■■■ 已修改文件
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java 41 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
web_src/src/components/channelList.vue 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
@@ -91,10 +91,9 @@
    public ResponseEntity<String> onServerKeepalive(@RequestBody JSONObject json){
        if (logger.isDebugEnabled()) {
            logger.debug("[ ZLM HOOK ]on_server_keepalive API调用,参数:" + json.toString());
            logger.debug("[ ZLM HOOK ] on_server_keepalive API调用,参数:" + json.toString());
        }
        String mediaServerId = json.getString("mediaServerId");
        List<ZLMHttpHookSubscribe.Event> subscribes = this.subscribe.getSubscribes(ZLMHttpHookSubscribe.HookType.on_server_keepalive);
        if (subscribes != null  && subscribes.size() > 0) {
            for (ZLMHttpHookSubscribe.Event subscribe : subscribes) {
@@ -164,7 +163,6 @@
            if (mediaInfo != null) {
                subscribe.response(mediaInfo, json);
            }
        }
        JSONObject ret = new JSONObject();
        ret.put("code", 0);
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java
@@ -151,7 +151,7 @@
                        }
                    }
                    File snapFile = new File(targetPath + "/" + fileName);
                    File snapFile = new File(targetPath + File.separator + fileName);
                    FileOutputStream outStream = new FileOutputStream(snapFile);
                    outStream.write(Objects.requireNonNull(response.body()).bytes());
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
@@ -123,36 +123,19 @@
        result.onCompletion(()->{
            // 点播结束时调用截图接口
            // TODO 应该在上流时调用更好,结束也可能是错误结束
            try {
                String classPath = ResourceUtils.getURL("classpath:").getPath();
                // 兼容打包为jar的class路径
                if(classPath.contains("jar")) {
                    classPath = classPath.substring(0, classPath.lastIndexOf("."));
                    classPath = classPath.substring(0, classPath.lastIndexOf("/") + 1);
            String path =  "snap";
            String fileName =  deviceId + "_" + channelId + ".jpg";
            ResponseEntity responseEntity =  (ResponseEntity)result.getResult();
            if (responseEntity != null && responseEntity.getStatusCode() == HttpStatus.OK) {
                WVPResult wvpResult = (WVPResult)responseEntity.getBody();
                if (Objects.requireNonNull(wvpResult).getCode() == 0) {
                    StreamInfo streamInfoForSuccess = (StreamInfo)wvpResult.getData();
                    MediaServerItem mediaInfo = mediaServerService.getOne(streamInfoForSuccess.getMediaServerId());
                    String streamUrl = streamInfoForSuccess.getFmp4();
                    // 请求截图
                    logger.info("[请求截图]: " + fileName);
                    zlmresTfulUtils.getSnap(mediaInfo, streamUrl, 15, 1, path, fileName);
                }
                if (classPath.startsWith("file:")) {
                    classPath = classPath.substring(classPath.indexOf(":") + 1);
                }
                String path = classPath + "static/static/snap/";
                // 兼容Windows系统路径(去除前面的“/”)
                if(System.getProperty("os.name").contains("indows")) {
                    path = path.substring(1);
                }
                String fileName =  deviceId + "_" + channelId + ".jpg";
                ResponseEntity responseEntity =  (ResponseEntity)result.getResult();
                if (responseEntity != null && responseEntity.getStatusCode() == HttpStatus.OK) {
                    WVPResult wvpResult = (WVPResult)responseEntity.getBody();
                    if (Objects.requireNonNull(wvpResult).getCode() == 0) {
                        StreamInfo streamInfoForSuccess = (StreamInfo)wvpResult.getData();
                        MediaServerItem mediaInfo = mediaServerService.getOne(streamInfoForSuccess.getMediaServerId());
                        String streamUrl = streamInfoForSuccess.getFmp4();
                        // 请求截图
                        logger.info("[请求截图]: " + fileName);
                        zlmresTfulUtils.getSnap(mediaInfo, streamUrl, 15, 1, path, fileName);
                    }
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        });
        if (streamInfo != null) {
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java
@@ -21,16 +21,22 @@
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.compress.utils.IOUtils;
import org.apache.http.HttpResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.async.DeferredResult;
import javax.servlet.http.HttpServletResponse;
import javax.sip.DialogState;
import java.io.*;
import java.nio.file.Files;
import java.util.*;
@Api(tags = "国标设备查询", value = "国标设备查询")
@@ -456,4 +462,17 @@
        wvpResult.setData(dialogStateMap);
        return wvpResult;
    }
    @GetMapping("/snap/{deviceId}/{channelId}")
    @ApiOperation(value = "请求截图", notes = "请求截图")
    public void getSnap(HttpServletResponse resp, @PathVariable String deviceId, @PathVariable String channelId) {
        try {
            final InputStream in = Files.newInputStream(new File("snap" + File.separator + deviceId + "_" + channelId + ".jpg").toPath());
            resp.setContentType(MediaType.IMAGE_PNG_VALUE);
            IOUtils.copy(in, resp.getOutputStream());
        } catch (IOException e) {
            resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
        }
    }
}
web_src/src/components/channelList.vue
@@ -39,21 +39,22 @@
    </el-table-column>
    <el-table-column label="快照" width="80" align="center">
      <template slot-scope="scope">
        <img style="max-height: 3rem;max-width: 4rem;"
             v-if="scope.row.subCount === 0 && scope.row.parental === 0"
             :id="scope.row.deviceId + '_' + scope.row.channelId"
             :src="getSnap(scope.row)"
             @error="getSnapErrorEvent($event.target.id)"
             alt="">
        <!--                    <el-image-->
        <!--                      :id="'snapImg_' + scope.row.deviceId + '_' + scope.row.channelId"-->
        <!--                      :src="getSnap(scope.row)"-->
        <!--                      @error="getSnapErrorEvent($event, scope.row)"-->
        <!--                      :fit="'contain'">-->
        <!--                      <div slot="error" class="image-slot">-->
        <!--                        <i class="el-icon-picture-outline"></i>-->
        <!--                      </div>-->
        <!--                    </el-image>-->
<!--        <img style="max-height: 3rem;max-width: 4rem;"-->
<!--             v-if="scope.row.subCount === 0 && scope.row.parental === 0"-->
<!--             :deviceId="scope.row.deviceId"-->
<!--             :channelId="scope.row.channelId"-->
<!--             :src="getSnap(scope.row)"-->
<!--             @error="getSnapErrorEvent($event.target.deviceId, $event.target.channelId)"-->
<!--             alt="">-->
                  <el-image
                    :src="getSnap(scope.row)"
                    :preview-src-list="getBigSnap(scope.row)"
                    @error="getSnapErrorEvent(scope.row.deviceId, cope.row.channelId)"
                    :fit="'contain'">
                    <div slot="error" class="image-slot">
                      <i class="el-icon-picture-outline"></i>
                    </div>
                  </el-image>
      </template>
    </el-table-column>
    <el-table-column prop="subCount" label="子节点数">
@@ -227,7 +228,7 @@
          setTimeout(() => {
            let snapId = deviceId + "_" + channelId;
            that.loadSnap[snapId] = 0;
            that.loadSnap[deviceId + channelId] = 0;
            that.getSnapErrorEvent(snapId)
          }, 5000)
          that.$refs.devicePlayer.openDialog("media", deviceId, channelId, {
@@ -269,19 +270,24 @@
      });
    },
    getSnap: function (row) {
      return '/static/snap/' + row.deviceId + '_' + row.channelId + '.jpg'
      let url = (process.env.NODE_ENV === 'development'? "debug": "") + '/api/device/query/snap/' + row.deviceId + '/' + row.channelId
      return url
    },
    getSnapErrorEvent: function (id) {
    getBigSnap: function (row) {
      return [this.getSnap(row)]
    },
    getSnapErrorEvent: function (deviceId, channelId) {
      if (typeof (this.loadSnap[id]) != "undefined") {
        console.log("下载截图" + this.loadSnap[id])
        if (this.loadSnap[id] > 5) {
          delete this.loadSnap[id];
      if (typeof (this.loadSnap[deviceId + channelId]) != "undefined") {
        console.log("下载截图" + this.loadSnap[deviceId + channelId])
        if (this.loadSnap[deviceId + channelId] > 5) {
          delete this.loadSnap[deviceId + channelId];
          return;
        }
        setTimeout(() => {
          this.loadSnap[id]++
          document.getElementById(id).setAttribute("src", '/static/snap/' + id + '.jpg?' + new Date().getTime())
          let url = (process.env.NODE_ENV === 'development'? "debug": "") + '/api/device/query/snap/' + deviceId + '/' + channelId
          this.loadSnap[deviceId + channelId]++
          document.getElementById(deviceId + channelId).setAttribute("src", url + '?' + new Date().getTime())
        }, 1000)
      }