From b4048fbe80dba8e7756ae557a15ab60b4f80a44b Mon Sep 17 00:00:00 2001 From: 648540858 <648540858@qq.com> Date: 星期二, 04 四月 2023 09:09:07 +0800 Subject: [PATCH] 合并开源主线 --- src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java | 138 +++++++++++++++++++++++++++++++++++---------- 1 files changed, 107 insertions(+), 31 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 d071118..4d8ed27 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 @@ -41,7 +41,7 @@ import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; import com.genersoft.iot.vmp.vmanager.bean.StreamContent; import com.genersoft.iot.vmp.vmanager.bean.WVPResult; -import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.AudioEvent; +import com.genersoft.iot.vmp.vmanager.gb28181.play.bean.AudioBroadcastEvent; import gov.nist.javax.sip.message.SIPResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -245,7 +245,7 @@ private void talk(MediaServerItem mediaServerItem, Device device, String channelId, String stream, ZlmHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent, - Runnable timeoutCallback, AudioEvent audioEvent) { + Runnable timeoutCallback, AudioBroadcastEvent audioEvent) { String playSsrc = mediaServerItem.getSsrcConfig().getPlaySsrc(); if (playSsrc == null) { @@ -438,7 +438,12 @@ onPublishHandlerForPlay(mediaServerItemInuse, response, device.getDeviceId(), channelId); hookEvent.response(mediaServerItemInuse, response); logger.info("[鐐规挱鎴愬姛] deviceId: {}, channelId: {}", device.getDeviceId(), channelId); - String streamUrl = String.format("http://127.0.0.1:%s/%s/%s.live.flv", mediaServerItemInuse.getHttpPort(), "rtp", ssrcInfo.getStream()); + String streamUrl; + if (mediaServerItemInuse.getRtspPort() != 0) { + streamUrl = String.format("rtsp://127.0.0.1:%s/%s/%s", mediaServerItemInuse.getRtspPort(), "rtp", ssrcInfo.getStream()); + }else { + streamUrl = String.format("http://127.0.0.1:%s/%s/%s.live.mp4", mediaServerItemInuse.getHttpPort(), "rtp", ssrcInfo.getStream()); + } String path = "snap"; String fileName = device.getDeviceId() + "_" + channelId + ".jpg"; // 璇锋眰鎴浘 @@ -453,7 +458,7 @@ // 妫�鏌ユ槸鍚︽湁y瀛楁 if (ssrcIndex >= 0) { //ssrc瑙勫畾闀垮害涓�10瀛楄妭锛屼笉鍙栦綑涓嬮暱搴︿互閬垮厤鍚庣画杩樻湁鈥渇=鈥濆瓧娈� TODO 鍚庣画瀵逛笉瑙勮寖鐨勯潪10浣峴src鍏煎 - String ssrcInResponse = contentString.substring(ssrcIndex + 2, ssrcIndex + 12); + String ssrcInResponse = contentString.substring(ssrcIndex + 2, ssrcIndex + 12).trim(); // 鏌ヨ鍒皊src涓嶄竴鑷翠笖寮�鍚簡ssrc鏍¢獙鍒欓渶瑕侀拡瀵瑰鐞� if (ssrcInfo.getSsrc().equals(ssrcInResponse)) { return; @@ -490,7 +495,7 @@ // 鍏抽棴rtp server mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream()); // 閲嶆柊寮�鍚痵src server - mediaServerService.openRTPServer(mediaServerItem, ssrcInfo.getStream(), ssrcInResponse, device.isSsrcCheck(), false, ssrcInfo.getPort()); + mediaServerService.openRTPServer(mediaServerItem, ssrcInfo.getStream(), ssrcInResponse, device.isSsrcCheck(), false, ssrcInfo.getPort(), false); } } @@ -731,7 +736,7 @@ // 鍏抽棴rtp server mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream()); // 閲嶆柊寮�鍚痵src server - mediaServerService.openRTPServer(mediaServerItem, ssrcInfo.getStream(), ssrcInResponse, device.isSsrcCheck(), true, ssrcInfo.getPort()); + mediaServerService.openRTPServer(mediaServerItem, ssrcInfo.getStream(), ssrcInResponse, device.isSsrcCheck(), true, ssrcInfo.getPort(), false); } } } @@ -806,23 +811,75 @@ hookCallBack.call(downloadResult); streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream()); }; - + InviteStreamCallback hookEvent = (InviteStreamInfo inviteStreamInfo) -> { + logger.info("鏀跺埌璁㈤槄娑堟伅锛� " + inviteStreamInfo.getCallId()); + dynamicTask.stop(downLoadTimeOutTaskKey); + StreamInfo streamInfo = onPublishHandler(inviteStreamInfo.getMediaServerItem(), inviteStreamInfo.getResponse(), deviceId, channelId); + streamInfo.setStartTime(startTime); + streamInfo.setEndTime(endTime); + redisCatchStorage.startDownload(streamInfo, inviteStreamInfo.getCallId()); + downloadResult.setCode(ErrorCode.SUCCESS.getCode()); + downloadResult.setMsg(ErrorCode.SUCCESS.getMsg()); + downloadResult.setData(streamInfo); + downloadResult.setMediaServerItem(inviteStreamInfo.getMediaServerItem()); + downloadResult.setResponse(inviteStreamInfo.getResponse()); + hookCallBack.call(downloadResult); + }; try { cmder.downloadStreamCmd(mediaServerItem, ssrcInfo, device, channelId, startTime, endTime, downloadSpeed, infoCallBack, - inviteStreamInfo -> { - logger.info("鏀跺埌璁㈤槄娑堟伅锛� " + inviteStreamInfo.getResponse().toJSONString()); - dynamicTask.stop(downLoadTimeOutTaskKey); - StreamInfo streamInfo = onPublishHandler(inviteStreamInfo.getMediaServerItem(), inviteStreamInfo.getResponse(), deviceId, channelId); - streamInfo.setStartTime(startTime); - streamInfo.setEndTime(endTime); - redisCatchStorage.startDownload(streamInfo, inviteStreamInfo.getCallId()); - downloadResult.setCode(ErrorCode.SUCCESS.getCode()); - downloadResult.setMsg(ErrorCode.SUCCESS.getMsg()); - downloadResult.setData(streamInfo); - downloadResult.setMediaServerItem(inviteStreamInfo.getMediaServerItem()); - downloadResult.setResponse(inviteStreamInfo.getResponse()); - hookCallBack.call(downloadResult); - }, errorEvent); + hookEvent, errorEvent, eventResult -> + { + if (eventResult.type == SipSubscribe.EventResultType.response) { + ResponseEvent responseEvent = (ResponseEvent) eventResult.event; + String contentString = new String(responseEvent.getResponse().getRawContent()); + // 鑾峰彇ssrc + int ssrcIndex = contentString.indexOf("y="); + // 妫�鏌ユ槸鍚︽湁y瀛楁 + if (ssrcIndex >= 0) { + //ssrc瑙勫畾闀垮害涓�10瀛楄妭锛屼笉鍙栦綑涓嬮暱搴︿互閬垮厤鍚庣画杩樻湁鈥渇=鈥濆瓧娈� TODO 鍚庣画瀵逛笉瑙勮寖鐨勯潪10浣峴src鍏煎 + String ssrcInResponse = contentString.substring(ssrcIndex + 2, ssrcIndex + 12); + // 鏌ヨ鍒皊src涓嶄竴鑷翠笖寮�鍚簡ssrc鏍¢獙鍒欓渶瑕侀拡瀵瑰鐞� + if (ssrcInfo.getSsrc().equals(ssrcInResponse)) { + return; + } + logger.info("[鍥炴斁娑堟伅] 鏀跺埌invite 200, 鍙戠幇涓嬬骇鑷畾涔変簡ssrc: {}", ssrcInResponse); + if (!mediaServerItem.isRtpEnable() || device.isSsrcCheck()) { + logger.info("[鍥炴斁娑堟伅] SSRC淇 {}->{}", ssrcInfo.getSsrc(), ssrcInResponse); + + if (!mediaServerItem.getSsrcConfig().checkSsrc(ssrcInResponse)) { + // ssrc 涓嶅彲鐢� + // 閲婃斁ssrc + mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc()); + streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream()); + eventResult.msg = "涓嬬骇鑷畾涔変簡ssrc,浣嗘槸姝src涓嶅彲鐢�"; + eventResult.statusCode = 400; + errorEvent.response(eventResult); + return; + } + + // 鍗曠鍙fā寮弒treamId涔熸湁鍙樺寲锛岄渶瑕侀噸鏂拌缃洃鍚� + if (!mediaServerItem.isRtpEnable()) { + // 娣诲姞璁㈤槄 + HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", ssrcInfo.getStream(), true, "rtsp", mediaServerItem.getId()); + subscribe.removeSubscribe(hookSubscribe); + hookSubscribe.getContent().put("stream", String.format("%08x", Integer.parseInt(ssrcInResponse)).toUpperCase()); + subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, JSONObject response) -> { + logger.info("[ZLM HOOK] ssrc淇鍚庢敹鍒拌闃呮秷鎭細 " + response.toJSONString()); + dynamicTask.stop(downLoadTimeOutTaskKey); + // hook鍝嶅簲 + onPublishHandlerForPlayback(mediaServerItemInUse, response, device.getDeviceId(), channelId, hookCallBack); + hookEvent.call(new InviteStreamInfo(mediaServerItem, null, eventResult.callId, "rtp", ssrcInfo.getStream())); + }); + } + // 鍏抽棴rtp server + mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream()); + // 閲嶆柊寮�鍚痵src server + mediaServerService.openRTPServer(mediaServerItem, ssrcInfo.getStream(), ssrcInResponse, device.isSsrcCheck(), true, ssrcInfo.getPort()); + } + } + } + + }); } catch (InvalidArgumentException | SipException | ParseException e) { logger.error("[鍛戒护鍙戦�佸け璐 褰曞儚涓嬭浇: {}", e.getMessage()); @@ -966,28 +1023,27 @@ } @Override - public void audioBroadcastCmd(Device device, String channelId, MediaServerItem mediaServerItem, int timeout, AudioEvent event) throws InvalidArgumentException, ParseException, SipException { + public boolean audioBroadcastCmd(Device device, String channelId, MediaServerItem mediaServerItem, String app, String stream, int timeout, boolean isFromPlatform, AudioBroadcastEvent event) throws InvalidArgumentException, ParseException, SipException { if (device == null || channelId == null) { - return; + return false; } logger.info("[璇煶鍠婅瘽] device锛� {}, channel: {}", device.getDeviceId(), channelId); DeviceChannel deviceChannel = storager.queryChannel(device.getDeviceId(), channelId); if (deviceChannel == null) { logger.warn("寮�鍚闊冲箍鎾殑鏃跺�欐湭鎵惧埌閫氶亾锛� {}", channelId); event.call("寮�鍚闊冲箍鎾殑鏃跺�欐湭鎵惧埌閫氶亾"); - return; + return false; } // 鏌ヨ閫氶亾浣跨敤鐘舵�� if (audioBroadcastManager.exit(device.getDeviceId(), channelId)) { SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(device.getDeviceId(), channelId, null, null); if (sendRtpItem != null && sendRtpItem.isOnlyAudio()) { // 鏌ヨ娴佹槸鍚﹀瓨鍦紝涓嶅瓨鍦ㄥ垯璁や负鏄紓甯哥姸鎬� - MediaServerItem mediaServer = mediaServerService.getOne(sendRtpItem.getMediaServerId()); - Boolean streamReady = zlmrtpServerFactory.isStreamReady(mediaServer, sendRtpItem.getApp(), sendRtpItem.getStream()); + Boolean streamReady = zlmrtpServerFactory.isStreamReady(mediaServerItem, sendRtpItem.getApp(), sendRtpItem.getStream()); if (streamReady) { logger.warn("璇煶骞挎挱宸茬粡寮�鍚細 {}", channelId); event.call("璇煶骞挎挱宸茬粡寮�鍚�"); - return; + return false; } else { stopAudioBroadcast(device.getDeviceId(), channelId); } @@ -1000,7 +1056,7 @@ if (streamReady) { logger.warn("[璇煶瀵硅] 杩涜涓細 {}", channelId); event.call("璇煶瀵硅杩涜涓�"); - return; + return false; } else { stopTalk(device, channelId); } @@ -1009,7 +1065,7 @@ // 鍙戦�侀�氱煡 cmder.audioBroadcastCmd(device, channelId, eventResultForOk -> { // 鍙戦�佹垚鍔� - AudioBroadcastCatch audioBroadcastCatch = new AudioBroadcastCatch(device.getDeviceId(), channelId, AudioBroadcastCatchStatus.Ready, mediaServerItem); + AudioBroadcastCatch audioBroadcastCatch = new AudioBroadcastCatch(device.getDeviceId(), channelId, mediaServerItem, app, stream, event, AudioBroadcastCatchStatus.Ready, isFromPlatform); audioBroadcastManager.update(audioBroadcastCatch); }, eventResultForError -> { // 鍙戦�佸け璐� @@ -1017,11 +1073,30 @@ event.call("璇煶骞挎挱鍙戦�佸け璐�"); stopAudioBroadcast(device.getDeviceId(), channelId); }); + return true; + } + + @Override + public boolean audioBroadcastInUse(Device device, String channelId) { + if (audioBroadcastManager.exit(device.getDeviceId(), channelId)) { + SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(device.getDeviceId(), channelId, null, null); + if (sendRtpItem != null && sendRtpItem.isOnlyAudio()) { + // 鏌ヨ娴佹槸鍚﹀瓨鍦紝涓嶅瓨鍦ㄥ垯璁や负鏄紓甯哥姸鎬� + MediaServerItem mediaServerServiceOne = mediaServerService.getOne(sendRtpItem.getMediaServerId()); + Boolean streamReady = zlmrtpServerFactory.isStreamReady(mediaServerServiceOne, sendRtpItem.getApp(), sendRtpItem.getStream()); + if (streamReady) { + logger.warn("璇煶骞挎挱閫氶亾浣跨敤涓細 {}", channelId); + return true; + } + } + } + return false; } @Override public void stopAudioBroadcast(String deviceId, String channelId) { + logger.info("[鍋滄瀵硅] 璁惧锛歿}, 閫氶亾锛歿}", deviceId, channelId); List<AudioBroadcastCatch> audioBroadcastCatchList = new ArrayList<>(); if (channelId == null) { audioBroadcastCatchList.addAll(audioBroadcastManager.get(deviceId)); @@ -1055,6 +1130,7 @@ } } } + @Override public void zlmServerOnline(String mediaServerId) { @@ -1165,7 +1241,7 @@ String is_Udp = sendRtpItem.isTcp() ? "0" : "1"; MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); - logger.info("鏀跺埌ACK锛宺tp/{}寮�濮嬪悜涓婄骇鎺ㄦ祦, 鐩爣={}:{}锛孲SRC={}, RTCP={}", sendRtpItem.getStream(), + logger.info("鏀跺埌ACK锛宺tp/{}寮�濮嬫帹娴�, 鐩爣={}:{}锛孲SRC={}, RTCP={}", sendRtpItem.getStream(), sendRtpItem.getIp(), sendRtpItem.getPort(), sendRtpItem.getSsrc(), sendRtpItem.isRtcp()); Map<String, Object> param = new HashMap<>(12); param.put("vhost", "__defaultVhost__"); @@ -1253,7 +1329,7 @@ } @Override - public void talkCmd(Device device, String channelId, MediaServerItem mediaServerItem, String stream, AudioEvent event) { + public void talkCmd(Device device, String channelId, MediaServerItem mediaServerItem, String stream, AudioBroadcastEvent event) { if (device == null || channelId == null) { return; } -- Gitblit v1.8.0