支持国标级联录像下载

结构优化
648540858 2024-01-30 20:46:47 +08:00
parent 02c0a45f11
commit a412f9c2d4
5 changed files with 56 additions and 28 deletions

View File

@ -344,7 +344,7 @@ public class GB28181ResourceServiceImpl implements IResourceService {
String startTimeStr = DateUtil.formatter.format(startTime); String startTimeStr = DateUtil.formatter.format(startTime);
String endTimeStr = DateUtil.formatter.format(stopTime); String endTimeStr = DateUtil.formatter.format(stopTime);
String stream = checkResult.device.getDeviceId() + "_" + checkResult.channel.getChannelId() + "_" + String stream = checkResult.device.getDeviceId() + "_" + checkResult.channel.getChannelId() + "_" +
startTimeStr + "_" + endTimeStr; DateUtil.urlFormatter.format(startTime) + "_" + DateUtil.urlFormatter.format(stopTime);
MediaServerItem mediaServerItem = playService.getNewMediaServerItem(checkResult.device); MediaServerItem mediaServerItem = playService.getNewMediaServerItem(checkResult.device);
SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, stream, null, SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, stream, null,
checkResult.device.isSsrcCheck(), true, 0, false, checkResult.device.getStreamModeForParam()); checkResult.device.isSsrcCheck(), true, 0, false, checkResult.device.getStreamModeForParam());
@ -360,8 +360,34 @@ public class GB28181ResourceServiceImpl implements IResourceService {
} }
@Override @Override
public void startDownload(CommonGbChannel channel, Instant startTime, Instant stopTime, Integer downloadSpeed, IResourcePlayCallback playCallback) { public void startDownload(CommonGbChannel commonGbChannel, Instant startTime, Instant stopTime, Integer downloadSpeed, IResourcePlayCallback callback) {
assert callback != null;
CheckCommonGbChannelResult checkResult = checkCommonGbChannel(commonGbChannel);
if (checkResult.errorMsg != null) {
callback.call(commonGbChannel, null, ErrorCode.SUCCESS.getCode(), checkResult.errorMsg, null);
return;
}
if (checkResult.device == null || checkResult.channel == null) {
callback.call(commonGbChannel, null, ErrorCode.SUCCESS.getCode(), "设备获取失败", null);
return;
}
String startTimeStr = DateUtil.formatter.format(startTime);
String endTimeStr = DateUtil.formatter.format(stopTime);
String stream = checkResult.device.getDeviceId() + "_" + checkResult.channel.getChannelId() + "_" +
DateUtil.urlFormatter.format(startTime) + "_" + DateUtil.urlFormatter.format(stopTime);
MediaServerItem mediaServerItem = playService.getNewMediaServerItem(checkResult.device);
SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, stream, null,
checkResult.device.isSsrcCheck(), true, 0, false, checkResult.device.getStreamModeForParam());
playService.download(mediaServerItem, ssrcInfo, checkResult.channel.getDeviceId(), checkResult.channel.getChannelId(),
startTimeStr, endTimeStr, downloadSpeed, (code, msg, data) -> {
if (code == InviteErrorCode.SUCCESS.getCode()) {
StreamInfo streamInfo = (StreamInfo)data;
callback.call(commonGbChannel, mediaServerItem, ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), streamInfo);
}else {
callback.call(commonGbChannel, null, code, msg, null);
}
});
} }
static class CheckCommonGbChannelResult { static class CheckCommonGbChannelResult {

View File

@ -18,7 +18,6 @@ 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.HookSubscribeFactory;
import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange;
import com.genersoft.iot.vmp.service.IInviteStreamService; import com.genersoft.iot.vmp.service.IInviteStreamService;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.IVideoManagerStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
import gov.nist.javax.sip.message.SIPRequest; import gov.nist.javax.sip.message.SIPRequest;
import org.dom4j.Element; import org.dom4j.Element;
@ -34,7 +33,6 @@ import javax.sip.SipException;
import javax.sip.header.CallIdHeader; import javax.sip.header.CallIdHeader;
import javax.sip.message.Response; import javax.sip.message.Response;
import java.text.ParseException; import java.text.ParseException;
import java.util.List;
import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText; import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
@ -44,7 +42,7 @@ import static com.genersoft.iot.vmp.gb28181.utils.XmlUtil.getText;
@Component @Component
public class MediaStatusNotifyMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler { public class MediaStatusNotifyMessageHandler extends SIPRequestProcessorParent implements InitializingBean, IMessageHandler {
private Logger logger = LoggerFactory.getLogger(MediaStatusNotifyMessageHandler.class); private final Logger logger = LoggerFactory.getLogger(MediaStatusNotifyMessageHandler.class);
private final String cmdType = "MediaStatus"; private final String cmdType = "MediaStatus";
@Autowired @Autowired
@ -56,18 +54,12 @@ public class MediaStatusNotifyMessageHandler extends SIPRequestProcessorParent i
@Autowired @Autowired
private SIPCommanderFroPlatform sipCommanderFroPlatform; private SIPCommanderFroPlatform sipCommanderFroPlatform;
@Autowired
private IRedisCatchStorage redisCatchStorage;
@Autowired @Autowired
private IStreamSendManager streamSendManager; private IStreamSendManager streamSendManager;
@Autowired @Autowired
private IVideoManagerStorage storage; private IVideoManagerStorage storage;
@Autowired
private VideoStreamSessionManager sessionManager;
@Autowired @Autowired
private ZlmHttpHookSubscribe subscribe; private ZlmHttpHookSubscribe subscribe;
@ -114,7 +106,7 @@ public class MediaStatusNotifyMessageHandler extends SIPRequestProcessorParent i
HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", ssrcTransaction.getStream(), false, "rtsp", ssrcTransaction.getMediaServerId()); HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", ssrcTransaction.getStream(), false, "rtsp", ssrcTransaction.getMediaServerId());
subscribe.removeSubscribe(hookSubscribe); subscribe.removeSubscribe(hookSubscribe);
// 如果级联播放,需要给上级发送此通知 TODO 多个上级同时观看一个下级 可能存在停错的问题需要将点播CallId进行上下级绑定 // 如果级联播放,需要给上级发送此通知
SendRtpItem sendRtpItem = streamSendManager.getByCallId(ssrcTransaction.getCallId()); SendRtpItem sendRtpItem = streamSendManager.getByCallId(ssrcTransaction.getCallId());
if (sendRtpItem != null) { if (sendRtpItem != null) {
ParentPlatform parentPlatform = storage.queryParentPlatByServerGBId(sendRtpItem.getDestId()); ParentPlatform parentPlatform = storage.queryParentPlatByServerGBId(sendRtpItem.getDestId());

View File

@ -272,7 +272,7 @@ public class ZLMHttpHookListener {
inviteInfo = inviteStreamService.getInviteInfoBySSRC(ssrc); inviteInfo = inviteStreamService.getInviteInfoBySSRC(ssrc);
if (inviteInfo != null) { if (inviteInfo != null) {
result.setStream_replace(inviteInfo.getStream()); result.setStream_replace(inviteInfo.getStream());
logger.info("[ZLM HOOK]推流鉴权 stream: {} 替换为 {}", param.getStream(), inviteInfo.getStream()); logger.info("[ZLM HOOK] 推流鉴权 stream: {} 替换为 {}", param.getStream(), inviteInfo.getStream());
} }
} }
@ -320,7 +320,7 @@ public class ZLMHttpHookListener {
result.setEnable_mp4(true); result.setEnable_mp4(true);
} }
} }
logger.info("[ZLM HOOK]推流鉴权 响应:{}->{}->>>>{}", param.getMediaServerId(), param, result); logger.info("[ZLM HOOK] 推流鉴权 响应:{}->{} \r\n{}", param.getMediaServerId(), param, result);
return result; return result;
} }
@ -725,7 +725,7 @@ public class ZLMHttpHookListener {
} }
taskExecutor.execute(() -> { taskExecutor.execute(() -> {
List<SendRtpItem> sendRtpItems = streamSendManager.getByAppAndStream(param.getApp(), param.getStream()); List<SendRtpItem> sendRtpItems = streamSendManager.getByAppAndStream(param.getApp(), param.getStream());
if (!sendRtpItems.isEmpty()) { if (sendRtpItems != null && !sendRtpItems.isEmpty()) {
for (SendRtpItem sendRtpItem : sendRtpItems) { for (SendRtpItem sendRtpItem : sendRtpItems) {
ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(sendRtpItem.getDestId()); ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(sendRtpItem.getDestId());
ssrcFactory.releaseSsrc(sendRtpItem.getMediaServerId(), sendRtpItem.getSsrc()); ssrcFactory.releaseSsrc(sendRtpItem.getMediaServerId(), sendRtpItem.getSsrc());

View File

@ -71,13 +71,13 @@ public class HookResultForOnPublish extends HookResult{
@Override @Override
public String toString() { public String toString() {
return "HookResultForOnPublish{" + return "\nHookResultForOnPublish {" +
"enable_audio=" + enable_audio + "\nenable_audio=" + enable_audio +
", enable_mp4=" + enable_mp4 + "\n, enable_mp4=" + enable_mp4 +
", mp4_max_second=" + mp4_max_second + "\n, mp4_max_second=" + mp4_max_second +
", mp4_save_path='" + mp4_save_path + '\'' + "\n, mp4_save_path='" + mp4_save_path + '\'' +
", stream_replace='" + stream_replace + '\'' + "\n, stream_replace='" + stream_replace + '\'' +
", modify_stamp='" + modify_stamp + '\'' + "\n, modify_stamp='" + modify_stamp + '\'' +
'}'; "\n}";
} }
} }

View File

@ -22,17 +22,25 @@ import com.genersoft.iot.vmp.media.zlm.IStreamSendManager;
import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils; import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory;
import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe;
import com.genersoft.iot.vmp.media.zlm.dto.*; import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory;
import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForRecordMp4;
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.hook.HookParam; 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.OnRecordMp4HookParam;
import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam; import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
import com.genersoft.iot.vmp.service.*; import com.genersoft.iot.vmp.service.IInviteStreamService;
import com.genersoft.iot.vmp.service.bean.*; import com.genersoft.iot.vmp.service.IMediaServerService;
import com.genersoft.iot.vmp.service.IMediaService;
import com.genersoft.iot.vmp.service.IPlayService;
import com.genersoft.iot.vmp.service.bean.DownloadFileInfo;
import com.genersoft.iot.vmp.service.bean.ErrorCallback;
import com.genersoft.iot.vmp.service.bean.InviteErrorCode;
import com.genersoft.iot.vmp.service.bean.SSRCInfo;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage; import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.IVideoManagerStorage; import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper; import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper;
import com.genersoft.iot.vmp.storager.dao.DeviceMapper; import com.genersoft.iot.vmp.storager.dao.DeviceMapper;
import com.genersoft.iot.vmp.storager.dao.CloudRecordServiceMapper;
import com.genersoft.iot.vmp.utils.CloudRecordUtils; import com.genersoft.iot.vmp.utils.CloudRecordUtils;
import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.utils.DateUtil;
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
@ -804,7 +812,9 @@ public class PlayServiceImpl implements IPlayService {
DownloadFileInfo downloadFileInfo = CloudRecordUtils.getDownloadFilePath(mediaServerItem, filePath); DownloadFileInfo downloadFileInfo = CloudRecordUtils.getDownloadFilePath(mediaServerItem, filePath);
InviteInfo inviteInfoForNew = inviteStreamService.getInviteInfo(inviteInfo.getType(), inviteInfo.getDeviceId() InviteInfo inviteInfoForNew = inviteStreamService.getInviteInfo(inviteInfo.getType(), inviteInfo.getDeviceId()
, inviteInfo.getChannelId(), inviteInfo.getStream()); , inviteInfo.getChannelId(), inviteInfo.getStream());
if (inviteInfoForNew.getStreamInfo() != null) {
inviteInfoForNew.getStreamInfo().setDownLoadFilePath(downloadFileInfo); inviteInfoForNew.getStreamInfo().setDownLoadFilePath(downloadFileInfo);
}
inviteStreamService.updateInviteInfo(inviteInfoForNew); inviteStreamService.updateInviteInfo(inviteInfoForNew);
}; };
HookSubscribeForRecordMp4 hookSubscribe = HookSubscribeFactory.on_record_mp4( HookSubscribeForRecordMp4 hookSubscribe = HookSubscribeFactory.on_record_mp4(