From fbdad00cdb294a857f55e33b2dd92c61dc37475c Mon Sep 17 00:00:00 2001
From: 648540858 <648540858@qq.com>
Date: 星期二, 13 十月 2020 18:55:42 +0800
Subject: [PATCH] 修复无音频通道开启通道音频后无法播放的bug 修复点播接口真的收到视频后回复
---
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRunner.java | 116 ++++++++---------------
src/main/java/com/genersoft/iot/vmp/vmanager/play/PlayController.java | 40 +++++++
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java | 7 +
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java | 86 +++++++++++++++++
src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java | 11 ++
web_src/src/components/gb28181/devicePlayer.vue | 12 ++
6 files changed, 193 insertions(+), 79 deletions(-)
diff --git a/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java b/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java
index 0e7da44..270f72a 100644
--- a/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java
+++ b/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java
@@ -1,5 +1,7 @@
package com.genersoft.iot.vmp.common;
+import com.alibaba.fastjson.JSONArray;
+
public class StreamInfo {
private String ssrc;
@@ -10,6 +12,7 @@
private String rtmp;
private String hls;
private String rtsp;
+ private JSONArray tracks;
public String getSsrc() {
return ssrc;
@@ -74,4 +77,12 @@
public void setCahnnelId(String cahnnelId) {
this.cahnnelId = cahnnelId;
}
+
+ public JSONArray getTracks() {
+ return tracks;
+ }
+
+ public void setTracks(JSONArray tracks) {
+ this.tracks = tracks;
+ }
}
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
index 666cc25..4c9f6fd 100644
--- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
@@ -46,6 +46,9 @@
@Autowired
private IVideoManagerStorager storager;
+ @Autowired
+ private ZLMRESTfulUtils zlmresTfulUtils;
+
@Value("${media.ip}")
private String mediaIp;
@@ -125,6 +128,8 @@
}
String app = json.getString("app");
String streamId = json.getString("id");
+
+
// String ssrc = String.format("%10d", Integer.parseInt(streamId, 16)); // ZLM 瑕佹眰澶у啓涓旈浣嶈ˉ闆�
String ssrc = new DecimalFormat("0000000000").format(Integer.parseInt(streamId, 16));
StreamInfo streamInfo = storager.queryPlayBySSRC(ssrc);
@@ -135,6 +140,8 @@
streamInfo.setRtmp(String.format("rtmp://%s:%s/rtp/%s", mediaInfo.getLocalIP(), mediaInfo.getRtmpPort(), streamId));
streamInfo.setHls(String.format("http://%s:%s/rtp/%s/hls.m3u8", mediaInfo.getLocalIP(), mediaInfo.getHttpPort(), streamId));
streamInfo.setRtsp(String.format("rtsp://%s:%s/rtp/%s", mediaInfo.getLocalIP(), mediaInfo.getRtspPort(), streamId));
+
+
storager.startPlay(streamInfo);
}
diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java
new file mode 100644
index 0000000..01aa341
--- /dev/null
+++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRESTfulUtils.java
@@ -0,0 +1,86 @@
+package com.genersoft.iot.vmp.media.zlm;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import okhttp3.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+
+@Component
+public class ZLMRESTfulUtils {
+
+ private final static Logger logger = LoggerFactory.getLogger(ZLMRESTfulUtils.class);
+
+ @Value("${media.ip}")
+ private String mediaIp;
+
+ @Value("${media.port}")
+ private int mediaPort;
+
+ @Value("${media.secret}")
+ private String mediaSecret;
+
+ public JSONObject sendPost(String api, Map<String, Object> param) {
+ OkHttpClient client = new OkHttpClient();
+ String url = String.format("http://%s:%s/index/api/%s", mediaIp, mediaPort, api);
+ JSONObject responseJSON = null;
+ logger.debug(url);
+
+ FormBody.Builder builder = new FormBody.Builder();
+ builder.add("secret",mediaSecret);
+ if (param != null) {
+ for (String key : param.keySet()){
+ builder.add(key, param.get(key).toString());
+ }
+ }
+
+ FormBody body = builder.build();
+
+ Request request = new Request.Builder()
+ .post(body)
+ .url(url)
+ .build();
+ try {
+ Response response = client.newCall(request).execute();
+ if (response.isSuccessful()) {
+ String responseStr = response.body().string();
+ if (responseStr != null) {
+ responseJSON = JSON.parseObject(responseStr);
+ }
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ return responseJSON;
+ }
+
+ public JSONObject getMediaList(String app, String schema){
+ Map<String, Object> param = new HashMap<>();
+ param.put("app",app);
+ param.put("schema",schema);
+ param.put("vhost","__defaultVhost__");
+ return sendPost("getMediaList",param);
+ }
+
+ public JSONObject getRtpInfo(String stream_id){
+ Map<String, Object> param = new HashMap<>();
+ param.put("stream_id",stream_id);
+ return sendPost("getRtpInfo",param);
+ }
+
+ public JSONObject getMediaServerConfig(){
+ return sendPost("getServerConfig",null);
+ }
+
+ public JSONObject setServerConfig(Map<String, Object> param){
+ return sendPost("setServerConfig",param);
+ }
+}
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 8dc8e50..8114814 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
@@ -17,6 +17,8 @@
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
+import java.util.HashMap;
+import java.util.Map;
@Component
@Order(value=1)
@@ -42,6 +44,9 @@
@Value("${server.port}")
private String serverPort;
+ @Autowired
+ private ZLMRESTfulUtils zlmresTfulUtils;
+
@Override
public void run(String... strings) throws Exception {
// 鑾峰彇zlm淇℃伅
@@ -59,41 +64,23 @@
public MediaServerConfig getMediaServerConfig() {
+ JSONObject responseJSON = zlmresTfulUtils.getMediaServerConfig();
MediaServerConfig mediaServerConfig = null;
- OkHttpClient client = new OkHttpClient();
- String url = String.format("http://%s:%s/index/api/getServerConfig?secret=%s", mediaIp, mediaPort, mediaSecret);
- //鍒涘缓涓�涓猂equest
- Request request = new Request.Builder()
- .get()
- .url(url)
- .build();
- //閫氳繃client鍙戣捣璇锋眰
- final Call call = client.newCall(request);
- //鎵ц鍚屾璇锋眰锛岃幏鍙朢esponse瀵硅薄
- Response response = null;
- try {
- response = call.execute();
- if (response.isSuccessful()) {
- String responseStr = response.body().string();
- if (responseStr != null) {
- JSONObject responseJSON = JSON.parseObject(responseStr);
- JSONArray data = responseJSON.getJSONArray("data");
- if (data != null && data.size() > 0) {
- mediaServerConfig = JSON.parseObject(JSON.toJSONString(data.get(0)), MediaServerConfig.class);
- mediaServerConfig.setLocalIP(mediaIp);
- }
- }
- }else {
- logger.error("getMediaServerConfig澶辫触, 1s鍚庨噸璇�");
- Thread.sleep(1000);
- getMediaServerConfig();
+ if (responseJSON != null) {
+ JSONArray data = responseJSON.getJSONArray("data");
+ if (data != null && data.size() > 0) {
+ mediaServerConfig = JSON.parseObject(JSON.toJSONString(data.get(0)), MediaServerConfig.class);
+ mediaServerConfig.setLocalIP(mediaIp);
}
- } catch (IOException e) {
- e.printStackTrace();
- } catch (InterruptedException e) {
- e.printStackTrace();
+ } else {
+ logger.error("getMediaServerConfig澶辫触, 1s鍚庨噸璇�");
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ getMediaServerConfig();
}
-
return mediaServerConfig;
}
@@ -102,51 +89,30 @@
if (mediaIp.equals(sipIP)) {
hookIP = "127.0.0.1";
}
- OkHttpClient client = new OkHttpClient();
- String url = String.format("http://%s:%s/index/api/setServerConfig", mediaIp, mediaPort);
+
String hookPrex = String.format("http://%s:%s/index/hook", hookIP, serverPort);
+ Map<String, Object> param = new HashMap<>();
+ param.put("secret",mediaSecret);
+ param.put("hook.enable","1");
+ param.put("hook.on_flow_report","");
+ param.put("hook.on_http_access","");
+ param.put("hook.on_publish",String.format("%s/on_publish", hookPrex));
+ param.put("hook.on_record_mp4","");
+ param.put("hook.on_record_ts","");
+ param.put("hook.on_rtsp_auth","");
+ param.put("hook.on_rtsp_realm","");
+ param.put("hook.on_server_started",String.format("%s/on_server_started", hookPrex));
+ param.put("hook.on_shell_login",String.format("%s/on_shell_login", hookPrex));
+ 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");
- RequestBody body = new FormBody.Builder()
- .add("secret",mediaSecret)
- .add("hook.enable","1")
- .add("hook.on_flow_report","")
- .add("hook.on_http_access","")
- .add("hook.on_publish",String.format("%s/on_publish", hookPrex))
- .add("hook.on_record_mp4","")
- .add("hook.on_record_ts","")
- .add("hook.on_rtsp_auth","")
- .add("hook.on_rtsp_realm","")
- .add("hook.on_server_started",String.format("%s/on_server_started", hookPrex))
- .add("hook.on_shell_login",String.format("%s/on_shell_login", hookPrex))
- .add("hook.on_stream_none_reader",String.format("%s/on_stream_none_reader", hookPrex))
- .add("hook.on_stream_not_found",String.format("%s/on_stream_not_found", hookPrex))
- .add("hook.timeoutSec","20")
- .build();
+ JSONObject responseJSON = zlmresTfulUtils.setServerConfig(param);
- Request request = new Request.Builder()
- .post(body)
- .url(url)
- .build();
- client.newCall(request).enqueue(new Callback() {
- @Override
- public void onFailure(Call call, IOException e) {
- logger.error("saveZLMConfig ",e);
- }
- @Override
- public void onResponse(Call call, Response response) throws IOException {
- if (response.isSuccessful()) {
- String responseStr = response.body().string();
- if (responseStr != null) {
- JSONObject responseJSON = JSON.parseObject(responseStr);
- if (responseJSON.getInteger("code") == 0) {
- logger.info("璁剧疆zlm鎴愬姛");
- }else {
- logger.info("璁剧疆zlm澶辫触: " + responseJSON.getString("msg"));
- }
- }
- }
-
- }
- });
+ if (responseJSON != null && responseJSON.getInteger("code") == 0) {
+ logger.info("璁剧疆zlm鎴愬姛");
+ }else {
+ logger.info("璁剧疆zlm澶辫触: " + responseJSON.getString("msg"));
+ }
}
}
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 119426a..996039e 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
@@ -1,7 +1,9 @@
package com.genersoft.iot.vmp.vmanager.play;
import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
import com.genersoft.iot.vmp.common.StreamInfo;
+import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -31,6 +33,9 @@
@Autowired
private IVideoManagerStorager storager;
+
+ @Autowired
+ private ZLMRESTfulUtils zlmresTfulUtils;
@GetMapping("/play/{deviceId}/{channelId}")
public ResponseEntity<String> play(@PathVariable String deviceId,@PathVariable String channelId){
@@ -38,17 +43,44 @@
Device device = storager.queryVideoDevice(deviceId);
StreamInfo streamInfo = cmder.playStreamCmd(device, channelId);
// 绛夊緟鎺ㄦ祦, TODO 榛樿瓒呮椂15s
-
+ boolean lockFlag = true;
long startTime = System.currentTimeMillis();
- while (storager.queryPlay(streamInfo) == null || storager.queryPlay(streamInfo).getFlv() == null) {
+ String streamId = String.format("%08x", Integer.parseInt(streamInfo.getSsrc())).toUpperCase();
+
+ // 鍒ゆ柇鎺ㄦ祦鏄惁瀛樺湪
+ while (lockFlag) {
try {
- if (System.currentTimeMillis() - startTime > 15 * 1000)
+ if (System.currentTimeMillis() - startTime > 15 * 1000) {
+ JSONObject rtpInfo = zlmresTfulUtils.getRtpInfo(streamId);
+ if (rtpInfo == null){
+ continue;
+ }else {
+ lockFlag = false;
+ streamInfo = storager.queryPlay(streamInfo);
+ // 鑾峰彇濯掍綋淇℃伅
+ JSONObject mediaList = zlmresTfulUtils.getMediaList("rtp", "rtmp");
+ if (mediaList.getInteger("code") == 0) {
+ JSONArray data = mediaList.getJSONArray("data");
+ if (data!= null) {
+ for (Object datum : data) {
+ JSONObject media = (JSONObject)datum;
+ if (streamId.equals(media.getString("stream"))) {
+ streamInfo.setTracks(media.getJSONArray("tracks"));
+ storager.startPlay(streamInfo);
+ }
+ }
+ }
+ }
+ };
+
+ }
+
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
- streamInfo = storager.queryPlay(streamInfo);
+
if (logger.isDebugEnabled()) {
logger.debug(String.format("璁惧棰勮 API璋冪敤锛宒eviceId锛�%s 锛宑hannelId锛�%s",deviceId, channelId));
logger.debug("璁惧棰勮 API璋冪敤锛宻src锛�"+streamInfo.getSsrc()+",ZLMedia streamId:"+Integer.toHexString(Integer.parseInt(streamInfo.getSsrc())));
diff --git a/web_src/src/components/gb28181/devicePlayer.vue b/web_src/src/components/gb28181/devicePlayer.vue
index f49e03f..9e497e4 100644
--- a/web_src/src/components/gb28181/devicePlayer.vue
+++ b/web_src/src/components/gb28181/devicePlayer.vue
@@ -124,6 +124,18 @@
play: function(streamInfo, deviceId, channelId, hasAudio) {
console.log(hasAudio);
this.hasaudio = hasAudio;
+ // 鏍规嵁濯掍綋娴佷俊鎭簩娆″垽鏂�
+ if( this.hasaudio && !!streamInfo.tracks && streamInfo.tracks.length > 0) {
+ var realHasAudio = false;
+ for (let i = 0; i < streamInfo.tracks; i++) {
+ if (streamInfo.tracks[i].codec_type == 1) { // 鍒ゆ柇涓洪煶棰�
+ realHasAudio = true;
+ }
+ }
+ this.hasaudio = realHasAudio && this.hasaudio;
+ }
+ console.log("111")
+ console.log(this.hasaudio)
this.ssrc = streamInfo.ssrc;
this.deviceId = deviceId;
this.channelId = channelId;
--
Gitblit v1.8.0