From 9c555b56b70ed05c1b13f0a26098b702d7364839 Mon Sep 17 00:00:00 2001
From: 648540858 <648540858@qq.com>
Date: 星期三, 18 五月 2022 18:14:46 +0800
Subject: [PATCH] 优化语音广播的TCP主动模式

---
 src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java |  104 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 104 insertions(+), 0 deletions(-)

diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
index 17658e7..f0ffb84 100644
--- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
@@ -5,9 +5,11 @@
 import com.alibaba.fastjson.JSONObject;
 import com.genersoft.iot.vmp.common.StreamInfo;
 import com.genersoft.iot.vmp.conf.DynamicTask;
+import com.genersoft.iot.vmp.conf.SipConfig;
 import com.genersoft.iot.vmp.conf.UserSetting;
 import com.genersoft.iot.vmp.gb28181.bean.*;
 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
+import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager;
 import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
 import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
@@ -26,7 +28,9 @@
 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
 import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
 import com.genersoft.iot.vmp.utils.redis.RedisUtil;
+import com.genersoft.iot.vmp.vmanager.bean.AudioBroadcastResult;
 import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
+import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.AudioBroadcastEvent;
 import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.PlayResult;
 import com.genersoft.iot.vmp.service.IMediaService;
 import com.genersoft.iot.vmp.service.IPlayService;
@@ -41,9 +45,13 @@
 import org.springframework.web.context.request.async.DeferredResult;
 
 import javax.sip.ResponseEvent;
+import javax.sip.SipException;
 import java.io.FileNotFoundException;
 import java.math.BigDecimal;
+import java.text.ParseException;
 import java.util.*;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 @SuppressWarnings(value = {"rawtypes", "unchecked"})
 @Service
@@ -56,6 +64,9 @@
 
     @Autowired
     private SIPCommander cmder;
+
+    @Autowired
+    private AudioBroadcastManager audioBroadcastManager;
 
     @Autowired
     private SIPCommanderFroPlatform sipCommanderFroPlatform;
@@ -88,7 +99,13 @@
     private UserSetting userSetting;
 
     @Autowired
+    private SipConfig sipConfig;
+
+    @Autowired
     private DynamicTask dynamicTask;
+
+    @Autowired
+    private ZLMHttpHookSubscribe subscribe;
 
 
 
@@ -259,6 +276,7 @@
             }
         }, userSetting.getPlayTimeout()*1000);
         final String ssrc = ssrcInfo.getSsrc();
+        final String stream = ssrcInfo.getStream();
         cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (MediaServerItem mediaServerItemInuse, JSONObject response) -> {
             logger.info("鏀跺埌璁㈤槄娑堟伅锛� " + response.toJSONString());
             dynamicTask.stop(timeOutTaskKey);
@@ -278,6 +296,7 @@
                 if (ssrc.equals(ssrcInResponse)) {
                     return;
                 }
+                logger.info("[SIP 娑堟伅] 鏀跺埌invite 200, 鍙戠幇涓嬬骇鑷畾涔変簡ssrc 寮�鍚慨姝�");
                 if (!mediaServerItem.isRtpEnable() || device.isSsrcCheck()) {
                     if (!mediaServerItem.getSsrcConfig().checkSsrc(ssrcInResponse)) {
                         // ssrc 涓嶅彲鐢�
@@ -289,10 +308,32 @@
                         errorEvent.response(event);
                         return;
                     }
+
+                    // 鍗曠鍙fā寮弒treamId涔熸湁鍙樺寲锛岄渶瑕侀噸鏂拌缃洃鍚�
+                    if (!mediaServerItem.isRtpEnable()) {
+                        // 娣诲姞璁㈤槄
+                        JSONObject subscribeKey = new JSONObject();
+                        subscribeKey.put("app", "rtp");
+                        subscribeKey.put("stream", stream);
+                        subscribeKey.put("regist", true);
+                        subscribeKey.put("schema", "rtmp");
+                        subscribeKey.put("mediaServerId", mediaServerItem.getId());
+                        subscribe.removeSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed,subscribeKey);
+                        subscribeKey.put("stream", String.format("%08x", Integer.parseInt(ssrcInResponse)).toUpperCase());
+                        subscribe.addSubscribe(ZLMHttpHookSubscribe.HookType.on_stream_changed, subscribeKey,
+                                (MediaServerItem mediaServerItemInUse, JSONObject response)->{
+                                    logger.info("[ZLM HOOK] ssrc淇鍚庢敹鍒拌闃呮秷鎭細 " + response.toJSONString());
+                                    dynamicTask.stop(timeOutTaskKey);
+                                    // hook鍝嶅簲
+                                    onPublishHandlerForPlay(mediaServerItemInUse, response, device.getDeviceId(), channelId, uuid);
+                                    hookEvent.response(mediaServerItemInUse, response);
+                                });
+                    }
                     // 鍏抽棴rtp server
                     mediaServerService.closeRTPServer(device.getDeviceId(), channelId, finalSsrcInfo.getStream());
                     // 閲嶆柊寮�鍚痵src server
                     mediaServerService.openRTPServer(mediaServerItem, finalSsrcInfo.getStream(), ssrcInResponse, device.isSsrcCheck(), false);
+
                 }
             }
         }, (event) -> {
@@ -624,4 +665,67 @@
             }
         }
     }
