src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
web_src/src/components/channelList.vue | ●●●●● 补丁 | 查看 | 原始文档 | 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) }