648540858
2023-03-21 455e58f866d7f538422f50362137d9759dc58768
优化合并对讲broadcast级联模式
4个文件已修改
95 ■■■■■ 已修改文件
src/main/java/com/genersoft/iot/vmp/gb28181/session/AudioBroadcastManager.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
web_src/src/components/dialog/devicePlayer.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/session/AudioBroadcastManager.java
@@ -87,7 +87,9 @@
    public List<AudioBroadcastCatch> get(String deviceId) {
        List<AudioBroadcastCatch> audioBroadcastCatchList= new ArrayList<>();
        if (SipUtils.isFrontEnd(deviceId)) {
            if (data.get(deviceId) != null) {
            audioBroadcastCatchList.add(data.get(deviceId));
            }
        }else {
            for (String key : data.keySet()) {
                if (key.startsWith(deviceId)) {
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/ByeRequestProcessor.java
@@ -2,14 +2,12 @@
import com.genersoft.iot.vmp.common.StreamInfo;
import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException;
import com.genersoft.iot.vmp.gb28181.bean.Device;
import com.genersoft.iot.vmp.gb28181.bean.InviteStreamType;
import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction;
import com.genersoft.iot.vmp.gb28181.bean.*;
import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager;
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorObserver;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
import com.genersoft.iot.vmp.gb28181.transmit.event.request.ISIPRequestProcessor;
import com.genersoft.iot.vmp.gb28181.transmit.event.request.SIPRequestProcessorParent;
import com.genersoft.iot.vmp.media.zlm.ZLMRTPServerFactory;
@@ -37,6 +35,7 @@
import javax.sip.message.Response;
import java.text.ParseException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
@@ -50,6 +49,9 @@
    @Autowired
    private ISIPCommander cmder;
    @Autowired
    private ISIPCommanderForPlatform commanderForPlatform;
    @Autowired
    private IRedisCatchStorage redisCatchStorage;
@@ -204,12 +206,86 @@
                case broadcast:
                    String deviceId = ssrcTransaction.getDeviceId();
                    String channelId1 = ssrcTransaction.getChannelId();
                    // 如果是
                    Device deviceFromTransaction = storager.queryVideoDevice(deviceId);
                    if (deviceFromTransaction == null) {
                        ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(deviceId);
                        if (parentPlatform != null) {
                            // 来自上级平台的停止对讲
                            // 释放ssrc
                            MediaServerItem mediaServerItemFromTransaction = mediaServerService.getOne(ssrcTransaction.getMediaServerId());
                            if (mediaServerItemFromTransaction != null) {
                                mediaServerService.releaseSsrc(mediaServerItemFromTransaction.getId(), ssrcTransaction.getSsrc());
                            }
                            streamSession.remove(ssrcTransaction.getDeviceId(), ssrcTransaction.getChannelId(), ssrcTransaction.getStream());
                        }
                    }else {
                        // 来自设备的停止对讲
                        // 如果是来自设备,则听停止推流。 来自上级则停止收流
                        AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(deviceId, channelId1);
                        if (audioBroadcastCatch != null) {
                            //
                            SendRtpItem sendRtpItemForBroadcast =  redisCatchStorage.querySendRTPServer(deviceId, channelId1,
                                    audioBroadcastCatch.getStream(), audioBroadcastCatch.getSipTransactionInfo().getCallId());
                            if (sendRtpItemForBroadcast != null) {
                                MediaServerItem mediaServerItemForBroadcast = mediaServerService.getOne(sendRtpItem.getMediaServerId());
                                if (mediaServerItemForBroadcast == null) {
                                    return;
                                }
                                Boolean ready = zlmrtpServerFactory.isStreamReady(mediaServerItem, sendRtpItem.getApp(), audioBroadcastCatch.getStream());
                                if (ready) {
                                    Map<String, Object> param = new HashMap<>();
                                    param.put("vhost","__defaultVhost__");
                                    param.put("app",sendRtpItem.getApp());
                                    param.put("stream",audioBroadcastCatch.getStream());
                                    param.put("ssrc",sendRtpItem.getSsrc());
                                    logger.info("[收到bye] 停止推流:{}", audioBroadcastCatch.getStream());
                                    MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
                                    redisCatchStorage.deleteSendRTPServer(sendRtpItem.getPlatformId(), sendRtpItem.getChannelId(), request.getCallIdHeader().getCallId(), null);
                                    zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param);
                                }
                                if (audioBroadcastCatch.isFromPlatform()) {
                                    // 上级也正在点播。 向上级回复bye
                                    List<SsrcTransaction> ssrcTransactions = streamSession.getSsrcTransactionForAll(null, channelId1, null, null);
                                    if (ssrcTransactions.size() > 0) {
                                        for (SsrcTransaction transaction : ssrcTransactions) {
                                            if (transaction.getType().equals(VideoStreamSessionManager.SessionType.broadcast)) {
                                                ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(transaction.getDeviceId());
                                                if (parentPlatform != null) {
                                                    try {
                                                        commanderForPlatform.streamByeCmd(parentPlatform, channelId1, transaction.getStream(), transaction.getCallId(), eventResult -> {
                                                            streamSession.remove(transaction.getDeviceId(), transaction.getChannelId(), transaction.getStream());
                                                        });
                                                    } catch (InvalidArgumentException | SipException | ParseException |
                                                             SsrcTransactionNotFoundException e) {
                                                        logger.error("[命令发送失败] 向{}发送bye失败", transaction.getDeviceId());
                                                    }
                                                    // 释放ssrc
                                                    MediaServerItem mediaServerItemFromTransaction = mediaServerService.getOne(transaction.getMediaServerId());
                                                    if (mediaServerItemFromTransaction != null) {
                                                        mediaServerService.releaseSsrc(mediaServerItemFromTransaction.getId(), transaction.getSsrc());
                                                    }
                                                    streamSession.remove(transaction.getDeviceId(), transaction.getChannelId(), transaction.getStream());
                                                }
                                            }
                                        }
                                    }
                                }
                                redisCatchStorage.deleteSendRTPServer(deviceId, channelId1,
                                        audioBroadcastCatch.getStream(), audioBroadcastCatch.getSipTransactionInfo().getCallId());
                            }
                            audioBroadcastManager.del(deviceId, channelId1);
                        }
                    }
                    break;
                default:
                    break;
            }
            streamSession.remove(device.getDeviceId(), channelId, ssrcTransaction.getStream());
        }
    }
}
src/main/java/com/genersoft/iot/vmp/service/impl/DeviceServiceImpl.java
@@ -195,6 +195,7 @@
        List<AudioBroadcastCatch> audioBroadcastCatches = audioBroadcastManager.get(deviceId);
        if (audioBroadcastCatches.size() > 0) {
            for (AudioBroadcastCatch audioBroadcastCatch : audioBroadcastCatches) {
                SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(deviceId, audioBroadcastCatch.getChannelId(), null, null);
                if (sendRtpItem != null) {
                    redisCatchStorage.deleteSendRTPServer(deviceId, sendRtpItem.getChannelId(), null, null);
web_src/src/components/dialog/devicePlayer.vue
@@ -301,8 +301,8 @@
          <el-tab-pane label="语音对讲" name="broadcast">
            <div style="padding: 0 10px">
              <el-switch v-model="broadcastMode" :disabled="broadcastStatus !== -1" active-color="#409EFF"
                         active-text="喊话"
                         inactive-text="对讲"></el-switch>
                         active-text="喊话(Broadcast)"
                         inactive-text="对讲(Talk)"></el-switch>
            </div>
            <div class="trank" style="text-align: center;">
              <el-button @click="broadcastStatusClick()" :type="getBroadcastStatus()" :disabled="broadcastStatus === -2"