+
+    @Override
+    public void audioBroadcast(Device device, String channelId, int timeout, AudioBroadcastEvent event) {
+        if (device == null || channelId == null) {
+            return;
+        }
+        DeviceChannel deviceChannel = storager.queryChannel(device.getDeviceId(), channelId);
+        if (deviceChannel == null) {
+            logger.warn("寮�鍚闊冲箍鎾殑鏃跺�欐湭鎵惧埌閫氶亾锛� {}", channelId);
+            event.call("寮�鍚闊冲箍鎾殑鏃跺�欐湭鎵惧埌閫氶亾");
+            return;
+        }
+        // 鏌ヨ閫氶亾浣跨敤鐘舵��
+        if (audioBroadcastManager.exit(device.getDeviceId(), channelId)) {
+            SendRtpItem sendRtpItem =  redisCatchStorage.querySendRTPServer(device.getDeviceId(), channelId, null, null);
+            if (sendRtpItem != null && sendRtpItem.isOnlyAudio()) {
+                logger.warn("璇煶骞挎挱宸茬粡寮�鍚細 {}", channelId);
+                event.call("璇煶骞挎挱宸茬粡寮�鍚�");
+                return;
+            }
+        }
+
+        // 鍙戦�侀�氱煡
+        cmder.audioBroadcastCmd(device, channelId, eventResultForOk -> {
+            // 鍙戦�佹垚鍔�
+            AudioBroadcastCatch audioBroadcastCatch = new AudioBroadcastCatch(device.getDeviceId(), channelId, AudioBroadcastCatchStatus.Ready);
+            audioBroadcastManager.add(audioBroadcastCatch);
+        }, eventResultForError -> {
+            // 鍙戦�佸け璐�
+            logger.error("璇煶骞挎挱鍙戦�佸け璐ワ細 {}:{}", channelId, eventResultForError.msg);
+            event.call("璇煶骞挎挱鍙戦�佸け璐�");
+            stopAudioBroadcast(device.getDeviceId(), channelId);
+        });
+    }
+
+    @Override
+    public void stopAudioBroadcast(String deviceId, String channelId){
+        AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(deviceId, channelId);
+        if (audioBroadcastCatch != null) {
+            audioBroadcastManager.del(deviceId, audioBroadcastCatch.getChannelId());
+            try {
+                SendRtpItem sendRtpItem =  redisCatchStorage.querySendRTPServer(deviceId, audioBroadcastCatch.getChannelId(), null, null);
+                if (sendRtpItem != null) {
+                    redisCatchStorage.deleteSendRTPServer(deviceId, sendRtpItem.getChannelId(), null, null);
+                    MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
+                    Map<String, Object> param = new HashMap<>();
+                    param.put("vhost", "__defaultVhost__");
+                    param.put("app", sendRtpItem.getApp());
+                    param.put("stream", sendRtpItem.getStreamId());
+                    zlmresTfulUtils.stopSendRtp(mediaInfo, param);
+                }
+                if (audioBroadcastCatch.getStatus() == AudioBroadcastCatchStatus.Ok) {
+                    cmder.streamByeCmd(audioBroadcastCatch.getDialog(), audioBroadcastCatch.getRequest(), null);
+                }
+            } catch (SipException e) {
+                throw new RuntimeException(e);
+            } catch (ParseException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+
+    }
 }

--
Gitblit v1.8.0