From 3ec3b88456cf9ac455d93baba40f339bb284dd77 Mon Sep 17 00:00:00 2001
From: 648540858 <648540858@qq.com>
Date: 星期三, 14 十月 2020 14:39:10 +0800
Subject: [PATCH] 修复点播判断错误导致的15s超长延时 增加默认不关闭推流, 无人观看超时或点击停止按钮关闭流 修复点播其他bug
---
src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java | 3 +
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java | 9 ++
src/main/java/com/genersoft/iot/vmp/storager/jdbc/VideoManagerJdbcStoragerImpl.java | 6 ++
src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java | 29 +++++++--
web_src/src/components/channelList.vue | 25 +++++++-
src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceChannel.java | 13 ++++
web_src/src/components/gb28181/devicePlayer.vue | 17 -----
src/main/java/com/genersoft/iot/vmp/storager/redis/VideoManagerRedisStoragerImpl.java | 40 ++++++++++++-
src/main/resources/application.yml | 1
9 files changed, 114 insertions(+), 29 deletions(-)
diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceChannel.java b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceChannel.java
index 00bd995..1350341 100644
--- a/src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceChannel.java
+++ b/src/main/java/com/genersoft/iot/vmp/gb28181/bean/DeviceChannel.java
@@ -148,6 +148,11 @@
*/
private boolean hasAudio;
+ /**
+ * 鏄惁姝e湪鎾斁
+ */
+ private boolean play;
+
public String getChannelId() {
return channelId;
}
@@ -388,4 +393,12 @@
public void setHasAudio(boolean hasAudio) {
this.hasAudio = hasAudio;
}
+
+ public boolean isPlay() {
+ return play;
+ }
+
+ public void setPlay(boolean play) {
+ this.play = play;
+ }
}
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java
index 8114814..7d7edf4 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java
@@ -38,6 +38,9 @@
@Value("${media.secret}")
private String mediaSecret;
+ @Value("${media.streamNoneReaderDelayMS}")
+ private String streamNoneReaderDelayMS;
+
@Value("${sip.ip}")
private String sipIP;
@@ -54,9 +57,10 @@
MediaServerConfig mediaServerConfig = getMediaServerConfig();
if (mediaServerConfig != null) {
logger.info("zlm鎺ュ叆鎴愬姛...");
- storager.updateMediaInfo(mediaServerConfig);
logger.info("璁剧疆zlm...");
saveZLMConfig();
+ mediaServerConfig = getMediaServerConfig();
+ storager.updateMediaInfo(mediaServerConfig);
}
}
@@ -79,7 +83,7 @@
} catch (InterruptedException e) {
e.printStackTrace();
}
- getMediaServerConfig();
+ mediaServerConfig = getMediaServerConfig();
}
return mediaServerConfig;
}
@@ -106,6 +110,7 @@
param.put("hook.on_stream_none_reader",String.format("%s/on_stream_none_reader", hookPrex));
param.put("hook.on_stream_not_found",String.format("%s/on_stream_not_found", hookPrex));
param.put("hook.timeoutSec","20");
+ param.put("general.streamNoneReaderDelayMS",streamNoneReaderDelayMS);
JSONObject responseJSON = zlmresTfulUtils.setServerConfig(param);
diff --git a/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java b/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java
index 8381738..0894fe2 100644
--- a/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java
+++ b/src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java
@@ -1,6 +1,7 @@
package com.genersoft.iot.vmp.storager;
import java.util.List;
+import java.util.Map;
import com.alibaba.fastjson.JSONObject;
import com.genersoft.iot.vmp.common.PageResult;
@@ -180,4 +181,6 @@
StreamInfo queryPlayBySSRC(String ssrc);
StreamInfo queryPlayByDevice(String deviceId, String code);
+
+ Map<String, StreamInfo> queryPlayByDeviceId(String deviceId);
}
diff --git a/src/main/java/com/genersoft/iot/vmp/storager/jdbc/VideoManagerJdbcStoragerImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/jdbc/VideoManagerJdbcStoragerImpl.java
index c3a18b7..99f19ee 100644
--- a/src/main/java/com/genersoft/iot/vmp/storager/jdbc/VideoManagerJdbcStoragerImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/storager/jdbc/VideoManagerJdbcStoragerImpl.java
@@ -1,6 +1,7 @@
package com.genersoft.iot.vmp.storager.jdbc;
import java.util.List;
+import java.util.Map;
import com.genersoft.iot.vmp.common.PageResult;
import com.genersoft.iot.vmp.common.StreamInfo;
@@ -186,4 +187,9 @@
public StreamInfo queryPlayByDevice(String deviceId, String code) {
return null;
}
+
+ @Override
+ public Map<String, StreamInfo> queryPlayByDeviceId(String deviceId) {
+ return null;
+ }
}
diff --git a/src/main/java/com/genersoft/iot/vmp/storager/redis/VideoManagerRedisStoragerImpl.java b/src/main/java/com/genersoft/iot/vmp/storager/redis/VideoManagerRedisStoragerImpl.java
index 38a6476..91b60a1 100644
--- a/src/main/java/com/genersoft/iot/vmp/storager/redis/VideoManagerRedisStoragerImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/storager/redis/VideoManagerRedisStoragerImpl.java
@@ -134,6 +134,8 @@
@Override
public PageResult queryChannelsByDeviceId(String deviceId, String query, Boolean hasSubChannel, String online, int page, int count) {
+ // 鑾峰彇鍒版墍鏈夋鍦ㄦ挱鏀剧殑娴�
+ Map<String, StreamInfo> stringStreamInfoMap = queryPlayByDeviceId(deviceId);
List<DeviceChannel> result = new ArrayList<>();
PageResult pageResult = new PageResult<DeviceChannel>();
String queryContent = "*";
@@ -154,13 +156,19 @@
int maxCount = (page + 1 ) * count;
if (deviceChannelList != null && deviceChannelList.size() > 0 ) {
for (int i = page * count; i < (pageResult.getTotal() > maxCount ? maxCount : pageResult.getTotal() ); i++) {
- result.add((DeviceChannel)redis.get((String)deviceChannelList.get(i)));
+ DeviceChannel deviceChannel = (DeviceChannel)redis.get((String)deviceChannelList.get(i));
+ StreamInfo streamInfo = stringStreamInfoMap.get(deviceId + "_" + deviceChannel.getChannelId());
+ deviceChannel.setPlay(streamInfo != null);
+ if (streamInfo != null) deviceChannel.setSsrc(streamInfo.getSsrc());
+ result.add(deviceChannel);
}
pageResult.setData(result);
}
return pageResult;
}
+
+
@Override
public List<DeviceChannel> queryChannelsByDeviceId(String deviceId) {
@@ -231,7 +239,13 @@
@Override
public DeviceChannel queryChannel(String deviceId, String channelId) {
- return (DeviceChannel)redis.get(VideoManagerConstants.CACHEKEY_PREFIX + deviceId + "_" + channelId + "_");
+ DeviceChannel deviceChannel = null;
+ List<Object> deviceChannelList = redis.keys(VideoManagerConstants.CACHEKEY_PREFIX + deviceId +
+ "_" + channelId + "*");
+ if (deviceChannelList != null && deviceChannelList.size() > 0 ) {
+ deviceChannel = (DeviceChannel)redis.get((String)deviceChannelList.get(0));
+ }
+ return deviceChannel;
}
@@ -345,6 +359,12 @@
@Override
public boolean stopPlay(StreamInfo streamInfo) {
if (streamInfo == null) return false;
+ DeviceChannel deviceChannel = queryChannel(streamInfo.getDeviceID(), streamInfo.getCahnnelId());
+ if (deviceChannel != null) {
+ deviceChannel.setSsrc(null);
+ deviceChannel.setPlay(false);
+ updateChannel(streamInfo.getDeviceID(), deviceChannel);
+ }
return redis.del(String.format("%S_%s_%s_%s", VideoManagerConstants.PLAYER_PREFIX,
streamInfo.getSsrc(),
streamInfo.getDeviceID(),
@@ -366,7 +386,7 @@
@Override
public StreamInfo queryPlayBySSRC(String ssrc) {
List<Object> playLeys = redis.keys(String.format("%S_%s_*", VideoManagerConstants.PLAYER_PREFIX, ssrc));
- if (playLeys.size() == 0) return null;
+ if (playLeys == null || playLeys.size() == 0) return null;
return (StreamInfo)redis.get(playLeys.get(0).toString());
}
@@ -375,6 +395,7 @@
List<Object> playLeys = redis.keys(String.format("%S_*_%s_%s", VideoManagerConstants.PLAYER_PREFIX,
deviceId,
code));
+ if (playLeys == null || playLeys.size() == 0) return null;
return (StreamInfo)redis.get(playLeys.get(0).toString());
}
@@ -438,6 +459,19 @@
}
}
+ @Override
+ public Map<String, StreamInfo> queryPlayByDeviceId(String deviceId) {
+ Map<String, StreamInfo> streamInfos = new HashMap<>();
+ List<Object> playLeys = redis.keys(String.format("%S_*_%S_*", VideoManagerConstants.PLAYER_PREFIX, deviceId));
+ if (playLeys.size() == 0) return streamInfos;
+ for (int i = 0; i < playLeys.size(); i++) {
+ String key = (String) playLeys.get(i);
+ StreamInfo streamInfo = (StreamInfo)redis.get(key);
+ streamInfos.put(streamInfo.getDeviceID() + "_" + streamInfo.getCahnnelId(), streamInfo);
+ }
+ return streamInfos;
+ }
+
}
diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java
index 996039e..d5647fc 100644
--- a/src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java
+++ b/src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java
@@ -41,18 +41,36 @@
public ResponseEntity<String> play(@PathVariable String deviceId,@PathVariable String channelId){
Device device = storager.queryVideoDevice(deviceId);
- StreamInfo streamInfo = cmder.playStreamCmd(device, channelId);
+ StreamInfo streamInfo = storager.queryPlayByDevice(deviceId, channelId);
+
+ if (streamInfo == null) {
+ streamInfo = cmder.playStreamCmd(device, channelId);
+ }else {
+ String streamId = String.format("%08x", Integer.parseInt(streamInfo.getSsrc())).toUpperCase();
+ JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(streamId);
+ if (rtpInfo.getBoolean("exist")) {
+ return new ResponseEntity<String>(JSON.toJSONString(streamInfo),HttpStatus.OK);
+ }else {
+ storager.stopPlay(streamInfo);
+ streamInfo = cmder.playStreamCmd(device, channelId);
+ }
+
+ }
+ String streamId = String.format("%08x", Integer.parseInt(streamInfo.getSsrc())).toUpperCase();
// 绛夊緟鎺ㄦ祦, TODO 榛樿瓒呮椂15s
boolean lockFlag = true;
long startTime = System.currentTimeMillis();
- String streamId = String.format("%08x", Integer.parseInt(streamInfo.getSsrc())).toUpperCase();
- // 鍒ゆ柇鎺ㄦ祦鏄惁瀛樺湪
while (lockFlag) {
try {
+
if (System.currentTimeMillis() - startTime > 15 * 1000) {
+ storager.stopPlay(streamInfo);
+ return new ResponseEntity<String>("timeout",HttpStatus.OK);
+ }else {
JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(streamId);
- if (rtpInfo == null){
+ Boolean exist = rtpInfo.getBoolean("exist");
+ if (rtpInfo == null || !rtpInfo.getBoolean("exist") || streamInfo.getFlv() != null){
continue;
}else {
lockFlag = false;
@@ -72,10 +90,9 @@
}
}
};
-
}
-
Thread.sleep(200);
+ streamInfo = storager.queryPlayByDevice(deviceId, channelId);
} catch (InterruptedException e) {
e.printStackTrace();
}
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 5b5f01e..ad37548 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -43,4 +43,5 @@
ip: 192.168.1.20
port: 9080
secret: 035c73f7-bb6b-4889-a715-d9eb2d1925cc
+ streamNoneReaderDelayMS: 1800000 # 鏃犱汉瑙傜湅澶氫箙鍏抽棴娴�
diff --git a/web_src/src/components/channelList.vue b/web_src/src/components/channelList.vue
index 7c667ba..b3980c3 100644
--- a/web_src/src/components/channelList.vue
+++ b/web_src/src/components/channelList.vue
@@ -56,7 +56,8 @@
</el-table-column>
<el-table-column label="鎿嶄綔" width="240" align="center" fixed="right">
<template slot-scope="scope">
- <el-button size="mini" icon="el-icon-video-play" v-if="scope.row.parental == 0" @click="sendDevicePush(scope.row)">棰勮瑙嗛</el-button>
+ <el-button size="mini" icon="el-icon-video-play" v-if="scope.row.parental == 0" @click="sendDevicePush(scope.row)">鎾斁</el-button>
+ <el-button size="mini" icon="el-icon-switch-button" type="danger" v-if="scope.row.play" @click="stopDevicePush(scope.row)">鍋滄</el-button>
<el-button size="mini" icon="el-icon-s-open" type="primary" v-if="scope.row.parental == 1" @click="changeSubchannel(scope.row)">鏌ョ湅瀛愮洰褰�</el-button>
<!-- <el-button size="mini" @click="sendDevicePush(scope.row)">褰曞儚鏌ヨ</el-button> -->
</template>
@@ -198,7 +199,7 @@
message: '璇锋眰鎴愬姛',
type: 'success'
});
- });;
+ });
},
//閫氱煡璁惧涓婁紶濯掍綋娴�
sendDevicePush: function(itemData) {
@@ -212,12 +213,30 @@
method: 'get',
url: '/api/play/' + deviceId + '/' + channelId
}).then(function(res) {
+ console.log(res.data)
let ssrc = res.data.ssrc;
that.isLoging = false
- that.$refs.devicePlayer.play(res.data,deviceId,channelId,itemData.hasAudio);
+ if (!!ssrc) {
+ that.$refs.devicePlayer.play(res.data,deviceId,channelId,itemData.hasAudio);
+ that.initData();
+ }else {
+ that.$message.error(res.data);
+ }
}).catch(function(e) {
});
},
+ stopDevicePush: function(itemData) {
+ console.log(itemData)
+ var that = this;
+ this.$axios({
+ method: 'post',
+ url: '/api/play/' + itemData.ssrc + '/stop'
+ }).then(function(res) {
+ console.log(JSON.stringify(res));
+ that.initData();
+ });
+ },
+
showDevice: function(){
this.$router.push(this.beforeUrl).then(()=>{
this.initParam();
diff --git a/web_src/src/components/gb28181/devicePlayer.vue b/web_src/src/components/gb28181/devicePlayer.vue
index 9e497e4..ce36483 100644
--- a/web_src/src/components/gb28181/devicePlayer.vue
+++ b/web_src/src/components/gb28181/devicePlayer.vue
@@ -1,6 +1,6 @@
<template>
<div id="devicePlayer">
- <el-dialog title="瑙嗛鎾斁" top="0" :visible.sync="showVideoDialog" :destroy-on-close="true" @close="stop()">
+ <el-dialog title="瑙嗛鎾斁" top="0" :visible.sync="showVideoDialog" :destroy-on-close="true" @close="close()">
<LivePlayer v-if="showVideoDialog" ref="videoPlayer" :videoUrl="videoUrl" :error="videoError" :hasaudio="hasaudio" fluent autoplay live ></LivePlayer>
<div id="shared" style="text-align: right; margin-top: 1rem;">
<el-tabs v-model="tabActiveName">
@@ -145,24 +145,11 @@
this.showVideoDialog = true;
console.log(this.ssrc);
},
- stop: function() {
+ close: function() {
console.log('鍏抽棴瑙嗛');
this.$refs.videoPlayer.pause();
this.videoUrl = '';
this.showVideoDialog = false;
- this.$axios({
- method: 'post',
- url: '/api/play/' + this.ssrc + '/stop'
- }).then(function(res) {
- console.log(JSON.stringify(res));
- });
-
- this.$axios({
- method: 'post',
- url: '/api/playback/' + this.ssrc + '/stop'
- }).then(function(res) {
- console.log(JSON.stringify(res));
- });
},
copySharedInfo: function(data) {
console.log('澶嶅埗鍐呭锛�' + data);
--
Gitblit v1.8.0