Merge branch 'wvp-28181-2.0' into main-dev
# Conflicts: # src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java # src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java # src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java # src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerFactory.java # src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java # src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java # src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java # src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamCloseResponseListener.java # src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java
This commit is contained in:
@@ -27,7 +27,7 @@ public interface IPlayService {
|
||||
|
||||
void play(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId,
|
||||
ErrorCallback<Object> callback);
|
||||
SSRCInfo play(MediaServerItem mediaServerItem, String deviceId, String channelId, ErrorCallback<Object> callback);
|
||||
SSRCInfo play(MediaServerItem mediaServerItem, String deviceId, String channelId, String ssrc, ErrorCallback<Object> callback);
|
||||
|
||||
StreamInfo onPublishHandlerForPlay(MediaServerItem mediaServerItem, HookParam hookParam, String deviceId, String channelId);
|
||||
|
||||
|
||||
@@ -518,8 +518,12 @@ public class DeviceServiceImpl implements IDeviceService {
|
||||
if (!ObjectUtils.isEmpty(device.getMediaServerId())) {
|
||||
deviceInStore.setMediaServerId(device.getMediaServerId());
|
||||
}
|
||||
deviceInStore.setSdpIp(device.getSdpIp());
|
||||
deviceInStore.setCharset(device.getCharset());
|
||||
if (!ObjectUtils.isEmpty(device.getCharset())) {
|
||||
deviceInStore.setCharset(device.getCharset());
|
||||
}
|
||||
if (!ObjectUtils.isEmpty(device.getSdpIp())) {
|
||||
deviceInStore.setSdpIp(device.getSdpIp());
|
||||
}
|
||||
|
||||
// 目录订阅相关的信息
|
||||
if (device.getSubscribeCycleForCatalog() > 0) {
|
||||
@@ -550,10 +554,18 @@ public class DeviceServiceImpl implements IDeviceService {
|
||||
removeMobilePositionSubscribe(deviceInStore);
|
||||
}
|
||||
}
|
||||
// 坐标系变化,需要重新计算GCJ02坐标和WGS84坐标
|
||||
if (!deviceInStore.getGeoCoordSys().equals(device.getGeoCoordSys())) {
|
||||
updateDeviceChannelGeoCoordSys(device);
|
||||
if (deviceInStore.getGeoCoordSys() != null) {
|
||||
// 坐标系变化,需要重新计算GCJ02坐标和WGS84坐标
|
||||
if (!deviceInStore.getGeoCoordSys().equals(device.getGeoCoordSys())) {
|
||||
updateDeviceChannelGeoCoordSys(device);
|
||||
}
|
||||
}else {
|
||||
device.setGeoCoordSys("WGS84");
|
||||
}
|
||||
if (device.getCharset() == null) {
|
||||
device.setCharset("GB2312");
|
||||
}
|
||||
|
||||
// 更新redis
|
||||
redisCatchStorage.updateDevice(device);
|
||||
deviceMapper.updateCustom(device);
|
||||
|
||||
@@ -183,7 +183,7 @@ public class MediaServerServiceImpl implements IMediaServerService {
|
||||
}
|
||||
int rtpServerPort;
|
||||
if (mediaServerItem.isRtpEnable()) {
|
||||
rtpServerPort = zlmServerFactory.createRTPServer(mediaServerItem, streamId, ssrcCheck?Integer.parseInt(ssrc):0, port, onlyAuto, reUsePort, tcpMode);
|
||||
rtpServerPort = zlmServerFactory.createRTPServer(mediaServerItem, streamId, ssrcCheck?Integer.parseInt(ssrc):0, port, reUsePort, tcpMode);
|
||||
} else {
|
||||
rtpServerPort = mediaServerItem.getRtpProxyPort();
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ public class PlayServiceImpl implements IPlayService {
|
||||
private ZLMRESTfulUtils zlmresTfulUtils;
|
||||
|
||||
@Autowired
|
||||
private ZLMServerFactory zlmserverfactory;
|
||||
private ZLMServerFactory zlmServerFactory;
|
||||
|
||||
@Autowired
|
||||
private AssistRESTfulUtils assistRESTfulUtils;
|
||||
@@ -148,7 +148,7 @@ public class PlayServiceImpl implements IPlayService {
|
||||
|
||||
|
||||
@Override
|
||||
public SSRCInfo play(MediaServerItem mediaServerItem, String deviceId, String channelId, ErrorCallback<Object> callback) {
|
||||
public SSRCInfo play(MediaServerItem mediaServerItem, String deviceId, String channelId, String ssrc, ErrorCallback<Object> callback) {
|
||||
if (mediaServerItem == null) {
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到可用的zlm");
|
||||
}
|
||||
@@ -174,7 +174,7 @@ public class PlayServiceImpl implements IPlayService {
|
||||
String mediaServerId = streamInfo.getMediaServerId();
|
||||
MediaServerItem mediaInfo = mediaServerService.getOne(mediaServerId);
|
||||
|
||||
Boolean ready = zlmserverfactory.isStreamReady(mediaInfo, "rtp", streamId);
|
||||
Boolean ready = zlmServerFactory.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,
|
||||
@@ -445,18 +445,7 @@ public class PlayServiceImpl implements IPlayService {
|
||||
streamInfo);
|
||||
logger.info("[点播成功] deviceId: {}, channelId:{}, 码流类型:{}", device.getDeviceId(),
|
||||
device.isSwitchPrimarySubStream() ? "辅码流" : "主码流");
|
||||
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";
|
||||
// 请求截图
|
||||
logger.info("[请求截图]: " + fileName);
|
||||
zlmresTfulUtils.getSnap(mediaServerItemInuse, streamUrl, 15, 1, path, fileName);
|
||||
|
||||
snapOnPlay(mediaServerItemInuse, device.getDeviceId(), channelId, ssrcInfo.getStream());
|
||||
}, (event) -> {
|
||||
inviteInfo.setStatus(InviteSessionStatus.ok);
|
||||
|
||||
@@ -539,6 +528,7 @@ public class PlayServiceImpl implements IPlayService {
|
||||
InviteErrorCode.SUCCESS.getCode(),
|
||||
InviteErrorCode.SUCCESS.getMsg(),
|
||||
streamInfo);
|
||||
snapOnPlay(mediaServerItemInUse, device.getDeviceId(), channelId, stream);
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -614,11 +604,33 @@ public class PlayServiceImpl implements IPlayService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public StreamInfo onPublishHandlerForPlay(MediaServerItem mediaServerItem, HookParam hookParam, String deviceId, String channelId) {
|
||||
OnStreamChangedHookParam streamChangedHookParam = (OnStreamChangedHookParam) hookParam;
|
||||
StreamInfo streamInfo = onPublishHandler(mediaServerItem, streamChangedHookParam, deviceId, channelId);
|
||||
/**
|
||||
* 点播成功时调用截图.
|
||||
*
|
||||
* @param mediaServerItemInuse media
|
||||
* @param deviceId 设备 ID
|
||||
* @param channelId 通道 ID
|
||||
* @param stream ssrc
|
||||
*/
|
||||
private void snapOnPlay(MediaServerItem 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);
|
||||
} else {
|
||||
streamUrl = String.format("http://127.0.0.1:%s/%s/%s.live.mp4", mediaServerItemInuse.getHttpPort(), "rtp", stream);
|
||||
}
|
||||
String path = "snap";
|
||||
String fileName = deviceId + "_" + channelId + ".jpg";
|
||||
// 请求截图
|
||||
logger.info("[请求截图]: " + fileName);
|
||||
zlmresTfulUtils.getSnap(mediaServerItemInuse, streamUrl, 15, 1, path, fileName);
|
||||
}
|
||||
|
||||
private StreamInfo onPublishHandlerForPlay(MediaServerItem mediaServerItem, HookParam hookParam, String deviceId, String channelId) {
|
||||
StreamInfo streamInfo = null;
|
||||
Device device = redisCatchStorage.getDevice(deviceId);
|
||||
OnStreamChangedHookParam streamChangedHookParam = (OnStreamChangedHookParam)hookParam;
|
||||
streamInfo = onPublishHandler(mediaServerItem, streamChangedHookParam, deviceId, channelId);
|
||||
if (streamInfo != null) {
|
||||
DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId);
|
||||
if (deviceChannel != null) {
|
||||
@@ -1656,7 +1668,7 @@ public class PlayServiceImpl implements IPlayService {
|
||||
}
|
||||
|
||||
MediaServerItem newMediaServerItem = getNewMediaServerItem(device);
|
||||
play(newMediaServerItem, deviceId, channelId, (code, msg, data)->{
|
||||
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) {
|
||||
|
||||
@@ -4,14 +4,13 @@ import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.genersoft.iot.vmp.common.GeneralCallback;
|
||||
import com.genersoft.iot.vmp.common.StreamInfo;
|
||||
import com.genersoft.iot.vmp.conf.DynamicTask;
|
||||
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||
import com.genersoft.iot.vmp.conf.exception.ControllerException;
|
||||
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
||||
import com.genersoft.iot.vmp.gb28181.event.subscribe.catalog.CatalogEvent;
|
||||
import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
|
||||
import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
|
||||
import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory;
|
||||
import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange;
|
||||
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
|
||||
import com.genersoft.iot.vmp.media.zlm.dto.StreamProxyItem;
|
||||
import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
|
||||
@@ -41,6 +40,7 @@ import org.springframework.util.ObjectUtils;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* 视频代理业务
|
||||
@@ -86,6 +86,9 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
|
||||
@Autowired
|
||||
private ZlmHttpHookSubscribe hookSubscribe;
|
||||
|
||||
@Autowired
|
||||
private DynamicTask dynamicTask;
|
||||
|
||||
@Autowired
|
||||
DataSourceTransactionManager dataSourceTransactionManager;
|
||||
|
||||
@@ -124,9 +127,6 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
|
||||
port = mediaInfo.getRtspPort();
|
||||
schemaForUri = schema;
|
||||
}else if (schema.equalsIgnoreCase("flv")) {
|
||||
port = mediaInfo.getHttpPort();
|
||||
schemaForUri = "http";
|
||||
}else if (schema.equalsIgnoreCase("rtmp")) {
|
||||
port = mediaInfo.getRtmpPort();
|
||||
schemaForUri = schema;
|
||||
}else {
|
||||
@@ -155,17 +155,28 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
|
||||
return;
|
||||
}
|
||||
|
||||
HookSubscribeForStreamChange hookSubscribeForStreamChange = HookSubscribeFactory.on_stream_changed(param.getApp(), param.getStream(), true, "rtsp", mediaInfo.getId());
|
||||
hookSubscribe.addSubscribe(hookSubscribeForStreamChange, (mediaServerItem, response) -> {
|
||||
StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(
|
||||
mediaInfo, param.getApp(), param.getStream(), null, null);
|
||||
callback.run(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), streamInfo);
|
||||
});
|
||||
String talkKey = UUID.randomUUID().toString();
|
||||
dynamicTask.startCron(talkKey, ()->{
|
||||
StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStreamWithCheck(param.getApp(), param.getStream(), mediaInfo.getId(), false);
|
||||
if (streamInfo != null) {
|
||||
callback.run(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), streamInfo);
|
||||
}
|
||||
}, 1000);
|
||||
String delayTalkKey = UUID.randomUUID().toString();
|
||||
dynamicTask.startDelay(delayTalkKey, ()->{
|
||||
StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStreamWithCheck(param.getApp(), param.getStream(), mediaInfo.getId(), false);
|
||||
if (streamInfo != null) {
|
||||
callback.run(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), streamInfo);
|
||||
}else {
|
||||
dynamicTask.stop(talkKey);
|
||||
callback.run(ErrorCode.ERROR100.getCode(), "超时", null);
|
||||
}
|
||||
}, 5000);
|
||||
|
||||
if (param.isEnable()) {
|
||||
JSONObject jsonObject = addStreamProxyToZlm(param);
|
||||
if (jsonObject != null && jsonObject.getInteger("code") == 0) {
|
||||
hookSubscribe.removeSubscribe(hookSubscribeForStreamChange);
|
||||
dynamicTask.stop(talkKey);
|
||||
StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(
|
||||
mediaInfo, param.getApp(), param.getStream(), null, null);
|
||||
callback.run(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), streamInfo);
|
||||
@@ -292,10 +303,10 @@ public class StreamProxyServiceImpl implements IStreamProxyService {
|
||||
return null;
|
||||
}
|
||||
if ("default".equals(param.getType())){
|
||||
result = zlmresTfulUtils.addStreamProxy(mediaServerItem, param.getApp(), param.getStream(), param.getUrl(),
|
||||
result = zlmresTfulUtils.addStreamProxy(mediaServerItem, param.getApp(), param.getStream(), param.getUrl().trim(),
|
||||
param.isEnableAudio(), param.isEnableMp4(), param.getRtpType());
|
||||
}else if ("ffmpeg".equals(param.getType())) {
|
||||
result = zlmresTfulUtils.addFFmpegSource(mediaServerItem, param.getSrcUrl(), param.getDstUrl(),
|
||||
result = zlmresTfulUtils.addFFmpegSource(mediaServerItem, param.getSrcUrl().trim(), param.getDstUrl(),
|
||||
param.getTimeoutMs() + "", param.isEnableAudio(), param.isEnableMp4(),
|
||||
param.getFfmpegCmdKey());
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ public class RedisGbPlayMsgListener implements MessageListener {
|
||||
private RedisTemplate<Object, Object> redisTemplate;
|
||||
|
||||
@Autowired
|
||||
private ZLMServerFactory ZLMServerFactory;
|
||||
private ZLMServerFactory zlmServerFactory;
|
||||
|
||||
@Autowired
|
||||
private IMediaServerService mediaServerService;
|
||||
@@ -230,7 +230,7 @@ public class RedisGbPlayMsgListener implements MessageListener {
|
||||
param.put("pt", requestPushStreamMsg.getPt());
|
||||
param.put("use_ps", requestPushStreamMsg.isPs() ? "1" : "0");
|
||||
param.put("only_audio", requestPushStreamMsg.isOnlyAudio() ? "1" : "0");
|
||||
JSONObject jsonObject = ZLMServerFactory.startSendRtpStream(mediaInfo, param);
|
||||
JSONObject jsonObject = zlmServerFactory.startSendRtpStream(mediaInfo, param);
|
||||
// 回复消息
|
||||
responsePushStream(jsonObject, fromId, serial);
|
||||
}
|
||||
@@ -267,7 +267,7 @@ public class RedisGbPlayMsgListener implements MessageListener {
|
||||
return;
|
||||
}
|
||||
// 确定流是否在线
|
||||
Boolean streamReady = ZLMServerFactory.isStreamReady(mediaServerItem, content.getApp(), content.getStream());
|
||||
Boolean streamReady = zlmServerFactory.isStreamReady(mediaServerItem, content.getApp(), content.getStream());
|
||||
if (streamReady != null && streamReady) {
|
||||
logger.info("[回复推流信息] {}/{}", content.getApp(), content.getStream());
|
||||
responseSendItem(mediaServerItem, content, toId, serial);
|
||||
@@ -311,7 +311,7 @@ public class RedisGbPlayMsgListener implements MessageListener {
|
||||
* 将获取到的sendItem发送出去
|
||||
*/
|
||||
private void responseSendItem(MediaServerItem mediaServerItem, RequestSendItemMsg content, String toId, String serial) {
|
||||
SendRtpItem sendRtpItem = ZLMServerFactory.createSendRtpItem(mediaServerItem, content.getIp(),
|
||||
SendRtpItem sendRtpItem = zlmServerFactory.createSendRtpItem(mediaServerItem, content.getIp(),
|
||||
content.getPort(), content.getSsrc(), content.getPlatformId(),
|
||||
content.getApp(), content.getStream(), content.getChannelId(),
|
||||
content.getTcp(), content.getRtcp());
|
||||
|
||||
Reference in New Issue
Block a user