From b6e604f2449bb65dfaafb0f0741ba54ff0d2f9c2 Mon Sep 17 00:00:00 2001
From: 648540858 <648540858@qq.com>
Date: 星期二, 30 四月 2024 15:20:03 +0800
Subject: [PATCH] 修改云端录像详情页使用直接访问zlm的方式播放录像
---
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java | 929 +++++++++++++++++++++++++++++++++++++++++++++++----------
1 files changed, 758 insertions(+), 171 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 9012c29..7cf0398 100755
--- a/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
+++ b/src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
@@ -1,11 +1,7 @@
package com.genersoft.iot.vmp.service.impl;
-import com.alibaba.fastjson2.JSONArray;
-import com.alibaba.fastjson2.JSONObject;
-import com.genersoft.iot.vmp.common.InviteInfo;
-import com.genersoft.iot.vmp.common.InviteSessionStatus;
-import com.genersoft.iot.vmp.common.InviteSessionType;
-import com.genersoft.iot.vmp.common.StreamInfo;
+import com.baomidou.dynamic.datasource.annotation.DS;
+import com.genersoft.iot.vmp.common.*;
import com.genersoft.iot.vmp.conf.DynamicTask;
import com.genersoft.iot.vmp.conf.UserSetting;
import com.genersoft.iot.vmp.conf.exception.ControllerException;
@@ -13,29 +9,39 @@
import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException;
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.SSRCFactory;
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
-import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
-import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
+import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
+import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
-import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
-import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory;
-import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
-import com.genersoft.iot.vmp.media.zlm.dto.*;
-import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam;
-import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRecordMp4HookParam;
-import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
+import com.genersoft.iot.vmp.media.bean.MediaInfo;
+import com.genersoft.iot.vmp.media.bean.RecordInfo;
+import com.genersoft.iot.vmp.media.event.hook.Hook;
+import com.genersoft.iot.vmp.media.event.hook.HookType;
+import com.genersoft.iot.vmp.media.event.media.MediaArrivalEvent;
+import com.genersoft.iot.vmp.media.event.media.MediaDepartureEvent;
+import com.genersoft.iot.vmp.media.event.media.MediaNotFoundEvent;
+import com.genersoft.iot.vmp.media.service.IMediaServerService;
+import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager;
+import com.genersoft.iot.vmp.media.event.hook.HookSubscribe;
+import com.genersoft.iot.vmp.media.bean.MediaServer;
import com.genersoft.iot.vmp.service.*;
import com.genersoft.iot.vmp.service.bean.*;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
-import com.genersoft.iot.vmp.storager.dao.CloudRecordServiceMapper;
import com.genersoft.iot.vmp.utils.CloudRecordUtils;
import com.genersoft.iot.vmp.utils.DateUtil;
+import com.genersoft.iot.vmp.vmanager.bean.AudioBroadcastResult;
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
+import com.genersoft.iot.vmp.vmanager.bean.StreamContent;
+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;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.event.EventListener;
+import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
@@ -43,16 +49,16 @@
import javax.sip.InvalidArgumentException;
import javax.sip.ResponseEvent;
import javax.sip.SipException;
+import javax.sip.header.CallIdHeader;
import java.io.File;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
-import java.util.List;
-import java.util.UUID;
-import java.util.Vector;
+import java.util.*;
@SuppressWarnings(value = {"rawtypes", "unchecked"})
@Service
+@DS("master")
public class PlayServiceImpl implements IPlayService {
private final static Logger logger = LoggerFactory.getLogger(PlayServiceImpl.class);
@@ -61,10 +67,16 @@
private IVideoManagerStorage storager;
@Autowired
- private SIPCommander cmder;
+ private ISIPCommander cmder;
@Autowired
- private SIPCommanderFroPlatform sipCommanderFroPlatform;
+ private AudioBroadcastManager audioBroadcastManager;
+
+ @Autowired
+ private IDeviceService deviceService;
+
+ @Autowired
+ private ISIPCommanderForPlatform sipCommanderFroPlatform;
@Autowired
private IRedisCatchStorage redisCatchStorage;
@@ -73,16 +85,10 @@
private IInviteStreamService inviteStreamService;
@Autowired
- private ZlmHttpHookSubscribe subscribe;
+ private HookSubscribe subscribe;
@Autowired
- private ZLMRESTfulUtils zlmresTfulUtils;
-
- @Autowired
- private ZLMServerFactory zlmServerFactory;
-
- @Autowired
- private IMediaService mediaService;
+ private SendRtpPortManager sendRtpPortManager;
@Autowired
private IMediaServerService mediaServerService;
@@ -91,33 +97,186 @@
private VideoStreamSessionManager streamSession;
@Autowired
- private IDeviceService deviceService;
+ private UserSetting userSetting;
@Autowired
- private UserSetting userSetting;
+ private IDeviceChannelService channelService;
@Autowired
private DynamicTask dynamicTask;
@Autowired
- private CloudRecordServiceMapper cloudRecordServiceMapper;
+ private ISIPCommanderForPlatform commanderForPlatform;
+
+ @Autowired
+ private SSRCFactory ssrcFactory;
+
+ /**
+ * 娴佸埌鏉ョ殑澶勭悊
+ */
+ @Async("taskExecutor")
+ @org.springframework.context.event.EventListener
+ public void onApplicationEvent(MediaArrivalEvent event) {
+ if ("broadcast".equals(event.getApp())) {
+ if (event.getStream().indexOf("_") > 0) {
+ String[] streamArray = event.getStream().split("_");
+ if (streamArray.length == 2) {
+ String deviceId = streamArray[0];
+ String channelId = streamArray[1];
+ Device device = deviceService.getDevice(deviceId);
+ if (device == null) {
+ logger.info("[璇煶瀵硅/鍠婅瘽] 鏈壘鍒拌澶囷細{}", deviceId);
+ return;
+ }
+ if ("broadcast".equals(event.getApp())) {
+ if (audioBroadcastManager.exit(deviceId, channelId)) {
+ stopAudioBroadcast(deviceId, channelId);
+ }
+ // 寮�鍚闊冲璁查�氶亾
+ try {
+ audioBroadcastCmd(device, channelId, event.getMediaServer(),
+ event.getApp(), event.getStream(), 60, false, (msg) -> {
+ logger.info("[璇煶瀵硅] 閫氶亾寤虹珛鎴愬姛, device: {}, channel: {}", deviceId, channelId);
+ });
+ } catch (InvalidArgumentException | ParseException | SipException e) {
+ logger.error("[鍛戒护鍙戦�佸け璐 璇煶瀵硅: {}", e.getMessage());
+ }
+ }else if ("talk".equals(event.getApp())) {
+ // 寮�鍚闊冲璁查�氶亾
+ talkCmd(device, channelId, event.getMediaServer(), event.getStream(), (msg) -> {
+ logger.info("[璇煶瀵硅] 閫氶亾寤虹珛鎴愬姛, device: {}, channel: {}", deviceId, channelId);
+ });
+ }
+ }
+ }
+ }
+
+
+ }
+
+ /**
+ * 娴佺寮�鐨勫鐞�
+ */
+ @Async("taskExecutor")
+ @EventListener
+ public void onApplicationEvent(MediaDepartureEvent event) {
+ List<SendRtpItem> sendRtpItems = redisCatchStorage.querySendRTPServerByStream(event.getStream());
+ if (!sendRtpItems.isEmpty()) {
+ for (SendRtpItem sendRtpItem : sendRtpItems) {
+ if (sendRtpItem != null && sendRtpItem.getApp().equals(event.getApp())) {
+ String platformId = sendRtpItem.getPlatformId();
+ Device device = deviceService.getDevice(platformId);
+ try {
+ if (device != null) {
+ cmder.streamByeCmd(device, sendRtpItem.getChannelId(), event.getStream(), sendRtpItem.getCallId());
+ if (sendRtpItem.getPlayType().equals(InviteStreamType.BROADCAST)
+ || sendRtpItem.getPlayType().equals(InviteStreamType.TALK)) {
+ AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId());
+ if (audioBroadcastCatch != null) {
+ // 鏉ヨ嚜涓婄骇骞冲彴鐨勫仠姝㈠璁�
+ logger.info("[鍋滄瀵硅] 鏉ヨ嚜涓婄骇锛屽钩鍙帮細{}, 閫氶亾锛歿}", sendRtpItem.getDeviceId(), sendRtpItem.getChannelId());
+ audioBroadcastManager.del(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId());
+ }
+ }
+ }
+ } catch (SipException | InvalidArgumentException | ParseException |
+ SsrcTransactionNotFoundException e) {
+ logger.error("[鍛戒护鍙戦�佸け璐 鍙戦�丅YE: {}", e.getMessage());
+ }
+ }
+ }
+ }
+
+ if ("broadcast".equals(event.getApp()) || "talk".equals(event.getApp())) {
+ if (event.getStream().indexOf("_") > 0) {
+ String[] streamArray = event.getStream().split("_");
+ if (streamArray.length == 2) {
+ String deviceId = streamArray[0];
+ String channelId = streamArray[1];
+ Device device = deviceService.getDevice(deviceId);
+ if (device == null) {
+ logger.info("[璇煶瀵硅/鍠婅瘽] 鏈壘鍒拌澶囷細{}", deviceId);
+ return;
+ }
+ if ("broadcast".equals(event.getApp())) {
+ stopAudioBroadcast(deviceId, channelId);
+ }else if ("talk".equals(event.getApp())) {
+ stopTalk(device, channelId, false);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * 娴佹湭鎵惧埌鐨勫鐞�
+ */
+ @Async("taskExecutor")
+ @EventListener
+ public void onApplicationEvent(MediaNotFoundEvent event) {
+ if (!"rtp".equals(event.getApp())) {
+ return;
+ }
+ String[] s = event.getStream().split("_");
+ if ((s.length != 2 && s.length != 4)) {
+ return;
+ }
+ String deviceId = s[0];
+ String channelId = s[1];
+ Device device = redisCatchStorage.getDevice(deviceId);
+ if (device == null || !device.isOnLine()) {
+ return;
+ }
+ DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId);
+ if (deviceChannel == null) {
+ return;
+ }
+ if (s.length == 2) {
+ logger.info("[ZLM HOOK] 棰勮娴佹湭鎵惧埌, 鍙戣捣鑷姩鐐规挱锛歿}->{}->{}/{}", event.getMediaServer().getId(), event.getSchema(), event.getApp(), event.getStream());
+ play(event.getMediaServer(), deviceId, channelId, null, null);
+ } else if (s.length == 4) {
+ // 姝ゆ椂涓哄綍鍍忓洖鏀撅紝 褰曞儚鍥炴斁鏍煎紡涓�> 璁惧ID_閫氶亾ID_寮�濮嬫椂闂確缁撴潫鏃堕棿
+ String startTimeStr = s[2];
+ String endTimeStr = s[3];
+ if (startTimeStr == null || endTimeStr == null || startTimeStr.length() != 14 || endTimeStr.length() != 14) {
+ return;
+ }
+ String startTime = DateUtil.urlToyyyy_MM_dd_HH_mm_ss(startTimeStr);
+ String endTime = DateUtil.urlToyyyy_MM_dd_HH_mm_ss(endTimeStr);
+ logger.info("[ZLM HOOK] 鍥炴斁娴佹湭鎵惧埌, 鍙戣捣鑷姩鐐规挱锛歿}->{}->{}/{}-{}-{}",
+ event.getMediaServer().getId(), event.getSchema(),
+ event.getApp(), event.getStream(),
+ startTime, endTime
+ );
+
+ SSRCInfo ssrcInfo = mediaServerService.openRTPServer(event.getMediaServer(), event.getStream(), null,
+ device.isSsrcCheck(), true, 0, false, !deviceChannel.getHasAudio(), false, device.getStreamModeForParam());
+ playBack(event.getMediaServer(), ssrcInfo, deviceId, channelId, startTime, endTime, null);
+ }
+ }
@Override
- public SSRCInfo play(MediaServerItem mediaServerItem, String deviceId, String channelId, String ssrc, ErrorCallback<Object> callback) {
+ public SSRCInfo play(MediaServer mediaServerItem, String deviceId, String channelId, String ssrc, ErrorCallback<Object> callback) {
if (mediaServerItem == null) {
logger.warn("[鐐规挱] 鏈壘鍒板彲鐢ㄧ殑zlm deviceId: {},channelId:{}", deviceId, channelId);
throw new ControllerException(ErrorCode.ERROR100.getCode(), "鏈壘鍒板彲鐢ㄧ殑zlm");
}
-
Device device = redisCatchStorage.getDevice(deviceId);
if (device.getStreamMode().equalsIgnoreCase("TCP-ACTIVE") && !mediaServerItem.isRtpEnable()) {
logger.warn("[鐐规挱] 鍗曠鍙f敹娴佹椂涓嶆敮鎸乀CP涓诲姩鏂瑰紡鏀舵祦 deviceId: {},channelId:{}", deviceId, channelId);
throw new ControllerException(ErrorCode.ERROR100.getCode(), "鍗曠鍙f敹娴佹椂涓嶆敮鎸乀CP涓诲姩鏂瑰紡鏀舵祦");
}
+ DeviceChannel channel = channelService.getOne(deviceId, channelId);
+ if (channel == null) {
+ logger.warn("[鐐规挱] 鏈壘鍒伴�氶亾 deviceId: {},channelId:{}", deviceId, channelId);
+ throw new ControllerException(ErrorCode.ERROR100.getCode(), "鏈壘鍒伴�氶亾");
+ }
InviteInfo inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId);
if (inviteInfo != null ) {
if (inviteInfo.getStreamInfo() == null) {
+ // 閲婃斁鐢熸垚鐨剆src锛屼娇鐢ㄤ笂涓�娆$敵璇风殑
+ ssrcFactory.releaseSsrc(mediaServerItem.getId(), ssrc);
// 鐐规挱鍙戣捣浜嗕絾鏄皻鏈垚鍔�, 浠呮敞鍐屽洖璋冪瓑寰呯粨鏋滃嵆鍙�
inviteStreamService.once(InviteSessionType.PLAY, deviceId, channelId, null, callback);
logger.info("[鐐规挱寮�濮媇 宸茬粡璇锋眰涓紝绛夊緟缁撴灉锛� deviceId: {}, channelId: {}", device.getDeviceId(), channelId);
@@ -134,9 +293,8 @@
return inviteInfo.getSsrcInfo();
}
String mediaServerId = streamInfo.getMediaServerId();
- MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
-
- Boolean ready = zlmServerFactory.isStreamReady(mediaInfo, "rtp", streamId);
+ MediaServer mediaInfo = mediaServerService.getOne(mediaServerId);
+ Boolean ready = mediaServerService.isStreamReady(mediaInfo, "rtp", streamId);
if (ready != null && ready) {
callback.run(InviteErrorCode.SUCCESS.getCode(), InviteErrorCode.SUCCESS.getMsg(), streamInfo);
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
@@ -153,8 +311,8 @@
}
}
}
- String streamId = String.format("%s_%s", device.getDeviceId(), channelId);;
- SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, ssrc, device.isSsrcCheck(), false, 0, false, device.getStreamModeForParam());
+ String streamId = String.format("%s_%s", device.getDeviceId(), channelId);
+ SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, ssrc, device.isSsrcCheck(), false, 0, false, !channel.getHasAudio(), false, device.getStreamModeForParam());
if (ssrcInfo == null) {
callback.run(InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(), InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getMsg(), null);
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
@@ -163,13 +321,141 @@
null);
return null;
}
- play(mediaServerItem, ssrcInfo, device, channelId, callback);
+ play(mediaServerItem, ssrcInfo, device, channel, callback);
return ssrcInfo;
}
+ private void talk(MediaServer mediaServerItem, Device device, String channelId, String stream,
+ HookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent,
+ Runnable timeoutCallback, AudioBroadcastEvent audioEvent) {
+
+ String playSsrc = ssrcFactory.getPlaySsrc(mediaServerItem.getId());
+
+ if (playSsrc == null) {
+ audioEvent.call("ssrc宸茬粡鐢ㄥ敖");
+ return;
+ }
+ SendRtpItem sendRtpItem = new SendRtpItem();
+ sendRtpItem.setApp("talk");
+ sendRtpItem.setStream(stream);
+ sendRtpItem.setSsrc(playSsrc);
+ sendRtpItem.setDeviceId(device.getDeviceId());
+ sendRtpItem.setPlatformId(device.getDeviceId());
+ sendRtpItem.setChannelId(channelId);
+ sendRtpItem.setRtcp(false);
+ sendRtpItem.setMediaServerId(mediaServerItem.getId());
+ sendRtpItem.setOnlyAudio(true);
+ sendRtpItem.setPlayType(InviteStreamType.TALK);
+ sendRtpItem.setPt(8);
+ sendRtpItem.setStatus(1);
+ sendRtpItem.setTcpActive(false);
+ sendRtpItem.setTcp(true);
+ sendRtpItem.setUsePs(false);
+ sendRtpItem.setReceiveStream(stream + "_talk");
+
+ String callId = SipUtils.getNewCallId();
+ int port = sendRtpPortManager.getNextPort(mediaServerItem);
+ //绔彛鑾峰彇澶辫触鐨剆srcInfo 娌℃湁蹇呰鍙戦�佺偣鎾寚浠�
+ if (port <= 0) {
+ logger.info("[璇煶瀵硅] 绔彛鍒嗛厤寮傚父锛宒eviceId={},channelId={}", device.getDeviceId(), channelId);
+ audioEvent.call("绔彛鍒嗛厤寮傚父");
+ return;
+ }
+ sendRtpItem.setLocalPort(port);
+ sendRtpItem.setPort(port);
+ logger.info("[璇煶瀵硅]寮�濮� deviceId: {}, channelId: {},鏀舵祦绔彛锛� {}, 鏀舵祦妯″紡锛歿}, SSRC: {}, SSRC鏍¢獙锛歿}", device.getDeviceId(), channelId, sendRtpItem.getLocalPort(), device.getStreamMode(), sendRtpItem.getSsrc(), false);
+ // 瓒呮椂澶勭悊
+ String timeOutTaskKey = UUID.randomUUID().toString();
+ dynamicTask.startDelay(timeOutTaskKey, () -> {
+
+ logger.info("[璇煶瀵硅] 鏀舵祦瓒呮椂 deviceId: {}, channelId: {}锛岀鍙o細{}, SSRC: {}", device.getDeviceId(), channelId, sendRtpItem.getPort(), sendRtpItem.getSsrc());
+ timeoutCallback.run();
+ // 鐐规挱瓒呮椂鍥炲BYE 鍚屾椂閲婃斁ssrc浠ュ強姝ゆ鐐规挱鐨勮祫婧�
+ try {
+ cmder.streamByeCmd(device, channelId, sendRtpItem.getStream(), null);
+ } catch (InvalidArgumentException | ParseException | SipException | SsrcTransactionNotFoundException e) {
+ logger.error("[璇煶瀵硅]瓒呮椂锛� 鍙戦�丅YE澶辫触 {}", e.getMessage());
+ } finally {
+ timeoutCallback.run();
+ mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpItem.getSsrc());
+ streamSession.remove(device.getDeviceId(), channelId, sendRtpItem.getStream());
+ }
+ }, userSetting.getPlayTimeout());
+
+ try {
+ mediaServerService.startSendRtpPassive(mediaServerItem, null, sendRtpItem, userSetting.getPlayTimeout() * 1000);
+ }catch (ControllerException e) {
+ mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpItem.getSsrc());
+ logger.info("[璇煶瀵硅]澶辫触 deviceId: {}, channelId: {}", device.getDeviceId(), channelId);
+ audioEvent.call("澶辫触, " + e.getMessage());
+ // 鏌ョ湅鏄惁宸茬粡寤虹珛浜嗛�氶亾锛屽瓨鍦ㄥ垯鍙戦�乥ye
+ stopTalk(device, channelId);
+ }
+
+
+ // 鏌ョ湅璁惧鏄惁宸茬粡鍦ㄦ帹娴�
+ try {
+ cmder.talkStreamCmd(mediaServerItem, sendRtpItem, device, channelId, callId, (hookData) -> {
+ logger.info("[璇煶瀵硅] 娴佸凡鐢熸垚锛� 寮�濮嬫帹娴侊細 " + hookData);
+ dynamicTask.stop(timeOutTaskKey);
+ // TODO 鏆備笉鍋氬鐞�
+ }, (hookData) -> {
+ logger.info("[璇煶瀵硅] 璁惧寮�濮嬫帹娴侊細 " + hookData);
+ dynamicTask.stop(timeOutTaskKey);
+
+ }, (event) -> {
+ dynamicTask.stop(timeOutTaskKey);
+
+ if (event.event instanceof ResponseEvent) {
+ ResponseEvent responseEvent = (ResponseEvent) event.event;
+ if (responseEvent.getResponse() instanceof SIPResponse) {
+ SIPResponse response = (SIPResponse) responseEvent.getResponse();
+ sendRtpItem.setFromTag(response.getFromTag());
+ sendRtpItem.setToTag(response.getToTag());
+ sendRtpItem.setCallId(response.getCallIdHeader().getCallId());
+ redisCatchStorage.updateSendRTPSever(sendRtpItem);
+
+ streamSession.put(device.getDeviceId(), channelId, "talk",
+ sendRtpItem.getStream(), sendRtpItem.getSsrc(), sendRtpItem.getMediaServerId(),
+ response, InviteSessionType.TALK);
+ } else {
+ logger.error("[璇煶瀵硅]鏀跺埌鐨勬秷鎭敊璇紝response涓嶆槸SIPResponse");
+ }
+ } else {
+ logger.error("[璇煶瀵硅]鏀跺埌鐨勬秷鎭敊璇紝event涓嶆槸ResponseEvent");
+ }
+
+ }, (event) -> {
+ dynamicTask.stop(timeOutTaskKey);
+ mediaServerService.closeRTPServer(mediaServerItem, sendRtpItem.getStream());
+ // 閲婃斁ssrc
+ mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpItem.getSsrc());
+ streamSession.remove(device.getDeviceId(), channelId, sendRtpItem.getStream());
+ errorEvent.response(event);
+ });
+ } catch (InvalidArgumentException | SipException | ParseException e) {
+
+ logger.error("[鍛戒护鍙戦�佸け璐 瀵硅娑堟伅: {}", e.getMessage());
+ dynamicTask.stop(timeOutTaskKey);
+ mediaServerService.closeRTPServer(mediaServerItem, sendRtpItem.getStream());
+ // 閲婃斁ssrc
+ mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpItem.getSsrc());
+
+ streamSession.remove(device.getDeviceId(), channelId, sendRtpItem.getStream());
+ SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult();
+ eventResult.type = SipSubscribe.EventResultType.cmdSendFailEvent;
+ eventResult.statusCode = -1;
+ eventResult.msg = "鍛戒护鍙戦�佸け璐�";
+ errorEvent.response(eventResult);
+ }
+// }
+
+ }
+
+
@Override
- public void play(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId,
+ public void play(MediaServer mediaServerItem, SSRCInfo ssrcInfo, Device device, DeviceChannel channel,
ErrorCallback<Object> callback) {
if (mediaServerItem == null || ssrcInfo == null) {
@@ -178,110 +464,107 @@
null);
return;
}
- logger.info("[鐐规挱寮�濮媇 deviceId: {}, channelId: {},鐮佹祦绫诲瀷锛歿}, 鏀舵祦绔彛锛� {}, STREAM锛歿}, 鏀舵祦妯″紡锛歿}, SSRC: {}, SSRC鏍¢獙锛歿}",
- device.getDeviceId(), channelId, device.isSwitchPrimarySubStream() ? "杈呯爜娴�" : "涓荤爜娴�", ssrcInfo.getPort(), ssrcInfo.getStream(),
+ logger.info("[鐐规挱寮�濮媇 deviceId: {}, channelId: {},鐮佹祦绫诲瀷锛歿}, 鏀舵祦绔彛锛� {}, 鐮佹祦锛歿}, 鏀舵祦妯″紡锛歿}, SSRC: {}, SSRC鏍¢獙锛歿}",
+ device.getDeviceId(), channel.getChannelId(), channel.getStreamIdentification(), ssrcInfo.getPort(), ssrcInfo.getStream(),
device.getStreamMode(), ssrcInfo.getSsrc(), device.isSsrcCheck());
//绔彛鑾峰彇澶辫触鐨剆srcInfo 娌℃湁蹇呰鍙戦�佺偣鎾寚浠�
if (ssrcInfo.getPort() <= 0) {
- logger.info("[鐐规挱绔彛鍒嗛厤寮傚父]锛宒eviceId={},channelId={},ssrcInfo={}", device.getDeviceId(), channelId, ssrcInfo);
+ logger.info("[鐐规挱绔彛鍒嗛厤寮傚父]锛宒eviceId={},channelId={},ssrcInfo={}", device.getDeviceId(), channel.getChannelId(), ssrcInfo);
// 閲婃斁ssrc
mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
- streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
+ streamSession.remove(device.getDeviceId(), channel.getChannelId(), ssrcInfo.getStream());
callback.run(InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(), "鐐规挱绔彛鍒嗛厤寮傚父", null);
- inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
+ inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channel.getChannelId(), null,
InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(), "鐐规挱绔彛鍒嗛厤寮傚父", null);
return;
}
// 鍒濆鍖杛edis涓殑invite娑堟伅鐘舵��
- InviteInfo inviteInfo = InviteInfo.getInviteInfo(device.getDeviceId(), channelId, ssrcInfo.getStream(), ssrcInfo,
+ InviteInfo inviteInfo = InviteInfo.getInviteInfo(device.getDeviceId(), channel.getChannelId(), ssrcInfo.getStream(), ssrcInfo,
mediaServerItem.getSdpIp(), ssrcInfo.getPort(), device.getStreamMode(), InviteSessionType.PLAY,
InviteSessionStatus.ready);
- inviteInfo.setSubStream(device.isSwitchPrimarySubStream());
inviteStreamService.updateInviteInfo(inviteInfo);
// 瓒呮椂澶勭悊
String timeOutTaskKey = UUID.randomUUID().toString();
dynamicTask.startDelay(timeOutTaskKey, () -> {
// 鎵ц瓒呮椂浠诲姟鏃舵煡璇㈡槸鍚﹀凡缁忔垚鍔燂紝鎴愬姛浜嗗垯涓嶆墽琛岃秴鏃朵换鍔★紝闃叉瓒呮椂浠诲姟鍙栨秷澶辫触鐨勬儏鍐�
- InviteInfo inviteInfoForTimeOut = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId);
+ InviteInfo inviteInfoForTimeOut = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channel.getChannelId());
if (inviteInfoForTimeOut == null || inviteInfoForTimeOut.getStreamInfo() == null) {
- logger.info("[鐐规挱瓒呮椂] 鏀舵祦瓒呮椂 deviceId: {}, channelId: {},鐮佹祦绫诲瀷锛歿}锛岀鍙o細{}, SSRC: {}",
- device.getDeviceId(), channelId, device.isSwitchPrimarySubStream() ? "杈呯爜娴�" : "涓荤爜娴�",
+ logger.info("[鐐规挱瓒呮椂] 鏀舵祦瓒呮椂 deviceId: {}, channelId: {},鐮佹祦锛歿}锛岀鍙o細{}, SSRC: {}",
+ device.getDeviceId(), channel.getChannelId(), channel.getStreamIdentification(),
ssrcInfo.getPort(), ssrcInfo.getSsrc());
callback.run(InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getCode(), InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getMsg(), null);
- inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
+ inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channel.getChannelId(), null,
InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getCode(), InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getMsg(), null);
- inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId);
+ inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channel.getChannelId());
try {
- cmder.streamByeCmd(device, channelId, ssrcInfo.getStream(), null);
+ cmder.streamByeCmd(device, channel.getChannelId(), ssrcInfo.getStream(), null);
} catch (InvalidArgumentException | ParseException | SipException | SsrcTransactionNotFoundException e) {
logger.error("[鐐规挱瓒呮椂]锛� 鍙戦�丅YE澶辫触 {}", e.getMessage());
} finally {
mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream());
- streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
+ streamSession.remove(device.getDeviceId(), channel.getChannelId(), ssrcInfo.getStream());
mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream());
// 鍙栨秷璁㈤槄娑堟伅鐩戝惉
- HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", ssrcInfo.getStream(), true, "rtsp", mediaServerItem.getId());
- subscribe.removeSubscribe(hookSubscribe);
+ subscribe.removeSubscribe(Hook.getInstance(HookType.on_media_arrival, "rtp", ssrcInfo.getStream(), mediaServerItem.getId()));
}
}else {
- logger.info("[鐐规挱瓒呮椂] 鏀舵祦瓒呮椂 deviceId: {}, channelId: {},鐮佹祦绫诲瀷锛歿}锛岀鍙o細{}, SSRC: {}",
- device.getDeviceId(), channelId, device.isSwitchPrimarySubStream() ? "杈呯爜娴�" : "涓荤爜娴�",
+ logger.info("[鐐规挱瓒呮椂] 鏀舵祦瓒呮椂 deviceId: {}, channelId: {},鐮佹祦锛歿}锛岀鍙o細{}, SSRC: {}",
+ device.getDeviceId(), channel.getChannelId(), channel.getStreamIdentification(),
ssrcInfo.getPort(), ssrcInfo.getSsrc());
mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
mediaServerService.closeRTPServer(mediaServerItem.getId(), ssrcInfo.getStream());
- streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
+ streamSession.remove(device.getDeviceId(), channel.getChannelId(), ssrcInfo.getStream());
}
}, userSetting.getPlayTimeout());
try {
- cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (mediaServerItemInuse, hookParam ) -> {
- logger.info("鏀跺埌璁㈤槄娑堟伅锛� " + hookParam);
+ cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channel, (hookData ) -> {
+ logger.info("鏀跺埌璁㈤槄娑堟伅锛� " + hookData);
dynamicTask.stop(timeOutTaskKey);
// hook鍝嶅簲
- StreamInfo streamInfo = onPublishHandlerForPlay(mediaServerItemInuse, hookParam, device.getDeviceId(), channelId);
+ StreamInfo streamInfo = onPublishHandlerForPlay(hookData.getMediaServer(), hookData.getMediaInfo(), device.getDeviceId(), channel.getChannelId());
if (streamInfo == null){
callback.run(InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getCode(),
InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getMsg(), null);
- inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
+ inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channel.getChannelId(), null,
InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getCode(),
InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getMsg(), null);
return;
}
callback.run(InviteErrorCode.SUCCESS.getCode(), InviteErrorCode.SUCCESS.getMsg(), streamInfo);
- inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
+ inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channel.getChannelId(), null,
InviteErrorCode.SUCCESS.getCode(),
InviteErrorCode.SUCCESS.getMsg(),
streamInfo);
- logger.info("[鐐规挱鎴愬姛] deviceId: {}, channelId:{}, 鐮佹祦绫诲瀷锛歿}", device.getDeviceId(), channelId,
- device.isSwitchPrimarySubStream() ? "杈呯爜娴�" : "涓荤爜娴�");
- snapOnPlay(mediaServerItemInuse, device.getDeviceId(), channelId, ssrcInfo.getStream());
+ logger.info("[鐐规挱鎴愬姛] deviceId: {}, channelId:{}, 鐮佹祦绫诲瀷锛歿}", device.getDeviceId(), channel.getChannelId(),
+ channel.getStreamIdentification());
+ snapOnPlay(hookData.getMediaServer(), device.getDeviceId(), channel.getChannelId(), ssrcInfo.getStream());
}, (eventResult) -> {
// 澶勭悊鏀跺埌200ok鍚庣殑TCP涓诲姩杩炴帴浠ュ強SSRC涓嶄竴鑷寸殑闂
- InviteOKHandler(eventResult, ssrcInfo, mediaServerItem, device, channelId,
+ InviteOKHandler(eventResult, ssrcInfo, mediaServerItem, device, channel.getChannelId(),
timeOutTaskKey, callback, inviteInfo, InviteSessionType.PLAY);
}, (event) -> {
- logger.info("[鐐规挱澶辫触] deviceId: {}, channelId:{}, {}: {}", device.getDeviceId(), channelId, event.statusCode, event.msg);
+ logger.info("[鐐规挱澶辫触] deviceId: {}, channelId:{}, {}: {}", device.getDeviceId(), channel.getChannelId(), event.statusCode, event.msg);
dynamicTask.stop(timeOutTaskKey);
mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream());
// 閲婃斁ssrc
mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
- streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
+ streamSession.remove(device.getDeviceId(), channel.getChannelId(), ssrcInfo.getStream());
- callback.run(InviteErrorCode.ERROR_FOR_SIGNALLING_ERROR.getCode(),
- String.format("鐐规挱澶辫触锛� 閿欒鐮侊細 %s, %s", event.statusCode, event.msg), null);
- inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
+ callback.run(event.statusCode, event.msg, null);
+ inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channel.getChannelId(), null,
InviteErrorCode.ERROR_FOR_RESET_SSRC.getCode(),
String.format("鐐规挱澶辫触锛� 閿欒鐮侊細 %s, %s", event.statusCode, event.msg), null);
- inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId);
+ inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channel.getChannelId());
});
} catch (InvalidArgumentException | SipException | ParseException e) {
@@ -291,20 +574,20 @@
// 閲婃斁ssrc
mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
- streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
+ streamSession.remove(device.getDeviceId(), channel.getChannelId(), ssrcInfo.getStream());
callback.run(InviteErrorCode.ERROR_FOR_SIP_SENDING_FAILED.getCode(),
InviteErrorCode.ERROR_FOR_SIP_SENDING_FAILED.getMsg(), null);
- inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
+ inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channel.getChannelId(), null,
InviteErrorCode.ERROR_FOR_SIP_SENDING_FAILED.getCode(),
InviteErrorCode.ERROR_FOR_SIP_SENDING_FAILED.getMsg(), null);
- inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId);
+ inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channel.getChannelId());
}
}
private void tcpActiveHandler(Device device, String channelId, String contentString,
- MediaServerItem mediaServerItem,
+ MediaServer mediaServerItem,
String timeOutTaskKey, SSRCInfo ssrcInfo, ErrorCallback<Object> callback){
if (!device.getStreamMode().equalsIgnoreCase("TCP-ACTIVE")) {
return;
@@ -331,8 +614,23 @@
}
}
logger.info("[TCP涓诲姩杩炴帴瀵规柟] deviceId: {}, channelId: {}, 杩炴帴瀵规柟鐨勫湴鍧�锛歿}:{}, 鏀舵祦妯″紡锛歿}, SSRC: {}, SSRC鏍¢獙锛歿}", device.getDeviceId(), channelId, sdp.getConnection().getAddress(), port, device.getStreamMode(), ssrcInfo.getSsrc(), device.isSsrcCheck());
- JSONObject jsonObject = zlmresTfulUtils.connectRtpServer(mediaServerItem, sdp.getConnection().getAddress(), port, ssrcInfo.getStream());
- logger.info("[TCP涓诲姩杩炴帴瀵规柟] 缁撴灉锛� {}", jsonObject);
+ Boolean result = mediaServerService.connectRtpServer(mediaServerItem, sdp.getConnection().getAddress(), port, ssrcInfo.getStream());
+ logger.info("[TCP涓诲姩杩炴帴瀵规柟] 缁撴灉锛� {}" , result);
+ if (!result) {
+ // 涓诲姩杩炴帴澶辫触锛岀粨鏉熸祦绋嬶紝 娓呯悊鏁版嵁
+ dynamicTask.stop(timeOutTaskKey);
+ mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream());
+ // 閲婃斁ssrc
+ mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
+
+ streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
+
+ callback.run(InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getCode(),
+ InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getMsg(), null);
+ inviteStreamService.call(InviteSessionType.BROADCAST, device.getDeviceId(), channelId, null,
+ InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getCode(),
+ InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getMsg(), null);
+ }
} catch (SdpException e) {
logger.error("[TCP涓诲姩杩炴帴瀵规柟] deviceId: {}, channelId: {}, 瑙f瀽200OK鐨凷DP淇℃伅澶辫触", device.getDeviceId(), channelId, e);
dynamicTask.stop(timeOutTaskKey);
@@ -344,7 +642,7 @@
callback.run(InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getCode(),
InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getMsg(), null);
- inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
+ inviteStreamService.call(InviteSessionType.BROADCAST, device.getDeviceId(), channelId, null,
InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getCode(),
InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getMsg(), null);
}
@@ -358,7 +656,7 @@
* @param channelId 閫氶亾 ID
* @param stream ssrc
*/
- private void snapOnPlay(MediaServerItem mediaServerItemInuse, String deviceId, String channelId, String stream) {
+ private void snapOnPlay(MediaServer mediaServerItemInuse, String deviceId, String channelId, String stream) {
String streamUrl;
if (mediaServerItemInuse.getRtspPort() != 0) {
streamUrl = String.format("rtsp://127.0.0.1:%s/%s/%s", mediaServerItemInuse.getRtspPort(), "rtp", stream);
@@ -369,14 +667,13 @@
String fileName = deviceId + "_" + channelId + ".jpg";
// 璇锋眰鎴浘
logger.info("[璇锋眰鎴浘]: " + fileName);
- zlmresTfulUtils.getSnap(mediaServerItemInuse, streamUrl, 15, 1, path, fileName);
+ mediaServerService.getSnap(mediaServerItemInuse, streamUrl, 15, 1, path, fileName);
}
- private StreamInfo onPublishHandlerForPlay(MediaServerItem mediaServerItem, HookParam hookParam, String deviceId, String channelId) {
+ public StreamInfo onPublishHandlerForPlay(MediaServer mediaServerItem, MediaInfo mediaInfo, String deviceId, String channelId) {
StreamInfo streamInfo = null;
Device device = redisCatchStorage.getDevice(deviceId);
- OnStreamChangedHookParam streamChangedHookParam = (OnStreamChangedHookParam)hookParam;
- streamInfo = onPublishHandler(mediaServerItem, streamChangedHookParam, deviceId, channelId);
+ streamInfo = onPublishHandler(mediaServerItem, mediaInfo, deviceId, channelId);
if (streamInfo != null) {
DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId);
if (deviceChannel != null) {
@@ -394,9 +691,8 @@
}
- private StreamInfo onPublishHandlerForPlayback(MediaServerItem mediaServerItem, HookParam param, String deviceId, String channelId, String startTime, String endTime) {
- OnStreamChangedHookParam streamChangedHookParam = (OnStreamChangedHookParam) param;
- StreamInfo streamInfo = onPublishHandler(mediaServerItem, streamChangedHookParam, deviceId, channelId);
+ private StreamInfo onPublishHandlerForPlayback(MediaServer mediaServerItem, MediaInfo mediaInfo, String deviceId, String channelId, String startTime, String endTime) {
+ StreamInfo streamInfo = onPublishHandler(mediaServerItem, mediaInfo, deviceId, channelId);
if (streamInfo != null) {
streamInfo.setStartTime(startTime);
streamInfo.setEndTime(endTime);
@@ -405,7 +701,7 @@
deviceChannel.setStreamId(streamInfo.getStream());
storager.startPlay(deviceId, channelId, streamInfo.getStream());
}
- InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(InviteSessionType.PLAYBACK, ((OnStreamChangedHookParam) param).getStream());
+ InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(InviteSessionType.PLAYBACK, mediaInfo.getStream());
if (inviteInfo != null) {
inviteInfo.setStatus(InviteSessionStatus.ok);
@@ -418,11 +714,11 @@
}
@Override
- public MediaServerItem getNewMediaServerItem(Device device) {
+ public MediaServer getNewMediaServerItem(Device device) {
if (device == null) {
return null;
}
- MediaServerItem mediaServerItem;
+ MediaServer mediaServerItem;
if (ObjectUtils.isEmpty(device.getMediaServerId()) || "auto".equals(device.getMediaServerId())) {
mediaServerItem = mediaServerService.getMediaServerForMinimumLoad(null);
} else {
@@ -436,14 +732,20 @@
@Override
public void playBack(String deviceId, String channelId, String startTime,
- String endTime, ErrorCallback<Object> callback) {
+ String endTime, ErrorCallback<Object> callback) {
Device device = storager.queryVideoDevice(deviceId);
if (device == null) {
logger.warn("[褰曞儚鍥炴斁] 鏈壘鍒拌澶� deviceId: {},channelId:{}", deviceId, channelId);
throw new ControllerException(ErrorCode.ERROR100.getCode(), "鏈壘鍒拌澶囷細" + deviceId);
}
- MediaServerItem newMediaServerItem = getNewMediaServerItem(device);
+ DeviceChannel channel = channelService.getOne(deviceId, channelId);
+ if (channel == null) {
+ logger.warn("[褰曞儚鍥炴斁] 鏈壘鍒伴�氶亾 deviceId: {},channelId:{}", deviceId, channelId);
+ throw new ControllerException(ErrorCode.ERROR100.getCode(), "鏈壘鍒伴�氶亾锛�" + channelId);
+ }
+
+ MediaServer newMediaServerItem = getNewMediaServerItem(device);
if (device.getStreamMode().equalsIgnoreCase("TCP-ACTIVE") && ! newMediaServerItem.isRtpEnable()) {
logger.warn("[褰曞儚鍥炴斁] 鍗曠鍙f敹娴佹椂涓嶆敮鎸乀CP涓诲姩鏂瑰紡鏀舵祦 deviceId: {},channelId:{}", deviceId, channelId);
throw new ControllerException(ErrorCode.ERROR100.getCode(), "鍗曠鍙f敹娴佹椂涓嶆敮鎸乀CP涓诲姩鏂瑰紡鏀舵祦");
@@ -455,14 +757,14 @@
.replace(":", "")
.replace(" ", "");
String stream = deviceId + "_" + channelId + "_" + startTimeStr + "_" + endTimeTimeStr;
- SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, stream, null, device.isSsrcCheck(), true, 0, false, device.getStreamModeForParam());
+ SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, stream, null, device.isSsrcCheck(), true, 0, false, !channel.getHasAudio(), false, device.getStreamModeForParam());
playBack(newMediaServerItem, ssrcInfo, deviceId, channelId, startTime, endTime, callback);
}
@Override
- public void playBack(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo,
- String deviceId, String channelId, String startTime,
- String endTime, ErrorCallback<Object> callback) {
+ public void playBack(MediaServer mediaServerItem, SSRCInfo ssrcInfo,
+ String deviceId, String channelId, String startTime,
+ String endTime, ErrorCallback<Object> callback) {
if (mediaServerItem == null || ssrcInfo == null) {
callback.run(InviteErrorCode.ERROR_FOR_PARAMETER_ERROR.getCode(),
InviteErrorCode.ERROR_FOR_PARAMETER_ERROR.getMsg(),
@@ -511,10 +813,10 @@
inviteStreamService.removeInviteInfo(inviteInfo);
};
- ZlmHttpHookSubscribe.Event hookEvent = (mediaServerItemInuse, hookParam) -> {
- logger.info("鏀跺埌鍥炴斁璁㈤槄娑堟伅锛� " + hookParam);
+ HookSubscribe.Event hookEvent = (hookData) -> {
+ logger.info("鏀跺埌鍥炴斁璁㈤槄娑堟伅锛� " + hookData);
dynamicTask.stop(playBackTimeOutTaskKey);
- StreamInfo streamInfo = onPublishHandlerForPlayback(mediaServerItemInuse, hookParam, deviceId, channelId, startTime, endTime);
+ StreamInfo streamInfo = onPublishHandlerForPlayback(hookData.getMediaServer(), hookData.getMediaInfo(), deviceId, channelId, startTime, endTime);
if (streamInfo == null) {
logger.warn("璁惧鍥炴斁API璋冪敤澶辫触锛�");
callback.run(InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getCode(),
@@ -544,7 +846,7 @@
}
- private void InviteOKHandler(SipSubscribe.EventResult eventResult, SSRCInfo ssrcInfo, MediaServerItem mediaServerItem,
+ private void InviteOKHandler(SipSubscribe.EventResult eventResult, SSRCInfo ssrcInfo, MediaServer mediaServerItem,
Device device, String channelId, String timeOutTaskKey, ErrorCallback<Object> callback,
InviteInfo inviteInfo, InviteSessionType inviteSessionType){
inviteInfo.setStatus(InviteSessionStatus.ok);
@@ -640,7 +942,11 @@
if (device == null) {
return;
}
- MediaServerItem newMediaServerItem = this.getNewMediaServerItem(device);
+ DeviceChannel channel = channelService.getOne(deviceId, channelId);
+ if (channel == null) {
+ return;
+ }
+ MediaServer newMediaServerItem = this.getNewMediaServerItem(device);
if (newMediaServerItem == null) {
callback.run(InviteErrorCode.ERROR_FOR_ASSIST_NOT_READY.getCode(),
InviteErrorCode.ERROR_FOR_ASSIST_NOT_READY.getMsg(),
@@ -648,13 +954,13 @@
return;
}
// 褰曞儚涓嬭浇涓嶄娇鐢ㄥ浐瀹氭祦鍦板潃锛屽浐瀹氭祦鍦板潃浼氬鑷村鏋滃紑濮嬫椂闂翠笌缁撴潫鏃堕棿涓�鑷存椂鏂囦欢閿欒鐨勫彔鍔犲湪涓�璧�
- SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, null, device.isSsrcCheck(), true, 0, false, device.getStreamModeForParam());
+ SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, null, device.isSsrcCheck(), true, 0, false,!channel.getHasAudio(), false, device.getStreamModeForParam());
download(newMediaServerItem, ssrcInfo, deviceId, channelId, startTime, endTime, downloadSpeed, callback);
}
@Override
- public void download(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, ErrorCallback<Object> callback) {
+ public void download(MediaServer mediaServerItem, SSRCInfo ssrcInfo, String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, ErrorCallback<Object> callback) {
if (mediaServerItem == null || ssrcInfo == null) {
callback.run(InviteErrorCode.ERROR_FOR_PARAMETER_ERROR.getCode(),
InviteErrorCode.ERROR_FOR_PARAMETER_ERROR.getMsg(),
@@ -700,10 +1006,10 @@
streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
inviteStreamService.removeInviteInfo(inviteInfo);
};
- ZlmHttpHookSubscribe.Event hookEvent = (mediaServerItemInuse, hookParam) -> {
- logger.info("[褰曞儚涓嬭浇]鏀跺埌璁㈤槄娑堟伅锛� " + hookParam);
+ HookSubscribe.Event hookEvent = (hookData) -> {
+ logger.info("[褰曞儚涓嬭浇]鏀跺埌璁㈤槄娑堟伅锛� " + hookData);
dynamicTask.stop(downLoadTimeOutTaskKey);
- StreamInfo streamInfo = onPublishHandlerForDownload(mediaServerItemInuse, hookParam, deviceId, channelId, startTime, endTime);
+ StreamInfo streamInfo = onPublishHandlerForDownload(hookData.getMediaServer(), hookData.getMediaInfo(), deviceId, channelId, startTime, endTime);
if (streamInfo == null) {
logger.warn("[褰曞儚涓嬭浇] 鑾峰彇娴佸湴鍧�淇℃伅澶辫触");
callback.run(InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getCode(),
@@ -721,26 +1027,22 @@
downLoadTimeOutTaskKey, callback, inviteInfo, InviteSessionType.DOWNLOAD);
// 娉ㄥ唽褰曞儚鍥炶皟浜嬩欢锛屽綍鍍忎笅杞界粨鏉熷悗鍐欏叆涓嬭浇鍦板潃
- ZlmHttpHookSubscribe.Event hookEventForRecord = (mediaServerItemInuse, hookParam) -> {
+ HookSubscribe.Event hookEventForRecord = (hookData) -> {
logger.info("[褰曞儚涓嬭浇] 鏀跺埌褰曞儚鍐欏叆纾佺洏娑堟伅锛� 锛� {}/{}-{}",
inviteInfo.getDeviceId(), inviteInfo.getChannelId(), ssrcInfo.getStream());
- logger.info("[褰曞儚涓嬭浇] 鏀跺埌褰曞儚鍐欏叆纾佺洏娑堟伅鍐呭锛� " + hookParam);
- OnRecordMp4HookParam recordMp4HookParam = (OnRecordMp4HookParam)hookParam;
- String filePath = recordMp4HookParam.getFile_path();
+ logger.info("[褰曞儚涓嬭浇] 鏀跺埌褰曞儚鍐欏叆纾佺洏娑堟伅鍐呭锛� " + hookData);
+ RecordInfo recordInfo = hookData.getRecordInfo();
+ String filePath = recordInfo.getFilePath();
DownloadFileInfo downloadFileInfo = CloudRecordUtils.getDownloadFilePath(mediaServerItem, filePath);
InviteInfo inviteInfoForNew = inviteStreamService.getInviteInfo(inviteInfo.getType(), inviteInfo.getDeviceId()
, inviteInfo.getChannelId(), inviteInfo.getStream());
inviteInfoForNew.getStreamInfo().setDownLoadFilePath(downloadFileInfo);
inviteStreamService.updateInviteInfo(inviteInfoForNew);
};
- HookSubscribeForRecordMp4 hookSubscribe = HookSubscribeFactory.on_record_mp4(
- mediaServerItem.getId(), "rtp", ssrcInfo.getStream());
-
+ Hook hook = Hook.getInstance(HookType.on_record_mp4, "rtp", ssrcInfo.getStream(), mediaServerItem.getId());
// 璁剧疆杩囨湡鏃堕棿锛屼笅杞藉け璐ユ椂鑷姩澶勭悊璁㈤槄鏁版嵁
-// long difference = DateUtil.getDifference(startTime, endTime)/1000;
-// Instant expiresInstant = Instant.now().plusSeconds(TimeUnit.MINUTES.toSeconds(difference * 2));
-// hookSubscribe.setExpires(expiresInstant);
- subscribe.addSubscribe(hookSubscribe, hookEventForRecord);
+ hook.setExpireTime(System.currentTimeMillis() + 24 * 60 * 60 * 1000);
+ subscribe.addSubscribe(hook, hookEventForRecord);
});
} catch (InvalidArgumentException | SipException | ParseException e) {
logger.error("[鍛戒护鍙戦�佸け璐 褰曞儚涓嬭浇: {}", e.getMessage());
@@ -767,7 +1069,7 @@
// 鑾峰彇褰撳墠宸蹭笅杞芥椂闀�
String mediaServerId = inviteInfo.getStreamInfo().getMediaServerId();
- MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId);
+ MediaServer mediaServerItem = mediaServerService.getOne(mediaServerId);
if (mediaServerItem == null) {
logger.warn("[鑾峰彇涓嬭浇杩涘害] 鏌ヨ褰曞儚淇℃伅鏃跺彂鐜拌妭鐐逛笉瀛樺湪");
return null;
@@ -778,30 +1080,13 @@
logger.warn("[鑾峰彇涓嬭浇杩涘害] 涓嬭浇宸茬粨鏉�");
return null;
}
-
- JSONObject mediaListJson= zlmresTfulUtils.getMediaList(mediaServerItem, "rtp", stream);
- if (mediaListJson == null) {
- logger.warn("[鑾峰彇涓嬭浇杩涘害] 浠巣lm鏌ヨ杩涘害澶辫触");
+ String app = "rtp";
+ MediaInfo mediaInfo = mediaServerService.getMediaInfo(mediaServerItem, app, stream);
+ if (mediaInfo == null) {
+ logger.warn("[鑾峰彇涓嬭浇杩涘害] 鏌ヨ杩涘害澶辫触, 鑺傜偣Id锛� {}锛� {}/{}", mediaServerId, app, stream);
return null;
}
- if (mediaListJson.getInteger("code") != 0) {
- logger.warn("[鑾峰彇涓嬭浇杩涘害] 浠巣lm鏌ヨ杩涘害鍑虹幇閿欒锛� {}", mediaListJson.getString("msg"));
- return null;
- }
- JSONArray data = mediaListJson.getJSONArray("data");
- if (data == null) {
- logger.warn("[鑾峰彇涓嬭浇杩涘害] 浠巣lm鏌ヨ杩涘害鏃舵湭杩斿洖鏁版嵁");
- return null;
- }
- JSONObject mediaJSON = data.getJSONObject(0);
- JSONArray tracks = mediaJSON.getJSONArray("tracks");
- if (tracks.isEmpty()) {
- logger.warn("[鑾峰彇涓嬭浇杩涘害] 浠巣lm鏌ヨ杩涘害鏃舵湭杩斿洖鏁版嵁");
- return null;
- }
- JSONObject jsonObject = tracks.getJSONObject(0);
- long duration = jsonObject.getLongValue("duration");
- if (duration == 0) {
+ if (mediaInfo.getDuration() == 0) {
inviteInfo.getStreamInfo().setProgress(0);
} else {
String startTime = inviteInfo.getStreamInfo().getStartTime();
@@ -810,7 +1095,7 @@
long start = DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(startTime);
long end = DateUtil.yyyy_MM_dd_HH_mm_ssToTimestamp(endTime);
- BigDecimal currentCount = new BigDecimal(duration);
+ BigDecimal currentCount = new BigDecimal(mediaInfo.getDuration());
BigDecimal totalCount = new BigDecimal((end - start) * 1000);
BigDecimal divide = currentCount.divide(totalCount, 2, RoundingMode.HALF_UP);
double process = divide.doubleValue();
@@ -823,9 +1108,8 @@
return inviteInfo.getStreamInfo();
}
- private StreamInfo onPublishHandlerForDownload(MediaServerItem mediaServerItemInuse, HookParam hookParam, String deviceId, String channelId, String startTime, String endTime) {
- OnStreamChangedHookParam streamChangedHookParam = (OnStreamChangedHookParam) hookParam;
- StreamInfo streamInfo = onPublishHandler(mediaServerItemInuse, streamChangedHookParam, deviceId, channelId);
+ private StreamInfo onPublishHandlerForDownload(MediaServer mediaServerItemInuse, MediaInfo mediaInfo, String deviceId, String channelId, String startTime, String endTime) {
+ StreamInfo streamInfo = onPublishHandler(mediaServerItemInuse, mediaInfo, deviceId, channelId);
if (streamInfo != null) {
streamInfo.setProgress(0);
streamInfo.setStartTime(startTime);
@@ -842,8 +1126,8 @@
}
- public StreamInfo onPublishHandler(MediaServerItem mediaServerItem, OnStreamChangedHookParam hookParam, String deviceId, String channelId) {
- StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(mediaServerItem, "rtp", hookParam.getStream(), hookParam.getTracks(), null);
+ public StreamInfo onPublishHandler(MediaServer mediaServerItem, MediaInfo mediaInfo, String deviceId, String channelId) {
+ StreamInfo streamInfo = mediaServerService.getStreamInfoByAppAndStream(mediaServerItem, "rtp", mediaInfo.getStream(), mediaInfo, null);
streamInfo.setDeviceID(deviceId);
streamInfo.setChannelId(channelId);
return streamInfo;
@@ -879,13 +1163,142 @@
cmder.streamByeCmd(device, ssrcTransaction.getChannelId(),
ssrcTransaction.getStream(), null);
} catch (InvalidArgumentException | ParseException | SipException |
- SsrcTransactionNotFoundException e) {
+ SsrcTransactionNotFoundException e) {
logger.error("[zlm绂荤嚎]涓烘鍦ㄤ娇鐢ㄦzlm鐨勮澶囷紝 鍙戦�丅YE澶辫触 {}", e.getMessage());
}
}
}
}
}
+
+ @Override
+ public AudioBroadcastResult audioBroadcast(Device device, String channelId, Boolean broadcastMode) {
+ // TODO 蹇呴』澶氱鍙fā寮忔墠鏀寔璇煶鍠婅瘽楣よ闊冲璁�
+ if (device == null || channelId == null) {
+ return null;
+ }
+ logger.info("[璇煶鍠婅瘽] device锛� {}, channel: {}", device.getDeviceId(), channelId);
+ DeviceChannel deviceChannel = storager.queryChannel(device.getDeviceId(), channelId);
+ if (deviceChannel == null) {
+ logger.warn("寮�鍚闊冲箍鎾殑鏃跺�欐湭鎵惧埌閫氶亾锛� {}", channelId);
+ return null;
+ }
+ MediaServer mediaServerItem = mediaServerService.getMediaServerForMinimumLoad(null);
+ if (broadcastMode == null) {
+ broadcastMode = true;
+ }
+ String app = broadcastMode?"broadcast":"talk";
+ String stream = device.getDeviceId() + "_" + channelId;
+ AudioBroadcastResult audioBroadcastResult = new AudioBroadcastResult();
+ audioBroadcastResult.setApp(app);
+ audioBroadcastResult.setStream(stream);
+ audioBroadcastResult.setStreamInfo(new StreamContent(mediaServerService.getStreamInfoByAppAndStream(mediaServerItem, app, stream, null, null, null, false)));
+ audioBroadcastResult.setCodec("G.711");
+ return audioBroadcastResult;
+ }
+
+ @Override
+ public boolean audioBroadcastCmd(Device device, String channelId, MediaServer mediaServerItem, String app, String stream, int timeout, boolean isFromPlatform, AudioBroadcastEvent event) throws InvalidArgumentException, ParseException, SipException {
+ if (device == null || channelId == null) {
+ 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 false;
+ }
+ // 鏌ヨ閫氶亾浣跨敤鐘舵��
+ if (audioBroadcastManager.exit(device.getDeviceId(), channelId)) {
+ SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(device.getDeviceId(), channelId, null, null);
+ if (sendRtpItem != null && sendRtpItem.isOnlyAudio()) {
+ // 鏌ヨ娴佹槸鍚﹀瓨鍦紝涓嶅瓨鍦ㄥ垯璁や负鏄紓甯哥姸鎬�
+ Boolean streamReady = mediaServerService.isStreamReady(mediaServerItem, sendRtpItem.getApp(), sendRtpItem.getStream());
+ if (streamReady) {
+ logger.warn("璇煶骞挎挱宸茬粡寮�鍚細 {}", channelId);
+ event.call("璇煶骞挎挱宸茬粡寮�鍚�");
+ return false;
+ } else {
+ stopAudioBroadcast(device.getDeviceId(), channelId);
+ }
+ }
+ }
+
+ // 鍙戦�侀�氱煡
+ cmder.audioBroadcastCmd(device, channelId, eventResultForOk -> {
+ // 鍙戦�佹垚鍔�
+ AudioBroadcastCatch audioBroadcastCatch = new AudioBroadcastCatch(device.getDeviceId(), channelId, mediaServerItem, app, stream, event, AudioBroadcastCatchStatus.Ready, isFromPlatform);
+ audioBroadcastManager.update(audioBroadcastCatch);
+ // 绛夊緟invite娑堟伅锛� 瓒呮椂鍒欑粨鏉�
+ String key = VideoManagerConstants.BROADCAST_WAITE_INVITE + device.getDeviceId();
+ if (!SipUtils.isFrontEnd(device.getDeviceId())) {
+ key += audioBroadcastCatch.getChannelId();
+ }
+ dynamicTask.startDelay(key, ()->{
+ logger.info("[璇煶骞挎挱]绛夊緟invite娑堟伅瓒呮椂锛歿}/{}", device.getDeviceId(), channelId);
+ stopAudioBroadcast(device.getDeviceId(), channelId);
+ }, 10*1000);
+ }, eventResultForError -> {
+ // 鍙戦�佸け璐�
+ logger.error("璇煶骞挎挱鍙戦�佸け璐ワ細 {}:{}", channelId, eventResultForError.msg);
+ 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()) {
+ // 鏌ヨ娴佹槸鍚﹀瓨鍦紝涓嶅瓨鍦ㄥ垯璁や负鏄紓甯哥姸鎬�
+ MediaServer mediaServerServiceOne = mediaServerService.getOne(sendRtpItem.getMediaServerId());
+ Boolean streamReady = mediaServerService.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));
+ } else {
+ audioBroadcastCatchList.add(audioBroadcastManager.get(deviceId, channelId));
+ }
+ if (audioBroadcastCatchList.size() > 0) {
+ for (AudioBroadcastCatch audioBroadcastCatch : audioBroadcastCatchList) {
+ Device device = deviceService.getDevice(deviceId);
+ if (device == null || audioBroadcastCatch == null) {
+ return;
+ }
+ SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(deviceId, audioBroadcastCatch.getChannelId(), null, null);
+ if (sendRtpItem != null) {
+ redisCatchStorage.deleteSendRTPServer(deviceId, sendRtpItem.getChannelId(), null, null);
+ MediaServer mediaServer = mediaServerService.getOne(sendRtpItem.getMediaServerId());
+ mediaServerService.stopSendRtp(mediaServer, sendRtpItem.getApp(), sendRtpItem.getStream(), null);
+ try {
+ cmder.streamByeCmdForDeviceInvite(device, sendRtpItem.getChannelId(), audioBroadcastCatch.getSipTransactionInfo(), null);
+ } catch (InvalidArgumentException | ParseException | SipException |
+ SsrcTransactionNotFoundException e) {
+ logger.error("[娑堟伅鍙戦�佸け璐 鍙戦�佽闊冲枈璇滲YE澶辫触");
+ }
+ }
+
+ audioBroadcastManager.del(deviceId, channelId);
+ }
+ }
+ }
+
@Override
public void zlmServerOnline(String mediaServerId) {
@@ -948,16 +1361,19 @@
}
inviteInfo.getStreamInfo().setPause(true);
inviteStreamService.updateInviteInfo(inviteInfo);
- MediaServerItem mediaServerItem = mediaServerService.getOne(inviteInfo.getStreamInfo().getMediaServerId());
+ MediaServer mediaServerItem = mediaServerService.getOne(inviteInfo.getStreamInfo().getMediaServerId());
if (null == mediaServerItem) {
logger.warn("mediaServer 涓嶅瓨鍦�!");
throw new ServiceException("mediaServer涓嶅瓨鍦�");
}
// zlm 鏆傚仠RTP瓒呮椂妫�鏌�
// 浣跨敤zlm涓殑娴両D
- String ssrc = Long.toHexString(Long.parseLong(ssrcTransaction.getSsrc())).toUpperCase();
- JSONObject jsonObject = zlmresTfulUtils.pauseRtpCheck(mediaServerItem, ssrc);
- if (jsonObject == null || jsonObject.getInteger("code") != 0) {
+ String streamKey = inviteInfo.getStream();
+ if (!mediaServerItem.isRtpEnable()) {
+ streamKey = Long.toHexString(Long.parseLong(inviteInfo.getSsrcInfo().getSsrc())).toUpperCase();
+ }
+ Boolean result = mediaServerService.pauseRtpCheck(mediaServerItem, streamKey);
+ if (!result) {
throw new ServiceException("鏆傚仠RTP鎺ユ敹澶辫触");
}
Device device = storager.queryVideoDevice(inviteInfo.getDeviceId());
@@ -973,20 +1389,169 @@
}
inviteInfo.getStreamInfo().setPause(false);
inviteStreamService.updateInviteInfo(inviteInfo);
- MediaServerItem mediaServerItem = mediaServerService.getOne(inviteInfo.getStreamInfo().getMediaServerId());
+ MediaServer mediaServerItem = mediaServerService.getOne(inviteInfo.getStreamInfo().getMediaServerId());
if (null == mediaServerItem) {
logger.warn("mediaServer 涓嶅瓨鍦�!");
throw new ServiceException("mediaServer涓嶅瓨鍦�");
}
// zlm 鏆傚仠RTP瓒呮椂妫�鏌�
// 浣跨敤zlm涓殑娴両D
- String ssrc = Long.toHexString(Long.parseLong(ssrcTransaction.getSsrc())).toUpperCase();
- JSONObject jsonObject = zlmresTfulUtils.resumeRtpCheck(mediaServerItem, ssrc);
- if (jsonObject == null || jsonObject.getInteger("code") != 0) {
+ String streamKey = inviteInfo.getStream();
+ if (!mediaServerItem.isRtpEnable()) {
+ streamKey = Long.toHexString(Long.parseLong(inviteInfo.getSsrcInfo().getSsrc())).toUpperCase();
+ }
+ boolean result = mediaServerService.resumeRtpCheck(mediaServerItem, streamKey);
+ if (!result) {
throw new ServiceException("缁х画RTP鎺ユ敹澶辫触");
}
Device device = storager.queryVideoDevice(inviteInfo.getDeviceId());
cmder.playResumeCmd(device, inviteInfo.getStreamInfo());
+ }
+
+ @Override
+ public void startPushStream(SendRtpItem sendRtpItem, SIPResponse sipResponse, ParentPlatform platform, CallIdHeader callIdHeader) {
+ // 寮�濮嬪彂娴�
+ MediaServer mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
+
+ if (mediaInfo != null) {
+ try {
+ if (sendRtpItem.isTcpActive()) {
+ mediaServerService.startSendRtpPassive(mediaInfo, platform, sendRtpItem, null);
+ } else {
+ mediaServerService.startSendRtp(mediaInfo, platform, sendRtpItem);
+ }
+ }catch (ControllerException e) {
+ logger.error("RTP鎺ㄦ祦澶辫触: {}", e.getMessage());
+ startSendRtpStreamFailHand(sendRtpItem, platform, callIdHeader);
+ return;
+ }
+
+ logger.info("RTP鎺ㄦ祦鎴愬姛[ {}/{} ]锛寋}, ", sendRtpItem.getApp(), sendRtpItem.getStream(),
+ sendRtpItem.isTcpActive()?"琚姩鍙戞祦": sendRtpItem.getIp() + ":" + sendRtpItem.getPort());
+
+ }
+ }
+
+ @Override
+ public void startSendRtpStreamFailHand(SendRtpItem sendRtpItem, ParentPlatform platform, CallIdHeader callIdHeader) {
+ if (sendRtpItem.isOnlyAudio()) {
+ Device device = deviceService.getDevice(sendRtpItem.getDeviceId());
+ AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId());
+ if (audioBroadcastCatch != null) {
+ try {
+ cmder.streamByeCmd(device, sendRtpItem.getChannelId(), audioBroadcastCatch.getSipTransactionInfo(), null);
+ } catch (SipException | ParseException | InvalidArgumentException |
+ SsrcTransactionNotFoundException exception) {
+ logger.error("[鍛戒护鍙戦�佸け璐 鍋滄璇煶瀵硅: {}", exception.getMessage());
+ }
+ }
+ } else {
+ if (platform != null) {
+ // 鍚戜笂绾у钩鍙�
+ try {
+ commanderForPlatform.streamByeCmd(platform, callIdHeader.getCallId());
+ } catch (SipException | InvalidArgumentException | ParseException e) {
+ logger.error("[鍛戒护鍙戦�佸け璐 鍥芥爣绾ц仈 鍙戦�丅YE: {}", e.getMessage());
+ }
+ }
+
+ }
+ }
+
+ @Override
+ public void talkCmd(Device device, String channelId, MediaServer mediaServerItem, String stream, AudioBroadcastEvent event) {
+ if (device == null || channelId == null) {
+ return;
+ }
+ // TODO 蹇呴』澶氱鍙fā寮忔墠鏀寔璇煶鍠婅瘽楣よ闊冲璁�
+ logger.info("[璇煶瀵硅] device锛� {}, channel: {}", device.getDeviceId(), channelId);
+ 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()) {
+ // 鏌ヨ娴佹槸鍚﹀瓨鍦紝涓嶅瓨鍦ㄥ垯璁や负鏄紓甯哥姸鎬�
+ MediaServer mediaServer = mediaServerService.getOne(sendRtpItem.getMediaServerId());
+ Boolean streamReady = mediaServerService.isStreamReady(mediaServer, sendRtpItem.getApp(), sendRtpItem.getStream());
+ if (streamReady) {
+ logger.warn("[璇煶瀵硅] 姝e湪璇煶骞挎挱锛屾棤娉曞紑鍚闊抽�氳瘽锛� {}", channelId);
+ event.call("姝e湪璇煶骞挎挱");
+ return;
+ } else {
+ stopAudioBroadcast(device.getDeviceId(), channelId);
+ }
+ }
+ }
+
+ SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(device.getDeviceId(), channelId, stream, null);
+ if (sendRtpItem != null) {
+ MediaServer mediaServer = mediaServerService.getOne(sendRtpItem.getMediaServerId());
+ Boolean streamReady = mediaServerService.isStreamReady(mediaServer, "rtp", sendRtpItem.getReceiveStream());
+ if (streamReady) {
+ logger.warn("[璇煶瀵硅] 杩涜涓細 {}", channelId);
+ event.call("璇煶瀵硅杩涜涓�");
+ return;
+ } else {
+ stopTalk(device, channelId);
+ }
+ }
+
+ talk(mediaServerItem, device, channelId, stream, (hookData) -> {
+ logger.info("[璇煶瀵硅] 鏀跺埌璁惧鍙戞潵鐨勬祦");
+ }, eventResult -> {
+ logger.warn("[璇煶瀵硅] 澶辫触锛寋}/{}, 閿欒鐮� {} {}", device.getDeviceId(), channelId, eventResult.statusCode, eventResult.msg);
+ event.call("澶辫触锛岄敊璇爜 " + eventResult.statusCode + ", " + eventResult.msg);
+ }, () -> {
+ logger.warn("[璇煶瀵硅] 澶辫触锛寋}/{} 瓒呮椂", device.getDeviceId(), channelId);
+ event.call("澶辫触锛岃秴鏃� ");
+ stopTalk(device, channelId);
+ }, errorMsg -> {
+ logger.warn("[璇煶瀵硅] 澶辫触锛寋}/{} {}", device.getDeviceId(), channelId, errorMsg);
+ event.call(errorMsg);
+ stopTalk(device, channelId);
+ });
+ }
+
+ private void stopTalk(Device device, String channelId) {
+ stopTalk(device, channelId, null);
+ }
+
+ @Override
+ public void stopTalk(Device device, String channelId, Boolean streamIsReady) {
+ logger.info("[璇煶瀵硅] 鍋滄锛� {}/{}", device.getDeviceId(), channelId);
+ SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(device.getDeviceId(), channelId, null, null);
+ if (sendRtpItem == null) {
+ logger.info("[璇煶瀵硅] 鍋滄澶辫触锛� 鏈壘鍒板彂閫佷俊鎭紝鍙兘宸茬粡鍋滄");
+ return;
+ }
+ // 鍋滄鍚戣澶囨帹娴�
+ String mediaServerId = sendRtpItem.getMediaServerId();
+ if (mediaServerId == null) {
+ return;
+ }
+
+ MediaServer mediaServer = mediaServerService.getOne(mediaServerId);
+
+ if (streamIsReady == null || streamIsReady) {
+ mediaServerService.stopSendRtp(mediaServer, sendRtpItem.getApp(), sendRtpItem.getStream(), sendRtpItem.getSsrc());
+ }
+
+ ssrcFactory.releaseSsrc(mediaServerId, sendRtpItem.getSsrc());
+
+ SsrcTransaction ssrcTransaction = streamSession.getSsrcTransaction(device.getDeviceId(), channelId, null, sendRtpItem.getStream());
+ if (ssrcTransaction != null) {
+ try {
+ cmder.streamByeCmd(device, channelId, sendRtpItem.getStream(), null);
+ } catch (InvalidArgumentException | ParseException | SipException | SsrcTransactionNotFoundException e) {
+ logger.info("[璇煶瀵硅] 鍋滄娑堟伅鍙戦�佸け璐ワ紝鍙兘宸茬粡鍋滄");
+ }
+ }
+ redisCatchStorage.deleteSendRTPServer(device.getDeviceId(), channelId,null, null);
}
@Override
@@ -1000,7 +1565,7 @@
if (inviteInfo != null) {
if (inviteInfo.getStreamInfo() != null) {
// 宸插瓨鍦ㄧ嚎鐩存帴鎴浘
- MediaServerItem mediaServerItemInuse = mediaServerService.getOne(inviteInfo.getStreamInfo().getMediaServerId());
+ MediaServer mediaServerItemInuse = mediaServerService.getOne(inviteInfo.getStreamInfo().getMediaServerId());
String streamUrl;
if (mediaServerItemInuse.getRtspPort() != 0) {
streamUrl = String.format("rtsp://127.0.0.1:%s/%s/%s", mediaServerItemInuse.getRtspPort(), "rtp", inviteInfo.getStreamInfo().getStream());
@@ -1010,7 +1575,7 @@
String path = "snap";
// 璇锋眰鎴浘
logger.info("[璇锋眰鎴浘]: " + fileName);
- zlmresTfulUtils.getSnap(mediaServerItemInuse, streamUrl, 15, 1, path, fileName);
+ mediaServerService.getSnap(mediaServerItemInuse, streamUrl, 15, 1, path, fileName);
File snapFile = new File(path + File.separator + fileName);
if (snapFile.exists()) {
errorCallback.run(InviteErrorCode.SUCCESS.getCode(), InviteErrorCode.SUCCESS.getMsg(), snapFile.getAbsoluteFile());
@@ -1021,19 +1586,41 @@
}
}
- MediaServerItem newMediaServerItem = getNewMediaServerItem(device);
+ MediaServer newMediaServerItem = getNewMediaServerItem(device);
play(newMediaServerItem, deviceId, channelId, null, (code, msg, data)->{
- if (code == InviteErrorCode.SUCCESS.getCode()) {
- InviteInfo inviteInfoForPlay = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId);
- if (inviteInfoForPlay != null && inviteInfoForPlay.getStreamInfo() != null) {
- getSnap(deviceId, channelId, fileName, errorCallback);
- }else {
- errorCallback.run(InviteErrorCode.FAIL.getCode(), InviteErrorCode.FAIL.getMsg(), null);
- }
- }else {
- errorCallback.run(InviteErrorCode.FAIL.getCode(), InviteErrorCode.FAIL.getMsg(), null);
- }
+ if (code == InviteErrorCode.SUCCESS.getCode()) {
+ InviteInfo inviteInfoForPlay = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId);
+ if (inviteInfoForPlay != null && inviteInfoForPlay.getStreamInfo() != null) {
+ getSnap(deviceId, channelId, fileName, errorCallback);
+ }else {
+ errorCallback.run(InviteErrorCode.FAIL.getCode(), InviteErrorCode.FAIL.getMsg(), null);
+ }
+ }else {
+ errorCallback.run(InviteErrorCode.FAIL.getCode(), InviteErrorCode.FAIL.getMsg(), null);
+ }
});
}
+ @Override
+ public void stopPlay(Device device, String channelId) {
+ InviteInfo inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId);
+ if (inviteInfo == null) {
+ throw new ControllerException(ErrorCode.ERROR100.getCode(), "鐐规挱鏈壘鍒�");
+ }
+ if (InviteSessionStatus.ok == inviteInfo.getStatus()) {
+ try {
+ logger.info("[鍋滄鐐规挱] {}/{}", device.getDeviceId(), channelId);
+ cmder.streamByeCmd(device, channelId, inviteInfo.getStream(), null, null);
+ } catch (InvalidArgumentException | SipException | ParseException | SsrcTransactionNotFoundException e) {
+ logger.error("[鍛戒护鍙戦�佸け璐 鍋滄鐐规挱锛� 鍙戦�丅YE: {}", e.getMessage());
+ throw new ControllerException(ErrorCode.ERROR100.getCode(), "鍛戒护鍙戦�佸け璐�: " + e.getMessage());
+ }
+ }
+ inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId);
+ storager.stopPlay(device.getDeviceId(), channelId);
+ channelService.stopPlay(device.getDeviceId(), channelId);
+ if (inviteInfo.getStreamInfo() != null) {
+ mediaServerService.closeRTPServer(inviteInfo.getStreamInfo().getMediaServerId(), inviteInfo.getStream());
+ }
+ }
}
--
Gitblit v1.8.0