From f4f4fc53260eb67483dce406a963628273786a61 Mon Sep 17 00:00:00 2001
From: liusuyi <1951119284@qq.com>
Date: Sat, 30 May 2026 17:22:17 +0800
Subject: [PATCH] 优化
---
ard-modules/ard-modules-zlm/src/main/java/com/ard/zlm/service/impl/MediaServerServiceImpl.java | 522 +++++++++++++++++++++++++++++++++++++++++++++++++---------
1 files changed, 441 insertions(+), 81 deletions(-)
diff --git a/ard-modules/ard-modules-zlm/src/main/java/com/ard/zlm/service/impl/MediaServerServiceImpl.java b/ard-modules/ard-modules-zlm/src/main/java/com/ard/zlm/service/impl/MediaServerServiceImpl.java
index 61e765e..f43e858 100644
--- a/ard-modules/ard-modules-zlm/src/main/java/com/ard/zlm/service/impl/MediaServerServiceImpl.java
+++ b/ard-modules/ard-modules-zlm/src/main/java/com/ard/zlm/service/impl/MediaServerServiceImpl.java
@@ -8,11 +8,17 @@
import com.ard.common.core.domain.RtpServerParam;
import com.ard.common.core.enums.LiveStreamType;
import com.ard.common.core.utils.DateUtils;
+import com.ard.common.core.utils.file.FileMultipartFile;
import com.ard.gb28181.api.RemoteGb28181Service;
import com.ard.gb28181.api.domain.Device;
+import com.ard.gb28181.api.domain.GbChannelDTO;
import com.ard.qs.api.RemoteQsDeviceService;
import com.ard.qs.api.domain.QsDevice;
+import com.ard.system.api.RemoteFileService;
+import com.ard.system.api.domain.SysFile;
import com.ard.work.api.RemoteCameraService;
+import com.ard.work.api.RemoteChannelService;
+import com.ard.work.api.domian.ArdChannel;
import com.ard.zlm.api.domain.*;
import com.ard.zlm.api.hook.OriginType;
import com.ard.zlm.common.InviteErrorCode;
@@ -48,7 +54,12 @@
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.DigestUtils;
+import org.springframework.web.multipart.MultipartFile;
+import java.io.File;
+import java.io.FileInputStream;
+import java.nio.file.Files;
+import java.nio.file.Paths;
import java.util.*;
/**
@@ -62,7 +73,8 @@
@Slf4j
@Service
public class MediaServerServiceImpl implements IMediaServerService {
-
+ @Resource
+ private RemoteFileService remoteFileService;
@Resource
private MediaServerMapper mediaServerMapper;
@@ -95,6 +107,9 @@
@Resource
private RemoteQsDeviceService remoteQsDeviceService;
+
+ @Resource
+ private RemoteChannelService remoteChannelService;
@Resource
private ZLMRESTfulUtils zlmresTfulUtils;
@@ -626,19 +641,14 @@
callback.run(InviteErrorCode.FAIL.getCode(), "无可用的节点", null);
return;
}
-// R<QsDevice> devicer = remoteQsDeviceService.getQsDeviceInfo(streamPullPlay.getDeviceId(), SecurityConstants
-// .INNER);
-// if (devicer.getCode() != Constants.SUCCESS) {
-// throw new RuntimeException("获取设备信息失败" + streamPullPlay.getDeviceId());
-// }
-//
-// if (devicer.getData() == null) {
-// throw new RuntimeException("设备不存在" + streamPullPlay.getDeviceId());
-// }
-//
-// if ("OFFLINE".equals(devicer.getData().getDeviceStatus())) {
-// throw new RuntimeException("设备不在线" + streamPullPlay.getDeviceId());
-// }
+ R<ArdChannel> channel = remoteChannelService.getInfo(streamPullPlay.getChannelId(), SecurityConstants.INNER);
+ if (channel.getCode() != Constants.SUCCESS) {
+ throw new RuntimeException("获取通道信息失败" + streamPullPlay.getChannelId());
+ }
+
+ if (channel.getData() == null) {
+ throw new RuntimeException("通道不存在" + streamPullPlay.getChannelId());
+ }
StreamInfo stream = getStreamInfoByAppAndStreamWithCheck(streamPullPlay.getApp(), streamPullPlay.getStream(),
mediaServer.getId(), null, false);
@@ -670,13 +680,13 @@
callback.run(InviteErrorCode.SUCCESS.getCode(), InviteErrorCode.SUCCESS.getMsg(), streamInfo);
subscribe.removeSubscribe(rtpHook);
-// QsDevice qsDevice = new QsDevice();
-// qsDevice.setId(streamPullPlay.getDeviceId());
-// qsDevice.setSnap(filePath);
-// R<Boolean> r = remoteQsDeviceService.updateQsDevice(qsDevice, SecurityConstants.INNER);
-// if (r.getCode() != Constants.SUCCESS) {
-// throw new RuntimeException("更新设备失败");
-// }
+ ArdChannel ardChannel = new ArdChannel();
+ ardChannel.setId(streamPullPlay.getChannelId());
+ ardChannel.setSnapUrl(filePath);
+ R<Boolean> r = remoteChannelService.update(ardChannel, SecurityConstants.INNER);
+ if (r.getCode() != Constants.SUCCESS) {
+ throw new RuntimeException("更新设备失败");
+ }
});
IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType());
@@ -688,16 +698,16 @@
}
String key = mediaNodeServerService.startProxy(mediaServer, streamPullPlay);
-// QsDevice qsDevice = new QsDevice();
-// qsDevice.setId(streamPullPlay.getDeviceId());
-// qsDevice.setStreamKey(key);
-// qsDevice.setMediaServerId(mediaServer.getId());
-// qsDevice.setStreamStatus("1");
-// R<Boolean> r = remoteQsDeviceService.updateQsDevice(qsDevice, SecurityConstants.INNER);
-// if (r.getCode() != Constants.SUCCESS) {
-// log.error("更新设备失败");
-// callback.run(InviteErrorCode.FAIL.getCode(), "更新设备失败", null);
-// }
+ ArdChannel ardChannel = new ArdChannel();
+ ardChannel.setId(streamPullPlay.getChannelId());
+ ardChannel.setStreamKey(key);
+ ardChannel.setMediaServerId(mediaServer.getId());
+ //ardChannel.setStreamStatus("1");
+ R<Boolean> r = remoteChannelService.update(ardChannel, SecurityConstants.INNER);
+ if (r.getCode() != Constants.SUCCESS) {
+ log.error("更新设备失败");
+ callback.run(InviteErrorCode.FAIL.getCode(), "更新设备失败", null);
+ }
}
/**
@@ -769,17 +779,39 @@
stopProxy(mediaServer, streamPullPlay.getStreamKey());
- QsDevice qsDevice = new QsDevice();
- qsDevice.setId(streamPullPlay.getDeviceId());
- qsDevice.setStreamKey("");
- qsDevice.setMediaServerId("");
- qsDevice.setStreamStatus("0");
- R<Boolean> r = remoteQsDeviceService.updateQsDevice(qsDevice, SecurityConstants.INNER);
+ ArdChannel ardChannel = new ArdChannel();
+ ardChannel.setId(streamPullPlay.getChannelId());
+ ardChannel.setStreamKey("");
+ ardChannel.setMediaServerId("");
+ // ardChannel.setStreamStatus("0");
+ R<Boolean> r = remoteChannelService.update(ardChannel, SecurityConstants.INNER);
if (r.getCode() != Constants.SUCCESS) {
throw new RuntimeException("更新设备失败");
}
}
+ /**
+ * 点播成功时调用截图
+ *
+ * @param mediaServer media
+ * @param app app
+ * @param stream 流id
+ */
+ //@Override
+// public String snapOnPlay1(ZlmMediaServer mediaServer, String app, String stream) {
+// String fileName = app + "-" + stream + ".jpg";
+// // 请求截图
+// log.info("[请求截图]: " + fileName);
+//
+// IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType());
+// if (mediaNodeServerService == null) {
+// log.info("[getSnap] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType());
+// throw new RuntimeException("[getSnap] 失败, mediaServer的类型: " + mediaServer.getType() + ",未找到对应的实现类");
+// }
+// String filePath = fileDomain + filePrefix + "/snap/" + fileName;
+// mediaNodeServerService.getSnap(mediaServer, app, stream, 30, 300, this.filePath + "/snap", fileName);
+// return filePath;
+// }
/**
* 点播成功时调用截图
*
@@ -798,11 +830,53 @@
log.info("[getSnap] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType());
throw new RuntimeException("[getSnap] 失败, mediaServer的类型: " + mediaServer.getType() + ",未找到对应的实现类");
}
- String filePath = fileDomain + filePrefix + "/snap/" + fileName;
- mediaNodeServerService.getSnap(mediaServer, app, stream, 15, 1, this.filePath + "/snap", fileName);
- return filePath;
- }
+ // 生成临时文件路径(用于 FFmpeg 截图)
+ String tempDir = System.getProperty("java.io.tmpdir") + "/snap_temp/";
+ File tempDirFile = new File(tempDir);
+ if (!tempDirFile.exists()) {
+ tempDirFile.mkdirs();
+ }
+ String tempFilePath = tempDir + fileName;
+
+ try {
+ // 1. 获取截图到临时文件
+ mediaNodeServerService.getSnap(mediaServer, app, stream, 30, 300, tempDir, fileName);
+ // 2. 检查临时文件是否存在
+ File tempFile = new File(tempFilePath);
+ if (!tempFile.exists()) {
+ log.error("[截图失败] 临时文件不存在: {}", tempFilePath);
+ return null;
+ }
+
+ // 3. 使用 FileMultipartFile 转换为 MultipartFile
+ MultipartFile multipartFile = new FileMultipartFile(
+ tempFile,
+ fileName,
+ "image/jpeg"
+ );
+
+ // 3. 调用文件上传接口,上传到 MinIO(bucketName 可以固定为 "snap" 或动态传入)
+ R<SysFile> result = remoteFileService.upload(multipartFile, "snap");
+
+ // 4. 清理临时文件
+ Files.deleteIfExists(Paths.get(tempFilePath));
+
+ // 5. 返回 URL
+ if (result.getCode() == Constants.SUCCESS && result.getData() != null) {
+ String url = result.getData().getUrl();
+ log.info("[截图上传成功] URL: {}", url);
+ return url;
+ } else {
+ log.error("[截图上传失败] {}", result.getMsg());
+ return null;
+ }
+
+ } catch (Exception e) {
+ log.error("[截图失败] ", e);
+ return null;
+ }
+ }
/**
* 获取截图
*
@@ -1421,12 +1495,12 @@
/**
* 开始播放
*
- * @param device 设备信息
+ * @param ardChannel 通道信息
* @param record 是否录制
* @param callback 回调
*/
@Override
- public void play(QsDevice device, Boolean record, ErrorCallback<StreamInfo> callback) {
+ public void play(ArdChannel ardChannel, Boolean record, ErrorCallback<StreamInfo> callback) {
ZlmMediaServer mediaServer = getMediaServerForMinimumLoad(null);
if (mediaServer == null) {
@@ -1435,57 +1509,57 @@
}
// 播放海康sdk/播放海康isup/播放大华sdk
- if (LiveStreamType.HIK_SDK.getCode().equals(device.getType()) || LiveStreamType.HIK_ISUP.getCode().equals(device.getType()) || LiveStreamType.DAHUA_SDK.getCode().equals(device.getType())) {
- RTPServerParam rtpServerParam = new RTPServerParam();
- if (LiveStreamType.HIK_SDK.getCode().equals(device.getType())) {
- rtpServerParam.setApp("haikang");
- } else if (LiveStreamType.HIK_ISUP.getCode().equals(device.getType())) {
- rtpServerParam.setApp("haikang_isup");
- } else if (LiveStreamType.DAHUA_SDK.getCode().equals(device.getType())) {
- rtpServerParam.setApp("dahua");
- }
-
- rtpServerParam.setStreamId(device.getDeviceCode());
- rtpServerParam.setTcpMode(0);
- rtpServerParam.setType(device.getType());
- rtpServerParam.setId(device.getId());
- System.out.println(rtpServerParam);
- play(mediaServer, rtpServerParam, device, null, callback);
+ if (LiveStreamType.HIK_SDK.getCode().equals(ardChannel.getType()) || LiveStreamType.HIK_ISUP.getCode().equals(ardChannel.getType()) || LiveStreamType.DAHUA_SDK.getCode().equals(ardChannel.getType())) {
+// RTPServerParam rtpServerParam = new RTPServerParam();
+// if (LiveStreamType.HIK_SDK.getCode().equals(device.getType())) {
+// rtpServerParam.setApp("haikang");
+// } else if (LiveStreamType.HIK_ISUP.getCode().equals(device.getType())) {
+// rtpServerParam.setApp("haikang_isup");
+// } else if (LiveStreamType.DAHUA_SDK.getCode().equals(device.getType())) {
+// rtpServerParam.setApp("dahua");
+// }
+//
+// rtpServerParam.setStreamId(device.getDeviceCode());
+// rtpServerParam.setTcpMode(0);
+// rtpServerParam.setType(device.getType());
+// rtpServerParam.setId(device.getId());
+// System.out.println(rtpServerParam);
+// play(mediaServer, rtpServerParam, device, null, callback);
}
// rtsp/rtmp/flv/hls/onvif
- if (LiveStreamType.RTSP.getCode().equals(device.getType()) || LiveStreamType.RTMP.getCode().equals(device.getType()) || LiveStreamType.FLV.getCode().equals(device.getType()) || LiveStreamType.HLS.getCode().equals(device.getType()) || LiveStreamType.ONVIF.getCode().equals(device.getType())) {
+ if (LiveStreamType.RTSP.getCode().equals(ardChannel.getType()) || LiveStreamType.RTMP.getCode().equals(ardChannel.getType()) || LiveStreamType.FLV.getCode().equals(ardChannel.getType()) || LiveStreamType.HLS.getCode().equals(ardChannel.getType()) || LiveStreamType.ONVIF.getCode().equals(ardChannel.getType())) {
StreamPullPlay streamPullPlay = new StreamPullPlay();
- streamPullPlay.setDeviceId(device.getId());
- streamPullPlay.setStream(device.getDeviceCode());
- streamPullPlay.setUrl(device.getLiveAddress());
- streamPullPlay.setEnable_mp4("1".equals(device.getEnableMp4()));
- streamPullPlay.setEnable_audio("1".equals(device.getEnableAudio()));
+ streamPullPlay.setChannelId(ardChannel.getId());
+ streamPullPlay.setStream(ardChannel.getId());
+ streamPullPlay.setUrl(ardChannel.getLiveAddress());
+ streamPullPlay.setEnable_mp4(false);
+ streamPullPlay.setEnable_audio(true);
streamPullPlay.setRtp_type("1");
streamPullPlay.setTimeOut(10);
- if (LiveStreamType.RTSP.getCode().equals(device.getType())) {
+ if (LiveStreamType.RTSP.getCode().equals(ardChannel.getType())) {
streamPullPlay.setApp("rtsp");
- } else if (LiveStreamType.RTMP.getCode().equals(device.getType())) {
- streamPullPlay.setApp("rtmp");
- } else if (LiveStreamType.FLV.getCode().equals(device.getType())) {
- streamPullPlay.setApp("flv");
- if ("ws".equals(device.getFlvType())) {
- streamPullPlay.setUrl(convertWsToHttp(device.getLiveAddress()));
- }
- } else if (LiveStreamType.HLS.getCode().equals(device.getType())) {
- streamPullPlay.setApp("hls");
- } else if (LiveStreamType.ONVIF.getCode().equals(device.getType())) {
- streamPullPlay.setApp("onvif");
- }
+ } else if (LiveStreamType.RTMP.getCode().equals(ardChannel.getType())) {
+ streamPullPlay.setApp("rtmp");}
+// } else if (LiveStreamType.FLV.getCode().equals(device.getType())) {
+// streamPullPlay.setApp("flv");
+// if ("ws".equals(device.getFlvType())) {
+// streamPullPlay.setUrl(convertWsToHttp(device.getLiveAddress()));
+// }
+// } else if (LiveStreamType.HLS.getCode().equals(device.getType())) {
+// streamPullPlay.setApp("hls");
+// } else if (LiveStreamType.ONVIF.getCode().equals(device.getType())) {
+// streamPullPlay.setApp("onvif");
+// }
streamPullPlay(streamPullPlay, callback);
}
// 视频文件
- if (LiveStreamType.VIDEO_FILE.getCode().equals(device.getType())) {
- loadRecord(device.getId(), callback);
- }
+// if (LiveStreamType.VIDEO_FILE.getCode().equals(device.getType())) {
+// loadRecord(device.getId(), callback);
+// }
}
/**
@@ -1738,6 +1812,101 @@
}
}
+ /**
+ * gb28181 播放(基于GbDevice,不依赖QS)
+ */
+ @Override
+ public void startGb28181PlayByGbChannel(GbChannelDTO gbChannelDTO, Device gbDevice, ErrorCallback<StreamInfo> callback) {
+ ZlmMediaServer mediaServer = getMediaServerForMinimumLoad(null);
+
+ if (mediaServer == null) {
+ callback.run(InviteErrorCode.FAIL.getCode(), "无可用的节点", null);
+ return;
+ }
+
+ String streamMode = gbChannelDTO.getStreamMode() != null
+ ? gbChannelDTO.getStreamMode() : gbDevice.getStreamMode();
+ int tcpMode = streamMode.equals("TCP-ACTIVE") ? 2
+ : (streamMode.equals("TCP-PASSIVE") ? 1 : 0);
+
+ RTPServerParam rtpServerParam = new RTPServerParam();
+ rtpServerParam.setApp("gb28181");
+ rtpServerParam.setMediaServer(mediaServer);
+ rtpServerParam.setType(LiveStreamType.GB28181.getCode());
+ rtpServerParam.setStreamId(gbChannelDTO.getDeviceCode());
+ rtpServerParam.setTcpMode(tcpMode);
+ rtpServerParam.setId(gbChannelDTO.getId());
+
+ startGb28181PlayFunByGbChannel(mediaServer, gbChannelDTO, gbDevice, rtpServerParam, null, callback);
+ }
+
+ /**
+ * gb28181 停止点播(基于GbDevice,不依赖QS)
+ */
+ @Override
+ public void stopGb28181PlayByGbChannel(InviteSessionType type, GbChannelDTO gbChannelDTO, Device device, String stream) {
+ InviteInfo inviteInfo = inviteStreamService.getInviteInfo(type, gbChannelDTO.getId(), stream);
+ if (inviteInfo == null) {
+ if (type == InviteSessionType.PLAY) {
+ GbChannelDTO update = new GbChannelDTO();
+ update.setId(gbChannelDTO.getId());
+ update.setStreamKey("");
+ update.setMediaServerId("");
+ update.setStreamStatus("0");
+ R<Boolean> r = remoteGb28181Service.updateGbChannelStream(update, SecurityConstants.INNER);
+ if (r.getCode() != Constants.SUCCESS) {
+ throw new RuntimeException("更新GbDevice失败");
+ }
+ }
+ return;
+ }
+ inviteStreamService.removeInviteInfo(inviteInfo);
+ if (InviteSessionStatus.ok == inviteInfo.getStatus()) {
+ try {
+ log.info("[停止点播/回放/下载] {}/{}", gbChannelDTO.getGbDeviceId(), gbChannelDTO.getGbChannelId());
+
+ RtpServerParam rtpServer = new RtpServerParam();
+ rtpServer.setApp("gb28181");
+ rtpServer.setStream(gbChannelDTO.getDeviceCode());
+ rtpServer.setGbDeviceId(gbChannelDTO.getGbDeviceId());
+ rtpServer.setGbChannelId(gbChannelDTO.getGbChannelId());
+
+ R<Void> r = remoteGb28181Service.streamByeCmd(rtpServer, SecurityConstants.INNER);
+ if (r.getCode() != Constants.SUCCESS) {
+ log.error("[命令发送失败] 停止点播/回放/下载, deviceId:{}", gbChannelDTO.getGbDeviceId());
+ throw new RuntimeException("[命令发送失败] 停止点播/回放/下载, deviceId:" + gbChannelDTO.getGbDeviceId());
+ }
+ } catch (Exception e) {
+ log.error("[命令发送失败] 停止点播/回放/下载, 发送BYE: {}", e.getMessage());
+ throw new RuntimeException("命令发送失败: " + e.getMessage());
+ }
+ }
+
+ if (inviteInfo.getType() == InviteSessionType.PLAY) {
+ GbChannelDTO update = new GbChannelDTO();
+ update.setId(gbChannelDTO.getId());
+ update.setStreamKey("");
+ update.setMediaServerId("");
+ update.setStreamStatus("0");
+ R<Boolean> r = remoteGb28181Service.updateGbChannelStream(update, SecurityConstants.INNER);
+ if (r.getCode() != Constants.SUCCESS) {
+ throw new RuntimeException("更新GbDevice失败");
+ }
+ }
+
+ ZlmMediaServer mediaServer = null;
+ if (inviteInfo.getStreamInfo() != null) {
+ mediaServer = inviteInfo.getStreamInfo().getMediaServer();
+ } else {
+ mediaServer = getOne(inviteInfo.getMediaServerId());
+ }
+
+ if (mediaServer != null && inviteInfo.getSsrcInfo() != null) {
+ closeRTPServer(mediaServer, inviteInfo.getSsrcInfo().getStream());
+ ssrcFactory.releaseSsrc(inviteInfo.getMediaServerId(), inviteInfo.getSsrcInfo().getSsrc());
+ }
+ }
+
/**
* 开启国标28181播放
@@ -1956,6 +2125,197 @@
}
/**
+ * 开启国标28181播放(基于GbDevice,不依赖QS)
+ */
+ private SSRCInfo startGb28181PlayFunByGbChannel(ZlmMediaServer mediaServer, GbChannelDTO gbChannelDTO,
+ Device gbDevice, RTPServerParam rtpServerParam,
+ String ssrc, ErrorCallback<StreamInfo> callback) {
+ // 获取点播的状态信息
+ InviteInfo inviteInfoInCatch = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY,
+ gbChannelDTO.getId());
+ if (inviteInfoInCatch != null) {
+ if (inviteInfoInCatch.getStreamInfo() == null) {
+ ssrcFactory.releaseSsrc(mediaServer.getId(), null);
+ inviteStreamService.once(InviteSessionType.PLAY, gbChannelDTO.getId(), null, callback);
+ log.info("[点播开始] 已经请求中,等待结果, deviceId: {}, channel: {}", gbChannelDTO.getId(), gbChannelDTO.getId());
+ return inviteInfoInCatch.getSsrcInfo();
+ } else {
+ StreamInfo streamInfo = inviteInfoInCatch.getStreamInfo();
+ String streamId = streamInfo.getStream();
+ if (streamId == null) {
+ callback.run(InviteErrorCode.ERROR_FOR_CATCH_DATA.getCode(), "点播失败, redis缓存streamId等于null", null);
+ inviteStreamService.call(InviteSessionType.PLAY, gbChannelDTO.getId(), null,
+ InviteErrorCode.ERROR_FOR_CATCH_DATA.getCode(), "点播失败, redis缓存streamId等于null", null);
+ return inviteInfoInCatch.getSsrcInfo();
+ }
+ ZlmMediaServer mediaInfo = streamInfo.getMediaServer();
+ Boolean ready = isStreamReady(mediaInfo, rtpServerParam.getApp(), streamId);
+ if (ready != null && ready) {
+ if (callback != null) {
+ callback.run(InviteErrorCode.SUCCESS.getCode(), InviteErrorCode.SUCCESS.getMsg(), streamInfo);
+ }
+ inviteStreamService.call(InviteSessionType.PLAY, gbChannelDTO.getId(), null,
+ InviteErrorCode.SUCCESS.getCode(), InviteErrorCode.SUCCESS.getMsg(), streamInfo);
+ log.info("[点播已存在] 直接返回, 设备编号: {}", gbChannelDTO.getId());
+ return inviteInfoInCatch.getSsrcInfo();
+ } else {
+ inviteStreamService.once(InviteSessionType.PLAY, gbChannelDTO.getId(), null, callback);
+ RTPServerParam stopRtp = new RTPServerParam();
+ stopRtp.setId(gbChannelDTO.getId());
+ stopRtp.setType(rtpServerParam.getType());
+ stopRtp.setStreamId(rtpServerParam.getStreamId());
+ stopRtpPlay(stopRtp);
+ inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, gbChannelDTO.getId());
+ }
+ }
+ }
+
+ rtpServerParam.setMediaServer(mediaServer);
+ if (rtpServerParam.getPresetSsrc() != null) {
+ ssrc = rtpServerParam.getPresetSsrc();
+ } else {
+ if (rtpServerParam.isPlayback()) {
+ ssrc = ssrcFactory.getPlayBackSsrc(mediaServer.getId());
+ } else {
+ ssrc = ssrcFactory.getPlaySsrc(mediaServer.getId());
+ }
+ }
+ rtpServerParam.setSsrc(ssrc);
+
+ SSRCInfo ssrcInfo = receiveRtpServerService.openRTPServer(rtpServerParam, (code, msg, result) -> {
+ if (code == InviteErrorCode.SUCCESS.getCode() && result != null && result.getHookData() != null) {
+ log.info("[创建RTP服务器] 成功, code: {}, msg: {}, result: {}", code, msg, result);
+ StreamInfo streamInfo = getStreamInfoByAppAndStream(mediaServer, rtpServerParam.getApp(),
+ rtpServerParam.getStreamId(), result.getHookData().getMediaInfo());
+ if (streamInfo == null) {
+ if (callback != null) {
+ callback.run(InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getCode(),
+ InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getMsg(), null);
+ }
+ inviteStreamService.call(InviteSessionType.PLAY, gbChannelDTO.getId(), null,
+ InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getCode(),
+ InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getMsg(), null);
+ if (result != null && result.getSsrcInfo() != null) {
+ closeRTPServer(mediaServer, result.getSsrcInfo().getStream());
+ ssrcFactory.releaseSsrc(mediaServer.getId(), result.getSsrcInfo().getSsrc());
+ }
+ return;
+ }
+ if (callback != null) {
+ callback.run(InviteErrorCode.SUCCESS.getCode(), InviteErrorCode.SUCCESS.getMsg(), streamInfo);
+ inviteStreamService.call(InviteSessionType.PLAY, gbChannelDTO.getId(), null,
+ InviteErrorCode.SUCCESS.getCode(), InviteErrorCode.SUCCESS.getMsg(), streamInfo);
+
+ InviteInfo inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(
+ InviteSessionType.PLAY, gbChannelDTO.getId());
+ if (inviteInfo != null) {
+ inviteInfo.setStatus(InviteSessionStatus.ok);
+ inviteInfo.setStreamInfo(streamInfo);
+ inviteStreamService.updateInviteInfo(inviteInfo);
+ }
+
+ String filePath = snapOnPlay(streamInfo.getMediaServer(), streamInfo.getApp(),
+ streamInfo.getStream());
+
+ // 更新GbDevice流状态
+ GbChannelDTO update = new GbChannelDTO();
+ update.setId(rtpServerParam.getId());
+ update.setStreamKey(rtpServerParam.getStreamId());
+ update.setMediaServerId(mediaServer.getId());
+ update.setStreamStatus("1");
+ update.setSnap(filePath);
+ R<Boolean> r = remoteGb28181Service.updateGbChannelStream(update, SecurityConstants.INNER);
+ if (r.getCode() != Constants.SUCCESS) {
+ throw new RuntimeException("更新GbDevice失败");
+ }
+ }
+ } else {
+ log.error("[创建RTP服务器] 失败, code: {}, msg: {}, result: {}", code, msg, result);
+ if (callback != null) {
+ callback.run(code, msg, null);
+ }
+ inviteStreamService.call(InviteSessionType.PLAY, gbChannelDTO.getId(), null, code, msg, null);
+ inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, gbChannelDTO.getId());
+ if (result != null && result.getSsrcInfo() != null) {
+ closeRTPServer(mediaServer, result.getSsrcInfo().getStream());
+ ssrcFactory.releaseSsrc(mediaServer.getId(), result.getSsrcInfo().getSsrc());
+ }
+ }
+ });
+
+ if (ssrcInfo == null || ssrcInfo.getPort() <= 0) {
+ log.info("[点播端口/SSRC]获取失败,设备编号:{}, 通道编号:{}, ssrcInfo: {}", gbChannelDTO.getId(), gbChannelDTO.getId(), ssrcInfo);
+ if (rtpServerParam.getPresetSsrc() == null) {
+ ssrcFactory.releaseSsrc(mediaServer.getId(), ssrc);
+ }
+ callback.run(InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(), "获取端口或者ssrc失败", null);
+ inviteStreamService.call(InviteSessionType.PLAY, gbChannelDTO.getId(), null,
+ InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(),
+ InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getMsg(), null);
+ return null;
+ }
+
+ int port = ssrcInfo.getPort();
+ String ip = mediaServer.getIp();
+ RtpServerParam rtpServer = new RtpServerParam();
+ rtpServer.setPort(port);
+ rtpServer.setIp(ip);
+ rtpServer.setId(rtpServerParam.getId());
+ rtpServer.setSsrc(rtpServerParam.getSsrc());
+ rtpServer.setGbDeviceId(gbDevice.getDeviceId());
+ rtpServer.setGbChannelId(gbChannelDTO.getGbChannelId());
+ rtpServer.setStreamMode(gbDevice.getStreamMode());
+ rtpServer.setMediaServerId(mediaServer.getId());
+ rtpServer.setApp(rtpServerParam.getApp());
+ rtpServer.setStream(rtpServerParam.getStreamId());
+
+ log.info("[国标28181点播开始(基于GbDevice)] ===============================");
+ log.info("[国标28181] GbDeviceId: {}, 设备国标ID: {}, 通道国标ID: {}", gbChannelDTO.getId(),
+ gbDevice.getDeviceId(), gbChannelDTO.getGbChannelId());
+ log.info("[国标28181] 流模式: {}, ZLM tcpMode: {}, ssrcCheck: {}", gbDevice.getStreamMode(),
+ rtpServerParam.getTcpMode(), rtpServerParam.isSsrcCheck());
+ log.info("[国标28181] ZLM媒体服务器IP: {}, 收流端口: {}, 流ID: {}, SSRC: {}", ip, port, ssrcInfo.getStream(),
+ ssrcInfo.getSsrc());
+ log.info("[国标28181] =======================================");
+
+ InviteInfo inviteInfo = InviteInfo.getInviteInfo(gbChannelDTO.getId().toString(), gbChannelDTO.getId(),
+ ssrcInfo.getStream(), ssrcInfo, mediaServer.getId(), mediaServer.getSdpIp(), ssrcInfo.getPort(),
+ gbDevice.getStreamMode(), InviteSessionType.PLAY, InviteSessionStatus.ready,
+ userSetting.getRecordSip());
+
+ if ("1".equals(gbChannelDTO.getEnableMp4())) {
+ inviteInfo.setRecord(true);
+ }
+
+ inviteStreamService.updateInviteInfo(inviteInfo);
+
+ R<Void> r = remoteGb28181Service.playStreamCmd(rtpServer, SecurityConstants.INNER);
+
+ if (r.getCode() != Constants.SUCCESS) {
+ log.info("[点播失败]{}:{} deviceId: {}, channelId:{}", r.getCode(), r.getMsg(),
+ gbChannelDTO.getGbDeviceId(), gbChannelDTO.getGbChannelId());
+ inviteInfo = inviteStreamService.getInviteInfo(InviteSessionType.PLAY, gbChannelDTO.getId(),
+ rtpServerParam.getStreamId());
+ if (inviteInfo != null) {
+ inviteStreamService.removeInviteInfo(inviteInfo);
+ if (inviteInfo.getSsrcInfo() != null) {
+ ssrcFactory.releaseSsrc(mediaServer.getId(), inviteInfo.getSsrcInfo().getSsrc());
+ }
+ }
+ closeRTPServer(mediaServer, ssrcInfo.getStream());
+ ssrcFactory.releaseSsrc(mediaServer.getId(), ssrcInfo.getSsrc());
+ if (callback != null) {
+ callback.run(r.getCode(), r.getMsg(), null);
+ }
+ inviteStreamService.call(InviteSessionType.PLAY, gbChannelDTO.getId(), null,
+ r.getCode(), r.getMsg(), null);
+ inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, gbChannelDTO.getId());
+ return ssrcInfo;
+ }
+ return ssrcInfo;
+ }
+
+ /**
* 将 WebSocket 协议地址转换为 HTTP 协议地址
* ws:// -> http://
* wss:// -> https://
--
Gitblit v1.9.3