支持国标级联录像下载

结构优化
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 endTimeStr = DateUtil.formatter.format(stopTime);
String stream = checkResult.device.getDeviceId() + "_" + checkResult.channel.getChannelId() + "_" +
startTimeStr + "_" + endTimeStr;
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());
@ -360,8 +360,34 @@ public class GB28181ResourceServiceImpl implements IResourceService {
}
@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 {

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.HookSubscribeForStreamChange;
import com.genersoft.iot.vmp.service.IInviteStreamService;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
import gov.nist.javax.sip.message.SIPRequest;
import org.dom4j.Element;
@ -34,7 +33,6 @@ import javax.sip.SipException;
import javax.sip.header.CallIdHeader;
import javax.sip.message.Response;
import java.text.ParseException;
import java.util.List;
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
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";
@Autowired
@ -56,18 +54,12 @@ public class MediaStatusNotifyMessageHandler extends SIPRequestProcessorParent i
@Autowired
private SIPCommanderFroPlatform sipCommanderFroPlatform;
@Autowired
private IRedisCatchStorage redisCatchStorage;
@Autowired
private IStreamSendManager streamSendManager;
@Autowired
private IVideoManagerStorage storage;
@Autowired
private VideoStreamSessionManager sessionManager;
@Autowired
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());
subscribe.removeSubscribe(hookSubscribe);
// 如果级联播放,需要给上级发送此通知 TODO 多个上级同时观看一个下级 可能存在停错的问题需要将点播CallId进行上下级绑定
// 如果级联播放,需要给上级发送此通知
SendRtpItem sendRtpItem = streamSendManager.getByCallId(ssrcTransaction.getCallId());
if (sendRtpItem != null) {
ParentPlatform parentPlatform = storage.queryParentPlatByServerGBId(sendRtpItem.getDestId());

View File

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

View File

@ -71,13 +71,13 @@ public class HookResultForOnPublish extends HookResult{
@Override
public String toString() {
return "HookResultForOnPublish{" +
"enable_audio=" + enable_audio +
", enable_mp4=" + enable_mp4 +
", mp4_max_second=" + mp4_max_second +
", mp4_save_path='" + mp4_save_path + '\'' +
", stream_replace='" + stream_replace + '\'' +
", modify_stamp='" + modify_stamp + '\'' +
'}';
return "\nHookResultForOnPublish {" +
"\nenable_audio=" + enable_audio +
"\n, enable_mp4=" + enable_mp4 +
"\n, mp4_max_second=" + mp4_max_second +
"\n, mp4_save_path='" + mp4_save_path + '\'' +
"\n, stream_replace='" + stream_replace + '\'' +
"\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.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.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.OnRecordMp4HookParam;
import com.genersoft.iot.vmp.media.zlm.dto.hook.OnStreamChangedHookParam;
import com.genersoft.iot.vmp.service.*;
import com.genersoft.iot.vmp.service.bean.*;
import com.genersoft.iot.vmp.service.IInviteStreamService;
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.IVideoManagerStorage;
import com.genersoft.iot.vmp.storager.dao.DeviceChannelMapper;
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.DateUtil;
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
@ -804,7 +812,9 @@ public class PlayServiceImpl implements IPlayService {
DownloadFileInfo downloadFileInfo = CloudRecordUtils.getDownloadFilePath(mediaServerItem, filePath);
InviteInfo inviteInfoForNew = inviteStreamService.getInviteInfo(inviteInfo.getType(), inviteInfo.getDeviceId()
, inviteInfo.getChannelId(), inviteInfo.getStream());
if (inviteInfoForNew.getStreamInfo() != null) {
inviteInfoForNew.getStreamInfo().setDownLoadFilePath(downloadFileInfo);
}
inviteStreamService.updateInviteInfo(inviteInfoForNew);
};
HookSubscribeForRecordMp4 hookSubscribe = HookSubscribeFactory.on_record_mp4(