648540858
2023-01-05 e14cef80624602d873b1062aed93022b8ad13182
优化语音对讲
6个文件已修改
109 ■■■■■ 已修改文件
src/main/java/com/genersoft/iot/vmp/gb28181/bean/SipTransactionInfo.java 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/BroadcastResponseMessageHandler.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java 64 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/bean/SipTransactionInfo.java
@@ -9,14 +9,15 @@
    private String toTag;
    private String viaBranch;
    private boolean fromServer;
    // 自己是否媒体流发送者
    private boolean asSender;
    public SipTransactionInfo(SIPResponse response, boolean fromServer) {
    public SipTransactionInfo(SIPResponse response, boolean asSender) {
        this.callId = response.getCallIdHeader().getCallId();
        this.fromTag = response.getFromTag();
        this.toTag = response.getToTag();
        this.viaBranch = response.getTopmostViaHeader().getBranch();
        this.fromServer = fromServer;
        this.asSender = asSender;
    }
    public SipTransactionInfo(SIPResponse response) {
@@ -24,7 +25,6 @@
        this.fromTag = response.getFromTag();
        this.toTag = response.getToTag();
        this.viaBranch = response.getTopmostViaHeader().getBranch();
        this.fromServer = true;
    }
    public SipTransactionInfo() {
@@ -62,11 +62,11 @@
        this.viaBranch = viaBranch;
    }
    public boolean isFromServer() {
        return fromServer;
    public boolean isAsSender() {
        return asSender;
    }
    public void setFromServer(boolean fromServer) {
        this.fromServer = fromServer;
    public void setAsSender(boolean asSender) {
        this.asSender = asSender;
    }
}
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java
@@ -170,11 +170,11 @@
        //from
        SipURI fromSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(sipConfig.getId(),sipConfig.getDomain());
        Address fromAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(fromSipURI);
        FromHeader fromHeader = sipLayer.getSipFactory().createHeaderFactory().createFromHeader(fromAddress, transactionInfo.isFromServer()?transactionInfo.getFromTag():transactionInfo.getToTag());
        FromHeader fromHeader = sipLayer.getSipFactory().createHeaderFactory().createFromHeader(fromAddress, transactionInfo.isAsSender()? transactionInfo.getFromTag():transactionInfo.getToTag());
        //to
        SipURI toSipURI = sipLayer.getSipFactory().createAddressFactory().createSipURI(channelId,device.getHostAddress());
        Address toAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(toSipURI);
        ToHeader toHeader = sipLayer.getSipFactory().createHeaderFactory().createToHeader(toAddress,transactionInfo.isFromServer()?transactionInfo.getToTag():transactionInfo.getFromTag());
        ToHeader toHeader = sipLayer.getSipFactory().createHeaderFactory().createToHeader(toAddress, transactionInfo.isAsSender()?transactionInfo.getToTag():transactionInfo.getFromTag());
        //Forwards
        MaxForwardsHeader maxForwards = sipLayer.getSipFactory().createHeaderFactory().createMaxForwardsHeader(70);
@@ -183,11 +183,6 @@
        CSeqHeader cSeqHeader = sipLayer.getSipFactory().createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(), Request.BYE);
        CallIdHeader callIdHeader = sipLayer.getSipFactory().createHeaderFactory().createCallIdHeader(transactionInfo.getCallId());
        request = sipLayer.getSipFactory().createMessageFactory().createRequest(requestLine, Request.BYE, callIdHeader, cSeqHeader,fromHeader, toHeader, viaHeaders, maxForwards);
        request.addHeader(SipUtils.createUserAgentHeader(sipLayer.getSipFactory(), gitUtil));
        Address concatAddress = sipLayer.getSipFactory().createAddressFactory().createAddress(sipLayer.getSipFactory().createAddressFactory().createSipURI(sipConfig.getId(), sipLayer.getLocalIp(device.getLocalIp())+":"+sipConfig.getPort()));
        request.addHeader(sipLayer.getSipFactory().createHeaderFactory().createContactHeader(concatAddress));
        request.addHeader(SipUtils.createUserAgentHeader(sipLayer.getSipFactory(), gitUtil));
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
@@ -655,7 +655,12 @@
     */
    @Override
    public void streamByeCmd(Device device, String channelId, String stream, String callId, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException, SsrcTransactionNotFoundException {
        SsrcTransaction ssrcTransaction = streamSession.getSsrcTransaction(device.getDeviceId(), channelId, callId, stream);
        SsrcTransaction ssrcTransaction;
        if (callId != null) {
            ssrcTransaction = streamSession.getSsrcTransaction(null, null, callId, null);
        }else {
            ssrcTransaction = streamSession.getSsrcTransaction(device.getDeviceId(), channelId, null, stream);
        }
        if (ssrcTransaction == null) {
            throw new SsrcTransactionNotFoundException(device.getDeviceId(), channelId, callId, stream);
        }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/response/cmd/BroadcastResponseMessageHandler.java
@@ -62,7 +62,12 @@
                return;
            }
            String result = getText(rootElement, "Result");
            logger.info("[语音广播]回复:{}, {}/{}", result, device.getDeviceId(), channelId );
            Element infoElement = rootElement.element("Info");
            String reason = null;
            if (infoElement != null) {
                reason = getText(infoElement, "Reason");
            }
            logger.info("[语音广播]回复:{}, {}/{}", reason == null? result : result + ": " + reason, device.getDeviceId(), channelId );
            // 回复200 OK
            responseAck(request, Response.OK);
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
@@ -344,70 +344,34 @@
                }
            }else if ("broadcast".equals(param.getApp())){
                // 语音对讲推流  stream需要满足格式deviceId_channelId
                if (param.isRegist() && param.getStream().indexOf("_") > 0) {
                if (param.getStream().indexOf("_") > 0) {
                    String[] streamArray = param.getStream().split("_");
                    if (streamArray.length == 2) {
                        String deviceId = streamArray[0];
                        String channelId = streamArray[1];
                        Device device = deviceService.getDevice(deviceId);
                        if (device != null) {
                            DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId);
                            if (deviceChannel != null) {
                            if (param.isRegist()) {
                                if (audioBroadcastManager.exit(deviceId, channelId)) {
                                    // 直接推流
                                    SendRtpItem sendRtpItem =  redisCatchStorage.querySendRTPServer(null, null, param.getStream(), null);
                                    if (sendRtpItem == null) {
                                        // TODO 可能数据错误,重新开启语音通道
                                    }else {
                                        String is_Udp = sendRtpItem.isTcp() ? "0" : "1";
                                        MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
                                        logger.info("rtp/{}开始向上级推流, 目标={}:{},SSRC={}", sendRtpItem.getStreamId(), sendRtpItem.getIp(), sendRtpItem.getPort(), sendRtpItem.getSsrc());
                                        Map<String, Object> sendParam = new HashMap<>(12);
                                        sendParam.put("vhost","__defaultVhost__");
                                        sendParam.put("app",sendRtpItem.getApp());
                                        sendParam.put("stream",sendRtpItem.getStreamId());
                                        sendParam.put("ssrc", sendRtpItem.getSsrc());
                                        sendParam.put("src_port", sendRtpItem.getLocalPort());
                                        sendParam.put("pt", sendRtpItem.getPt());
                                        sendParam.put("use_ps", sendRtpItem.isUsePs() ? "1" : "0");
                                        sendParam.put("only_audio", sendRtpItem.isOnlyAudio() ? "1" : "0");
                                        JSONObject jsonObject;
                                        if (sendRtpItem.isTcpActive()) {
                                            jsonObject = zlmrtpServerFactory.startSendRtpPassive(mediaInfo, sendParam);
                                        } else {
                                            sendParam.put("is_udp", is_Udp);
                                            sendParam.put("dst_url", sendRtpItem.getIp());
                                            sendParam.put("dst_port", sendRtpItem.getPort());
                                            jsonObject = zlmrtpServerFactory.startSendRtpStream(mediaInfo, sendParam);
                                        }
                                        if (jsonObject != null && jsonObject.getInteger("code") == 0) {
                                            logger.info("[语音对讲] 自动推流成功, device: {}, channel: {}", deviceId, channelId);
                                        }else {
                                            logger.info("[语音对讲] 推流失败, 结果: {}", jsonObject);
                                        }
                                    }
                                }else {
                                    // 开启语音对讲通道
                                    try {
                                        playService.audioBroadcastCmd(device, channelId, 60, (msg)->{
                                            logger.info("[语音对讲] 通道建立成功, device: {}, channel: {}", deviceId, channelId);
                                        });
                                    } catch (InvalidArgumentException | ParseException | SipException e) {
                                        logger.error("[命令发送失败] 语音对讲: {}", e.getMessage());
                                    }
                                    playService.stopAudioBroadcast(deviceId, channelId);
                                }
                                // 开启语音对讲通道
                                try {
                                    playService.audioBroadcastCmd(device, channelId, 60, (msg)->{
                                        logger.info("[语音对讲] 通道建立成功, device: {}, channel: {}", deviceId, channelId);
                                    });
                                } catch (InvalidArgumentException | ParseException | SipException e) {
                                    logger.error("[命令发送失败] 语音对讲: {}", e.getMessage());
                                }
                            }else {
                                logger.info("[语音对讲] 未找到通道:{}", channelId);
                                // 流注销
                                playService.stopAudioBroadcast(deviceId, channelId);
                            }
                        }else{
                        } else{
                            logger.info("[语音对讲] 未找到设备:{}", deviceId);
                        }
                    }
                }
            }else if ("talk".equals(param.getApp())){
                // 语音对讲推流  stream需要满足格式deviceId_channelId
                if (param.isRegist() && param.getStream().indexOf("_") > 0) {
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
@@ -1085,6 +1085,12 @@
                    param.put("app", sendRtpItem.getApp());
                    param.put("stream", sendRtpItem.getStreamId());
                    zlmresTfulUtils.stopSendRtp(mediaInfo, param);
                    try {
                        cmder.streamByeCmd(device, sendRtpItem.getChannelId(), audioBroadcastCatch.getSipTransactionInfo(), null);
                    } catch (InvalidArgumentException | ParseException | SipException |
                             SsrcTransactionNotFoundException e) {
                        logger.error("[消息发送失败] 发送语音喊话BYE失败");
                    }
                }
                audioBroadcastManager.del(deviceId, channelId);