Commit 36cd31d69d451072e00ff1dd1928a61753aa5a97

Authored by 648540858
1 parent 04af6de3

修复ui开启音频无法播放的bug

修复可能导致录象查看的bug
修复开启openRTPServer时的bug
README.md
1 # wvp 1 # wvp
2 WEB VIDEO PLATFORM譏ッ荳荳ェ蝓コ莠雑B28181-2016譬螳樒鴫逧ス醍サ懆ァ「大ケウ蜿ー瑚エ溯エ」螳樒鴫譬ク蠢ソ。莉、荳手ョセ螟ョ。逅錘蜿ー驛ィ蛻シ梧髪謖¨AT遨ソ騾擾シ梧髪謖∵オキ蠎キ縲∝、ァ蜊弱∝ョァュ牙刀迚檎噪IPC縲¨VR縲.VR謗・蜈・縲 2 WEB VIDEO PLATFORM譏ッ荳荳ェ蝓コ莠雑B28181-2016譬螳樒鴫逧ス醍サ懆ァ「大ケウ蜿ー瑚エ溯エ」螳樒鴫譬ク蠢ソ。莉、荳手ョセ螟ョ。逅錘蜿ー驛ィ蛻シ梧髪謖¨AT遨ソ騾擾シ梧髪謖∵オキ蠎キ縲∝、ァ蜊弱∝ョァュ牙刀迚檎噪IPC縲¨VR縲.VR謗・蜈・縲
3 -豬∝ェ剃ス捺恪蜉。蝓コ莠算LMediaKit-https://github.com/xiongziliang/ZLMediaKit 3 +豬∝ェ剃ス捺恪蜉。蝓コ莠算LMediaKit-https://github.com/xiongziliang/ZLMediaKit
4 蜑肴ョオ鬘オ髱「蝓コ莠皿ediaServerUI霑幄。御ソョ謾ケ. 4 蜑肴ョオ鬘オ髱「蝓コ莠皿ediaServerUI霑幄。御ソョ謾ケ.
5 5
6 # 蠎皮畑蝨コ譎ッ 6 # 蠎皮畑蝨コ譎ッ
@@ -16,24 +16,25 @@ WEB VIDEO PLATFORM譏ッ荳荳ェ蝓コ莠雑B28181-2016譬螳樒鴫逧ス醍サ懆ァ「大ケウ蜿ー @@ -16,24 +16,25 @@ WEB VIDEO PLATFORM譏ッ荳荳ェ蝓コ莠雑B28181-2016譬螳樒鴫逧ス醍サ懆ァ「大ケウ蜿ー
16 ![build_1.png](https://github.com/648540858/wiki/blob/master/images/Screenshot_20201012_151606.png) 16 ![build_1.png](https://github.com/648540858/wiki/blob/master/images/Screenshot_20201012_151606.png)
17 17
18 # 蜴溽沿迚ケ諤ァ 18 # 蜴溽沿迚ケ諤ァ
19 -1. 隗「鷹「ァ  
20 -2. 莠大床謗ァ蛻カ域婿蜷代∫シゥ謾セ謗ァ蛻カ  
21 -3. 隗「題ョセ螟ソ。諱ッ蜷梧ュ・  
22 -4. 遖サ蝨ィ郤ソ逶第而  
23 -5. 蠖募ワ譟・隸「荳主屓謾セ亥渕莠晒VR\DVR梧嘯荳肴髪謖∝ソォ霑帙《eek謫堺ス懶シ  
24 -6. 譌莠コ隗ら恚閾ェ蜉ィ譁ュ豬  
25 -  
26 -  
27 -# 譁ー謾ッ謖∫音諤ァ  
28 -1. 髮web逡碁擇, 荳埼怙隕∝黒迢ャ驛ィ鄂イ蜑咲ォッ譛榊苅, 逶エ謗・蛻ゥ逕ィwvp蜀スョ譁サカ譛榊苅驛ィ鄂イ.  
29 -2. 謾ッ謖∝ケウ蜿ー謗・蜈・, 髓亥ッケ螟ァ蟷ウ蜿ー螟ァ驥剰ョセ螟噪諠霑幄。御シ伜喧.  
30 -3. 謾ッ謖∵」邏「,騾夐%遲幃.  
31 -4. 謾ッ謖∬蜉ィ驟咲スョZLM蟐剃ス捺恪蜉。, 蜃丞ー大屏驟咲スョ髣ョ鬚俶園蜃コ邇ー逧琉鬚.  
32 -5. 謾ッ謖∝星逕ィudp螟夂ォッ蜿」讓。蠑, 謠宣ォdp讓。蠑丈ク句ェ剃ス謎シ霎捺ァ閭ス.  
33 -6. 謾ッ謖夐%譏ッ蜷ヲ蜷ォ譛蛾浹鬚醍噪隶セ鄂ョ  
34 -7. 謾ッ謖夐%蟄千岼蠖墓衍隸「  
35 -8. 謾ッ謖「dp/tcp,荳、遘肴ィ。蠑丈シ霎楢ァ「第オ  
36 - 19 +1. 隗「鷹「ァ;
  20 +2. 莠大床謗ァ蛻カ域婿蜷代∫シゥ謾セ謗ァ蛻カ;
  21 +3. 隗「題ョセ螟ソ。諱ッ蜷梧ュ・;
  22 +4. 遖サ蝨ィ郤ソ逶第而;
  23 +5. 蠖募ワ譟・隸「荳主屓謾セ亥渕莠晒VR\DVR梧嘯荳肴髪謖∝ソォ霑帙《eek謫堺ス懶シ;
  24 +6. 譌莠コ隗ら恚閾ェ蜉ィ譁ュ豬;
  25 +7. 謾ッ謖ゞDP蜥卦CP荳、遘榊嵜譬ソ。莉、莨霎捺ィ。蠑;
  26 +
  27 +# 譁ー謾ッ謖∫音諤ァ
  28 +1. 髮web逡碁擇, 荳埼怙隕∝黒迢ャ驛ィ鄂イ蜑咲ォッ譛榊苅, 逶エ謗・蛻ゥ逕ィwvp蜀スョ譁サカ譛榊苅驛ィ鄂イ, 髫舜vp荳襍キ驛ィ鄂イ;
  29 +2. 謾ッ謖∝ケウ蜿ー謗・蜈・, 髓亥ッケ螟ァ蟷ウ蜿ー螟ァ驥剰ョセ螟噪諠霑幄。御シ伜喧;
  30 +3. 謾ッ謖∵」邏「,騾夐%遲幃;
  31 +4. 謾ッ謖∬蜉ィ驟咲スョZLM蟐剃ス捺恪蜉。, 蜃丞ー大屏驟咲スョ髣ョ鬚俶園蜃コ邇ー逧琉鬚;
  32 +5. 謾ッ謖∝星逕ィudp螟夂ォッ蜿」讓。蠑, 謠宣ォdp讓。蠑丈ク句ェ剃ス謎シ霎捺ァ閭ス;
  33 +6. 謾ッ謖夐%譏ッ蜷ヲ蜷ォ譛蛾浹鬚醍噪隶セ鄂ョ;
  34 +7. 謾ッ謖夐%蟄千岼蠖墓衍隸「;
  35 +8. 謾ッ謖「dp/tcp蝗ス譬オ∽シ霎捺ィ。蠑;
  36 +9. 謾ッ謖∫峩謗・霎灘RTSP縲ヽTMP縲?TTP-FLV縲仝ebsocket-FLV縲?LS螟夂ァ榊刻隶ョ豬∝慍蝮
  37 +10.
37 # 蠕ョ樒鴫 38 # 蠕ョ樒鴫
38 荳顔コァ郤ァ閨 39 荳顔コァ郤ァ閨
39 謗ィ豬∝陦ィ 40 謗ィ豬∝陦ィ
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
@@ -538,7 +538,7 @@ public class SIPCommander implements ISIPCommander { @@ -538,7 +538,7 @@ public class SIPCommander implements ISIPCommander {
538 recordInfoXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n"); 538 recordInfoXml.append("<DeviceID>" + channelId + "</DeviceID>\r\n");
539 recordInfoXml.append("<StartTime>" + DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(startTime) + "</StartTime>\r\n"); 539 recordInfoXml.append("<StartTime>" + DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(startTime) + "</StartTime>\r\n");
540 recordInfoXml.append("<EndTime>" + DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(endTime) + "</EndTime>\r\n"); 540 recordInfoXml.append("<EndTime>" + DateUtil.yyyy_MM_dd_HH_mm_ssToISO8601(endTime) + "</EndTime>\r\n");
541 - recordInfoXml.append("<Secrecy>0</Secrecy>\\r\n"); 541 + recordInfoXml.append("<Secrecy>0</Secrecy>\r\n");
542 // 大华NVR要求必须增加一个值为all的文本元素节点Type 542 // 大华NVR要求必须增加一个值为all的文本元素节点Type
543 recordInfoXml.append("<Type>all</Type>\r\n"); 543 recordInfoXml.append("<Type>all</Type>\r\n");
544 recordInfoXml.append("</Query>\r\n"); 544 recordInfoXml.append("</Query>\r\n");
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
@@ -140,8 +140,6 @@ public class ZLMHttpHookListener { @@ -140,8 +140,6 @@ public class ZLMHttpHookListener {
140 streamInfo.setRtmp(String.format("rtmp://%s:%s/rtp/%s", mediaInfo.getLocalIP(), mediaInfo.getRtmpPort(), streamId)); 140 streamInfo.setRtmp(String.format("rtmp://%s:%s/rtp/%s", mediaInfo.getLocalIP(), mediaInfo.getRtmpPort(), streamId));
141 streamInfo.setHls(String.format("http://%s:%s/rtp/%s/hls.m3u8", mediaInfo.getLocalIP(), mediaInfo.getHttpPort(), streamId)); 141 streamInfo.setHls(String.format("http://%s:%s/rtp/%s/hls.m3u8", mediaInfo.getLocalIP(), mediaInfo.getHttpPort(), streamId));
142 streamInfo.setRtsp(String.format("rtsp://%s:%s/rtp/%s", mediaInfo.getLocalIP(), mediaInfo.getRtspPort(), streamId)); 142 streamInfo.setRtsp(String.format("rtsp://%s:%s/rtp/%s", mediaInfo.getLocalIP(), mediaInfo.getRtspPort(), streamId));
143 -  
144 -  
145 storager.startPlay(streamInfo); 143 storager.startPlay(streamInfo);
146 } 144 }
147 145
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java
@@ -74,6 +74,15 @@ public class ZLMRESTfulUtils { @@ -74,6 +74,15 @@ public class ZLMRESTfulUtils {
74 return sendPost("getMediaList",param); 74 return sendPost("getMediaList",param);
75 } 75 }
76 76
  77 + public JSONObject getMediaInfo(String app, String schema, String stream){
  78 + Map<String, Object> param = new HashMap<>();
  79 + param.put("app",app);
  80 + param.put("schema",schema);
  81 + param.put("stream",stream);
  82 + param.put("vhost","__defaultVhost__");
  83 + return sendPost("getMediaInfo",param);
  84 + }
  85 +
77 public JSONObject getRtpInfo(String stream_id){ 86 public JSONObject getRtpInfo(String stream_id){
78 Map<String, Object> param = new HashMap<>(); 87 Map<String, Object> param = new HashMap<>();
79 param.put("stream_id",stream_id); 88 param.put("stream_id",stream_id);
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMUtils.java
@@ -37,7 +37,7 @@ public class ZLMUtils { @@ -37,7 +37,7 @@ public class ZLMUtils {
37 System.out.println(jsonObject.toJSONString()); 37 System.out.println(jsonObject.toJSONString());
38 return newPort; 38 return newPort;
39 }else { 39 }else {
40 - return getNewRTPPort(streamId); 40 + return getNewRTPPort(ssrc);
41 } 41 }
42 } 42 }
43 43
src/main/java/com/genersoft/iot/vmp/storager/jdbc/VideoManagerJdbcStoragerImpl.java
@@ -165,7 +165,7 @@ public class VideoManagerJdbcStoragerImpl implements IVideoManagerStorager { @@ -165,7 +165,7 @@ public class VideoManagerJdbcStoragerImpl implements IVideoManagerStorager {
165 165
166 @Override 166 @Override
167 public void updateCatch() { 167 public void updateCatch() {
168 - 168 + System.out.println("##################");
169 } 169 }
170 170
171 @Override 171 @Override
src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java
@@ -64,18 +64,25 @@ public class PlayController { @@ -64,18 +64,25 @@ public class PlayController {
64 64
65 while (lockFlag) { 65 while (lockFlag) {
66 try { 66 try {
67 -  
68 if (System.currentTimeMillis() - startTime > 15 * 1000) { 67 if (System.currentTimeMillis() - startTime > 15 * 1000) {
69 storager.stopPlay(streamInfo); 68 storager.stopPlay(streamInfo);
70 return new ResponseEntity<String>("timeout",HttpStatus.OK); 69 return new ResponseEntity<String>("timeout",HttpStatus.OK);
71 }else { 70 }else {
  71 + streamInfo = storager.queryPlayByDevice(deviceId, channelId);
72 JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(streamId); 72 JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(streamId);
73 - if (rtpInfo == null || !rtpInfo.getBoolean("exist") || storager.queryPlayByDevice(deviceId, channelId).getFlv() == null){ 73 + if (rtpInfo != null && rtpInfo.getBoolean("exist") && streamInfo.getFlv() != null){
  74 + JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo("rtp", "rtmp", streamId);
  75 + if (mediaInfo.getInteger("code") == 0 && mediaInfo.getBoolean("online")) {
  76 + lockFlag = false;
  77 + JSONArray tracks = mediaInfo.getJSONArray("tracks");
  78 + streamInfo.setTracks(tracks);
  79 + storager.startPlay(streamInfo);
  80 + }else {
  81 +
  82 + }
  83 + }else {
74 Thread.sleep(2000); 84 Thread.sleep(2000);
75 continue; 85 continue;
76 - }else {  
77 - lockFlag = false;  
78 - streamInfo = storager.queryPlay(streamInfo);  
79 }; 86 };
80 } 87 }
81 } catch (InterruptedException e) { 88 } catch (InterruptedException e) {
web_src/src/components/channelList.vue
@@ -54,12 +54,15 @@ @@ -54,12 +54,15 @@
54 </el-table-column> 54 </el-table-column>
55 <el-table-column prop="ptztypeText" label="云台类型"> 55 <el-table-column prop="ptztypeText" label="云台类型">
56 </el-table-column> 56 </el-table-column>
57 - <el-table-column label="操作" width="240" align="center" fixed="right"> 57 + <el-table-column label="操作" width="280" align="center" fixed="right">
58 <template slot-scope="scope"> 58 <template slot-scope="scope">
59 - <el-button size="mini" icon="el-icon-video-play" v-if="scope.row.parental == 0" @click="sendDevicePush(scope.row)">播放</el-button>  
60 - <el-button size="mini" icon="el-icon-switch-button" type="danger" v-if="scope.row.play" @click="stopDevicePush(scope.row)">停止</el-button>  
61 - <el-button size="mini" icon="el-icon-s-open" type="primary" v-if="scope.row.parental == 1" @click="changeSubchannel(scope.row)">查看子目录</el-button>  
62 - <!-- <el-button size="mini" @click="sendDevicePush(scope.row)">录像查询</el-button> --> 59 + <el-button-group>
  60 + <el-button size="mini" icon="el-icon-video-play" v-if="scope.row.parental == 0" @click="sendDevicePush(scope.row)">播放</el-button>
  61 + <el-button size="mini" icon="el-icon-switch-button" type="danger" v-if="scope.row.play" @click="stopDevicePush(scope.row)">停止</el-button>
  62 + <el-button size="mini" icon="el-icon-s-open" type="primary" v-if="scope.row.parental == 1" @click="changeSubchannel(scope.row)">查看</el-button>
  63 +<!-- <el-button size="mini" icon="el-icon-video-camera" type="primary" >设备录象</el-button>-->
  64 + <!-- <el-button size="mini" @click="sendDevicePush(scope.row)">录像查询</el-button> -->
  65 + </el-button-group>
63 </template> 66 </template>
64 </el-table-column> 67 </el-table-column>
65 </el-table> 68 </el-table>
web_src/src/components/gb28181/devicePlayer.vue
1 <template> 1 <template>
2 <div id="devicePlayer"> 2 <div id="devicePlayer">
3 <el-dialog title="视频播放" top="0" :visible.sync="showVideoDialog" :destroy-on-close="true" @close="close()"> 3 <el-dialog title="视频播放" top="0" :visible.sync="showVideoDialog" :destroy-on-close="true" @close="close()">
4 - <LivePlayer v-if="showVideoDialog && hasaudio" ref="videoPlayer" :videoUrl="videoUrl" :error="videoError" hasaudio fluent autoplay live ></LivePlayer>  
5 - <LivePlayer v-if="showVideoDialog && !hasaudio" ref="videoPlayer" :videoUrl="videoUrl" :error="videoError" fluent autoplay live ></LivePlayer> 4 + <LivePlayer v-if="showVideoDialog" ref="videoPlayer" :videoUrl="videoUrl" :error="videoError" :hasaudio="hasaudio" fluent autoplay live ></LivePlayer>
6 <div id="shared" style="text-align: right; margin-top: 1rem;"> 5 <div id="shared" style="text-align: right; margin-top: 1rem;">
7 <el-tabs v-model="tabActiveName"> 6 <el-tabs v-model="tabActiveName">
8 <el-tab-pane label="媒体流信息" name="media"> 7 <el-tab-pane label="媒体流信息" name="media">
@@ -123,20 +122,17 @@ @@ -123,20 +122,17 @@
123 methods: { 122 methods: {
124 123
125 play: function(streamInfo, deviceId, channelId, hasAudio) { 124 play: function(streamInfo, deviceId, channelId, hasAudio) {
126 - // this.hasaudio = hasAudio;  
127 - if (!hasAudio) { // hasaudio == false时设置播放器hasaudio false, 否则不设置  
128 - this.hasaudio = hasAudio;  
129 - } 125 + this.hasaudio = hasAudio;
130 // 根据媒体流信息二次判断 126 // 根据媒体流信息二次判断
131 - // if( this.hasaudio && !!streamInfo.tracks && streamInfo.tracks.length > 0) {  
132 - // var realHasAudio = false;  
133 - // for (let i = 0; i < streamInfo.tracks; i++) {  
134 - // if (streamInfo.tracks[i].codec_type == 1) { // 判断为音频  
135 - // realHasAudio = true;  
136 - // }  
137 - // }  
138 - // this.hasaudio = realHasAudio && this.hasaudio;  
139 - // } 127 + if( this.hasaudio && !!streamInfo.tracks && streamInfo.tracks.length > 0) {
  128 + var realHasAudio = false;
  129 + for (let i = 0; i < streamInfo.tracks; i++) {
  130 + if (streamInfo.tracks[i].codec_type == 1) { // 判断为音频
  131 + realHasAudio = true;
  132 + }
  133 + }
  134 + this.hasaudio = realHasAudio && this.hasaudio;
  135 + }
140 this.ssrc = streamInfo.ssrc; 136 this.ssrc = streamInfo.ssrc;
141 this.deviceId = deviceId; 137 this.deviceId = deviceId;
142 this.channelId = channelId; 138 this.channelId = channelId;