Commit 9ae0691c806b6b56306c2cda5509b0a0444cec06

Authored by 648540858
1 parent 936adf31

优化快照的存储与显示

src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
... ... @@ -91,10 +91,9 @@ public class ZLMHttpHookListener {
91 91 public ResponseEntity<String> onServerKeepalive(@RequestBody JSONObject json){
92 92  
93 93 if (logger.isDebugEnabled()) {
94   - logger.debug("[ ZLM HOOK ]on_server_keepalive API调用,参数:" + json.toString());
  94 + logger.debug("[ ZLM HOOK ] on_server_keepalive API调用,参数:" + json.toString());
95 95 }
96 96 String mediaServerId = json.getString("mediaServerId");
97   -
98 97 List<ZLMHttpHookSubscribe.Event> subscribes = this.subscribe.getSubscribes(ZLMHttpHookSubscribe.HookType.on_server_keepalive);
99 98 if (subscribes != null && subscribes.size() > 0) {
100 99 for (ZLMHttpHookSubscribe.Event subscribe : subscribes) {
... ... @@ -164,7 +163,6 @@ public class ZLMHttpHookListener {
164 163 if (mediaInfo != null) {
165 164 subscribe.response(mediaInfo, json);
166 165 }
167   -
168 166 }
169 167 JSONObject ret = new JSONObject();
170 168 ret.put("code", 0);
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java
... ... @@ -151,7 +151,7 @@ public class ZLMRESTfulUtils {
151 151 }
152 152  
153 153 }
154   - File snapFile = new File(targetPath + "/" + fileName);
  154 + File snapFile = new File(targetPath + File.separator + fileName);
155 155 FileOutputStream outStream = new FileOutputStream(snapFile);
156 156  
157 157 outStream.write(Objects.requireNonNull(response.body()).bytes());
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
... ... @@ -123,36 +123,19 @@ public class PlayServiceImpl implements IPlayService {
123 123 result.onCompletion(()->{
124 124 // 点播结束时调用截图接口
125 125 // TODO 应该在上流时调用更好,结束也可能是错误结束
126   - try {
127   - String classPath = ResourceUtils.getURL("classpath:").getPath();
128   - // 兼容打包为jar的class路径
129   - if(classPath.contains("jar")) {
130   - classPath = classPath.substring(0, classPath.lastIndexOf("."));
131   - classPath = classPath.substring(0, classPath.lastIndexOf("/") + 1);
  126 + String path = "snap";
  127 + String fileName = deviceId + "_" + channelId + ".jpg";
  128 + ResponseEntity responseEntity = (ResponseEntity)result.getResult();
  129 + if (responseEntity != null && responseEntity.getStatusCode() == HttpStatus.OK) {
  130 + WVPResult wvpResult = (WVPResult)responseEntity.getBody();
  131 + if (Objects.requireNonNull(wvpResult).getCode() == 0) {
  132 + StreamInfo streamInfoForSuccess = (StreamInfo)wvpResult.getData();
  133 + MediaServerItem mediaInfo = mediaServerService.getOne(streamInfoForSuccess.getMediaServerId());
  134 + String streamUrl = streamInfoForSuccess.getFmp4();
  135 + // 请求截图
  136 + logger.info("[请求截图]: " + fileName);
  137 + zlmresTfulUtils.getSnap(mediaInfo, streamUrl, 15, 1, path, fileName);
132 138 }
133   - if (classPath.startsWith("file:")) {
134   - classPath = classPath.substring(classPath.indexOf(":") + 1);
135   - }
136   - String path = classPath + "static/static/snap/";
137   - // 兼容Windows系统路径(去除前面的“/”)
138   - if(System.getProperty("os.name").contains("indows")) {
139   - path = path.substring(1);
140   - }
141   - String fileName = deviceId + "_" + channelId + ".jpg";
142   - ResponseEntity responseEntity = (ResponseEntity)result.getResult();
143   - if (responseEntity != null && responseEntity.getStatusCode() == HttpStatus.OK) {
144   - WVPResult wvpResult = (WVPResult)responseEntity.getBody();
145   - if (Objects.requireNonNull(wvpResult).getCode() == 0) {
146   - StreamInfo streamInfoForSuccess = (StreamInfo)wvpResult.getData();
147   - MediaServerItem mediaInfo = mediaServerService.getOne(streamInfoForSuccess.getMediaServerId());
148   - String streamUrl = streamInfoForSuccess.getFmp4();
149   - // 请求截图
150   - logger.info("[请求截图]: " + fileName);
151   - zlmresTfulUtils.getSnap(mediaInfo, streamUrl, 15, 1, path, fileName);
152   - }
153   - }
154   - } catch (FileNotFoundException e) {
155   - e.printStackTrace();
156 139 }
157 140 });
158 141 if (streamInfo != null) {
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceQuery.java
... ... @@ -21,16 +21,22 @@ import io.swagger.annotations.Api;
21 21 import io.swagger.annotations.ApiImplicitParam;
22 22 import io.swagger.annotations.ApiImplicitParams;
23 23 import io.swagger.annotations.ApiOperation;
  24 +import org.apache.commons.compress.utils.IOUtils;
  25 +import org.apache.http.HttpResponse;
24 26 import org.slf4j.Logger;
25 27 import org.slf4j.LoggerFactory;
26 28 import org.springframework.beans.factory.annotation.Autowired;
27 29 import org.springframework.http.HttpStatus;
  30 +import org.springframework.http.MediaType;
28 31 import org.springframework.http.ResponseEntity;
29 32 import org.springframework.util.StringUtils;
30 33 import org.springframework.web.bind.annotation.*;
31 34 import org.springframework.web.context.request.async.DeferredResult;
32 35  
  36 +import javax.servlet.http.HttpServletResponse;
33 37 import javax.sip.DialogState;
  38 +import java.io.*;
  39 +import java.nio.file.Files;
34 40 import java.util.*;
35 41  
36 42 @Api(tags = "国标设备查询", value = "国标设备查询")
... ... @@ -456,4 +462,17 @@ public class DeviceQuery {
456 462 wvpResult.setData(dialogStateMap);
457 463 return wvpResult;
458 464 }
  465 +
  466 + @GetMapping("/snap/{deviceId}/{channelId}")
  467 + @ApiOperation(value = "请求截图", notes = "请求截图")
  468 + public void getSnap(HttpServletResponse resp, @PathVariable String deviceId, @PathVariable String channelId) {
  469 +
  470 + try {
  471 + final InputStream in = Files.newInputStream(new File("snap" + File.separator + deviceId + "_" + channelId + ".jpg").toPath());
  472 + resp.setContentType(MediaType.IMAGE_PNG_VALUE);
  473 + IOUtils.copy(in, resp.getOutputStream());
  474 + } catch (IOException e) {
  475 + resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
  476 + }
  477 + }
459 478 }
... ...
web_src/src/components/channelList.vue
... ... @@ -39,21 +39,22 @@
39 39 </el-table-column>
40 40 <el-table-column label="快照" width="80" align="center">
41 41 <template slot-scope="scope">
42   - <img style="max-height: 3rem;max-width: 4rem;"
43   - v-if="scope.row.subCount === 0 && scope.row.parental === 0"
44   - :id="scope.row.deviceId + '_' + scope.row.channelId"
45   - :src="getSnap(scope.row)"
46   - @error="getSnapErrorEvent($event.target.id)"
47   - alt="">
48   - <!-- <el-image-->
49   - <!-- :id="'snapImg_' + scope.row.deviceId + '_' + scope.row.channelId"-->
50   - <!-- :src="getSnap(scope.row)"-->
51   - <!-- @error="getSnapErrorEvent($event, scope.row)"-->
52   - <!-- :fit="'contain'">-->
53   - <!-- <div slot="error" class="image-slot">-->
54   - <!-- <i class="el-icon-picture-outline"></i>-->
55   - <!-- </div>-->
56   - <!-- </el-image>-->
  42 +<!-- <img style="max-height: 3rem;max-width: 4rem;"-->
  43 +<!-- v-if="scope.row.subCount === 0 && scope.row.parental === 0"-->
  44 +<!-- :deviceId="scope.row.deviceId"-->
  45 +<!-- :channelId="scope.row.channelId"-->
  46 +<!-- :src="getSnap(scope.row)"-->
  47 +<!-- @error="getSnapErrorEvent($event.target.deviceId, $event.target.channelId)"-->
  48 +<!-- alt="">-->
  49 + <el-image
  50 + :src="getSnap(scope.row)"
  51 + :preview-src-list="getBigSnap(scope.row)"
  52 + @error="getSnapErrorEvent(scope.row.deviceId, cope.row.channelId)"
  53 + :fit="'contain'">
  54 + <div slot="error" class="image-slot">
  55 + <i class="el-icon-picture-outline"></i>
  56 + </div>
  57 + </el-image>
57 58 </template>
58 59 </el-table-column>
59 60 <el-table-column prop="subCount" label="子节点数">
... ... @@ -227,7 +228,7 @@ export default {
227 228 setTimeout(() => {
228 229  
229 230 let snapId = deviceId + "_" + channelId;
230   - that.loadSnap[snapId] = 0;
  231 + that.loadSnap[deviceId + channelId] = 0;
231 232 that.getSnapErrorEvent(snapId)
232 233 }, 5000)
233 234 that.$refs.devicePlayer.openDialog("media", deviceId, channelId, {
... ... @@ -269,19 +270,24 @@ export default {
269 270 });
270 271 },
271 272 getSnap: function (row) {
272   - return '/static/snap/' + row.deviceId + '_' + row.channelId + '.jpg'
  273 + let url = (process.env.NODE_ENV === 'development'? "debug": "") + '/api/device/query/snap/' + row.deviceId + '/' + row.channelId
  274 + return url
273 275 },
274   - getSnapErrorEvent: function (id) {
  276 + getBigSnap: function (row) {
  277 + return [this.getSnap(row)]
  278 + },
  279 + getSnapErrorEvent: function (deviceId, channelId) {
275 280  
276   - if (typeof (this.loadSnap[id]) != "undefined") {
277   - console.log("下载截图" + this.loadSnap[id])
278   - if (this.loadSnap[id] > 5) {
279   - delete this.loadSnap[id];
  281 + if (typeof (this.loadSnap[deviceId + channelId]) != "undefined") {
  282 + console.log("下载截图" + this.loadSnap[deviceId + channelId])
  283 + if (this.loadSnap[deviceId + channelId] > 5) {
  284 + delete this.loadSnap[deviceId + channelId];
280 285 return;
281 286 }
282 287 setTimeout(() => {
283   - this.loadSnap[id]++
284   - document.getElementById(id).setAttribute("src", '/static/snap/' + id + '.jpg?' + new Date().getTime())
  288 + let url = (process.env.NODE_ENV === 'development'? "debug": "") + '/api/device/query/snap/' + deviceId + '/' + channelId
  289 + this.loadSnap[deviceId + channelId]++
  290 + document.getElementById(deviceId + channelId).setAttribute("src", url + '?' + new Date().getTime())
285 291 }, 1000)
286 292  
287 293 }
... ...