Commit d8635682bbb37253e0d14cdd9bad2a37315011f7
Committed by
GitHub
Merge pull request #33 from lawrencehj/wvp-28181-2.0
优化录像列表获取算法等
Showing
9 changed files
with
35 additions
and
47 deletions
.gitignore
| ... | ... | @@ -9,7 +9,7 @@ |
| 9 | 9 | |
| 10 | 10 | # Mobile Tools for Java (J2ME) |
| 11 | 11 | .mtj.tmp/ |
| 12 | - | |
| 12 | +src/main/resources/application-*.yml | |
| 13 | 13 | # Package Files # |
| 14 | 14 | #*.jar |
| 15 | 15 | *.war |
| ... | ... | @@ -18,7 +18,7 @@ |
| 18 | 18 | *.zip |
| 19 | 19 | *.tar.gz |
| 20 | 20 | *.rar |
| 21 | - | |
| 21 | +*.iml | |
| 22 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml |
| 23 | 23 | hs_err_pid* |
| 24 | 24 | /.idea/* | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
| ... | ... | @@ -121,7 +121,9 @@ public class SipLayer implements SipListener { |
| 121 | 121 | logger.debug(evt.getRequest().toString()); |
| 122 | 122 | // 由于jainsip是单线程程序,为提高性能并发处理 |
| 123 | 123 | processThreadPool.execute(() -> { |
| 124 | - processorFactory.createRequestProcessor(evt).process(); | |
| 124 | + if (processorFactory != null) { | |
| 125 | + processorFactory.createRequestProcessor(evt).process(); | |
| 126 | + } | |
| 125 | 127 | }); |
| 126 | 128 | } |
| 127 | 129 | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
| ... | ... | @@ -290,12 +290,8 @@ public class SIPCommander implements ISIPCommander { |
| 290 | 290 | @Override |
| 291 | 291 | public void playStreamCmd(Device device, String channelId, ZLMHttpHookSubscribe.Event event, SipSubscribe.Event errorEvent) { |
| 292 | 292 | try { |
| 293 | - String ssrc = ""; | |
| 294 | - if (rtpEnable) { | |
| 295 | - ssrc = String.format("gb_play_%s_%s", device.getDeviceId(), channelId); | |
| 296 | - }else { | |
| 297 | - ssrc = streamSession.createPlaySsrc(); | |
| 298 | - } | |
| 293 | + | |
| 294 | + String ssrc = streamSession.createPlaySsrc(); | |
| 299 | 295 | String streamId = null; |
| 300 | 296 | if (rtpEnable) { |
| 301 | 297 | streamId = String.format("gb_play_%s_%s", device.getDeviceId(), channelId); |
| ... | ... | @@ -412,16 +408,13 @@ public class SIPCommander implements ISIPCommander { |
| 412 | 408 | , SipSubscribe.Event errorEvent) { |
| 413 | 409 | try { |
| 414 | 410 | MediaServerConfig mediaInfo = redisCatchStorage.getMediaInfo(); |
| 415 | - String ssrc = null; | |
| 411 | + String ssrc = streamSession.createPlayBackSsrc(); | |
| 416 | 412 | String streamId = null; |
| 417 | 413 | if (rtpEnable) { |
| 418 | - ssrc = String.format("gb_playback_%s_%s", device.getDeviceId(), channelId); | |
| 419 | - streamId = ssrc; | |
| 414 | + streamId = String.format("gb_playback_%s_%s", device.getDeviceId(), channelId); | |
| 420 | 415 | }else { |
| 421 | - ssrc = streamSession.createPlayBackSsrc(); | |
| 422 | 416 | streamId = String.format("%08x", Integer.parseInt(ssrc)).toUpperCase(); |
| 423 | 417 | } |
| 424 | - | |
| 425 | 418 | // 添加订阅 |
| 426 | 419 | JSONObject subscribeKey = new JSONObject(); |
| 427 | 420 | subscribeKey.put("app", "rtp"); | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
| ... | ... | @@ -342,6 +342,7 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor { |
| 342 | 342 | try { |
| 343 | 343 | // 回复200 OK |
| 344 | 344 | responseAck(evt); |
| 345 | + String seqNo = String.valueOf(System.currentTimeMillis()); | |
| 345 | 346 | RecordInfo recordInfo = new RecordInfo(); |
| 346 | 347 | Element rootElement = getRootElement(evt); |
| 347 | 348 | Element deviceIdElement = rootElement.element("DeviceID"); |
| ... | ... | @@ -396,32 +397,22 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor { |
| 396 | 397 | if (recordInfo.getSumNum() > 0 && recordList.size() > 0 && recordList.size() < recordInfo.getSumNum()) { |
| 397 | 398 | // 为防止连续请求该设备的录像数据,返回数据错乱,特增加sn进行区分 |
| 398 | 399 | String cacheKey = CACHE_RECORDINFO_KEY + deviceId + sn; |
| 399 | - // TODO 暂时直接操作redis存储,后续封装专用缓存接口,改为本地内存缓存 | |
| 400 | - if (redis.hasKey(cacheKey)) { | |
| 401 | - List<RecordItem> previousList = (List<RecordItem>) redis.get(cacheKey); | |
| 402 | - if (previousList != null && previousList.size() > 0) { | |
| 403 | - recordList.addAll(previousList); | |
| 404 | - } | |
| 405 | - // 本分支表示录像列表被拆包,且加上之前的数据还是不够,保存缓存返回,等待下个包再处理 | |
| 406 | - if (recordList.size() < recordInfo.getSumNum()) { | |
| 407 | - logger.info("已获取" + recordList.size() + "项录像数据,共" + recordInfo.getSumNum() + "项"); | |
| 408 | - redis.set(cacheKey, recordList, 90); | |
| 409 | - return; | |
| 410 | - } else { | |
| 411 | - // 本分支表示录像被拆包,但加上之前的数据够足够,返回响应 | |
| 412 | - // 因设备心跳有监听redis过期机制,为提高性能,此处手动删除 | |
| 413 | - logger.info("录像数据已全部获取"); | |
| 414 | - redis.del(cacheKey); | |
| 415 | - } | |
| 416 | - } else { | |
| 417 | - // 本分支有两种可能:1、录像列表被拆包,且是第一个包,直接保存缓存返回,等待下个包再处理 | |
| 418 | - // 2、之前有包,但超时清空了,那么这次sn批次的响应数据已经不完整,等待过期时间后redis自动清空数据 | |
| 419 | - logger.info("已获取" + recordList.size() + "项录像数据,共" + recordInfo.getSumNum() + "项"); | |
| 420 | - logger.info("等待后续的包..."); | |
| 421 | 400 | |
| 422 | - redis.set(cacheKey, recordList, 90); | |
| 401 | + redis.set(cacheKey + "_" + seqNo, recordList, 90); | |
| 402 | + List<Object> cacheKeys = redis.scan(cacheKey + "_*"); | |
| 403 | + List<RecordItem> totalRecordList = new ArrayList<RecordItem>(); | |
| 404 | + for (int i = 0; i < cacheKeys.size(); i++) { | |
| 405 | + totalRecordList.addAll((List<RecordItem>) redis.get(cacheKeys.get(i).toString())); | |
| 406 | + } | |
| 407 | + if (totalRecordList.size() < recordInfo.getSumNum()) { | |
| 408 | + logger.info("已获取" + totalRecordList.size() + "项录像数据,共" + recordInfo.getSumNum() + "项"); | |
| 423 | 409 | return; |
| 424 | 410 | } |
| 411 | + logger.info("录像数据已全部获取,共" + recordInfo.getSumNum() + "项"); | |
| 412 | + recordInfo.setRecordList(totalRecordList); | |
| 413 | + for (int i = 0; i < cacheKeys.size(); i++) { | |
| 414 | + redis.del(cacheKeys.get(i).toString()); | |
| 415 | + } | |
| 425 | 416 | } |
| 426 | 417 | // 自然顺序排序, 元素进行升序排列 |
| 427 | 418 | recordInfo.getRecordList().sort(Comparator.naturalOrder()); |
| ... | ... | @@ -460,7 +451,6 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor { |
| 460 | 451 | cmder.streamByeCmd(streamInfo.getStreamId()); |
| 461 | 452 | } |
| 462 | 453 | } |
| 463 | - | |
| 464 | 454 | } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) { |
| 465 | 455 | e.printStackTrace(); |
| 466 | 456 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/RegisterRequestProcessor.java
| ... | ... | @@ -144,10 +144,10 @@ public class RegisterRequestProcessor extends SIPRequestAbstractProcessor { |
| 144 | 144 | storager.updateDevice(device); |
| 145 | 145 | publisher.onlineEventPublish(device.getDeviceId(), VideoManagerConstants.EVENT_ONLINE_REGISTER); |
| 146 | 146 | |
| 147 | - // 只有第一次注册才更新通道 | |
| 148 | - if (!exists) { | |
| 147 | + // 重新注册更新设备和通道,以免设备替换或更新后信息无法更新 | |
| 148 | + //if (!exists) { | |
| 149 | 149 | handler.onRegister(device); |
| 150 | - } | |
| 150 | + //} | |
| 151 | 151 | } else if (registerFlag == 2) { |
| 152 | 152 | logger.info("注销成功! deviceId:" + device.getDeviceId()); |
| 153 | 153 | publisher.outlineEventPublish(device.getDeviceId(), VideoManagerConstants.EVENT_OUTLINE_UNREGISTER); | ... | ... |
src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceMapper.java
web_src/src/components/channelList.vue
| ... | ... | @@ -153,11 +153,10 @@ export default { |
| 153 | 153 | }, |
| 154 | 154 | getDeviceChannelList: function () { |
| 155 | 155 | let that = this; |
| 156 | - console.log(this.currentPage - 1) | |
| 157 | 156 | |
| 158 | 157 | this.$axios.get(`/api/devices/${this.$route.params.deviceId}/channels`, { |
| 159 | 158 | params: { |
| 160 | - page: that.currentPage - 1, | |
| 159 | + page: that.currentPage, | |
| 161 | 160 | count: that.count, |
| 162 | 161 | query: that.searchSrt, |
| 163 | 162 | online: that.online, |
| ... | ... | @@ -254,7 +253,7 @@ export default { |
| 254 | 253 | |
| 255 | 254 | this.$axios.get(`/api/subChannels/${this.deviceId}/${this.parentChannelId}/channels`, { |
| 256 | 255 | params: { |
| 257 | - page: that.currentPage - 1, | |
| 256 | + page: that.currentPage, | |
| 258 | 257 | count: that.count, |
| 259 | 258 | query: that.searchSrt, |
| 260 | 259 | online: that.online, | ... | ... |
web_src/src/components/platformEdit.vue
| ... | ... | @@ -74,7 +74,7 @@ |
| 74 | 74 | </el-select> |
| 75 | 75 | </el-form-item> |
| 76 | 76 | <el-form-item label="其他选项"> |
| 77 | - <el-checkbox label="启用" v-model="platform.enable"></el-checkbox> | |
| 77 | + <el-checkbox label="启用" v-model="platform.enable" @change="checkExpires"></el-checkbox> | |
| 78 | 78 | <el-checkbox label="云台控制" v-model="platform.PTZEnable"></el-checkbox> |
| 79 | 79 | <el-checkbox label="RTCP保活" v-model="platform.rtcp"></el-checkbox> |
| 80 | 80 | </el-form-item> |
| ... | ... | @@ -245,6 +245,11 @@ export default { |
| 245 | 245 | }); |
| 246 | 246 | return result; |
| 247 | 247 | }, |
| 248 | + checkExpires: function() { | |
| 249 | + if (this.platform.enable && this.platform.expires == "0") { | |
| 250 | + this.platform.expires = "300"; | |
| 251 | + } | |
| 252 | + } | |
| 248 | 253 | }, |
| 249 | 254 | }; |
| 250 | 255 | </script> | ... | ... |
web_src/src/components/videoList.vue