支持级联国标录像下载

pull/845/head
648540858 2023-05-09 17:31:58 +08:00
parent affbd89fdb
commit a2da81f79a
8 changed files with 71 additions and 21 deletions

View File

@ -2,7 +2,7 @@ package com.genersoft.iot.vmp.gb28181.bean;
public enum InviteStreamType { public enum InviteStreamType {
PLAY,PLAYBACK,PUSH,PROXY,CLOUD_RECORD_PUSH,CLOUD_RECORD_PROXY PLAY,PLAYBACK,DOWNLOAD,PUSH,PROXY,CLOUD_RECORD_PUSH,CLOUD_RECORD_PROXY
} }

View File

@ -540,7 +540,7 @@ public class SIPCommander implements ISIPCommander {
content.append("y=" + ssrcInfo.getSsrc() + "\r\n");//ssrc content.append("y=" + ssrcInfo.getSsrc() + "\r\n");//ssrc
logger.debug("此时请求下载信令的ssrc===>{}",ssrcInfo.getSsrc()); logger.debug("此时请求下载信令的ssrc===>{}",ssrcInfo.getSsrc());
HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", ssrcInfo.getStream(), true, null, mediaServerItem.getId()); HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", ssrcInfo.getStream(), true, "rtsp", mediaServerItem.getId());
// 添加订阅 // 添加订阅
CallIdHeader newCallIdHeader = sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()), device.getTransport()); CallIdHeader newCallIdHeader = sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()), device.getTransport());
String callId= newCallIdHeader.getCallId(); String callId= newCallIdHeader.getCallId();

View File

@ -429,8 +429,10 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
InviteErrorCallback<Object> errorEvent = ((statusCode, msg, data) -> { InviteErrorCallback<Object> errorEvent = ((statusCode, msg, data) -> {
// 未知错误。直接转发设备点播的错误 // 未知错误。直接转发设备点播的错误
try { try {
if (statusCode > 0) {
Response response = getMessageFactory().createResponse(statusCode, evt.getRequest()); Response response = getMessageFactory().createResponse(statusCode, evt.getRequest());
sipSender.transmitRequest(request.getLocalAddress().getHostAddress(), response); sipSender.transmitRequest(request.getLocalAddress().getHostAddress(), response);
}
} catch (ParseException | SipException e) { } catch (ParseException | SipException e) {
logger.error("未处理的异常 ", e); logger.error("未处理的异常 ", e);
} }
@ -455,6 +457,36 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
errorEvent.run(code, msg, data); errorEvent.run(code, msg, data);
} }
}); });
}else if ("Download".equalsIgnoreCase(sessionName)) {
// 获取指定的下载速度
Vector sdpMediaDescriptions = sdp.getMediaDescriptions(true);
MediaDescription mediaDescription = null;
String downloadSpeed = "1";
if (sdpMediaDescriptions.size() > 0) {
mediaDescription = (MediaDescription)sdpMediaDescriptions.get(0);
}
if (mediaDescription != null) {
downloadSpeed = mediaDescription.getAttribute("downloadspeed");
}
sendRtpItem.setPlayType(InviteStreamType.DOWNLOAD);
SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, null, null, device.isSsrcCheck(), true, 0, false, device.getStreamModeForParam());
sendRtpItem.setStreamId(ssrcInfo.getStream());
// 写入redis 超时时回复
redisCatchStorage.updateSendRTPSever(sendRtpItem);
playService.download(mediaServerItem, ssrcInfo, device.getDeviceId(), channelId, DateUtil.formatter.format(start),
DateUtil.formatter.format(end), Integer.parseInt(downloadSpeed),
(code, msg, data) -> {
if (code == InviteErrorCode.SUCCESS.getCode()){
hookEvent.run(code, msg, data);
}else if (code == InviteErrorCode.ERROR_FOR_SIGNALLING_TIMEOUT.getCode() || code == InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getCode()){
logger.info("[录像下载]超时, 用户:{} 通道:{}", username, channelId);
redisCatchStorage.deleteSendRTPServer(platform.getServerGBId(), channelId, callIdHeader.getCallId(), null);
errorEvent.run(code, msg, data);
}else {
errorEvent.run(code, msg, data);
}
});
}else { }else {
sendRtpItem.setPlayType(InviteStreamType.PLAY); sendRtpItem.setPlayType(InviteStreamType.PLAY);
String streamId = null; String streamId = null;

View File

@ -438,7 +438,7 @@ public class ZLMHttpHookListener {
@PostMapping(value = "/on_stream_none_reader", produces = "application/json;charset=UTF-8") @PostMapping(value = "/on_stream_none_reader", produces = "application/json;charset=UTF-8")
public JSONObject onStreamNoneReader(@RequestBody OnStreamNoneReaderHookParam param) { public JSONObject onStreamNoneReader(@RequestBody OnStreamNoneReaderHookParam param) {
logger.info("[ZLM HOOK]流无人观看:{]->{}->{}/{}" + param.getMediaServerId(), param.getSchema(), logger.info("[ZLM HOOK]流无人观看:{}->{}->{}/{}", param.getMediaServerId(), param.getSchema(),
param.getApp(), param.getStream()); param.getApp(), param.getStream());
JSONObject ret = new JSONObject(); JSONObject ret = new JSONObject();
ret.put("code", 0); ret.put("code", 0);

View File

@ -501,8 +501,10 @@ public class DeviceServiceImpl implements IDeviceService {
node.setBasicData(channel); node.setBasicData(channel);
node.setParent(false); node.setParent(false);
if (channel.getChannelId().length() > 8) { if (channel.getChannelId().length() > 8) {
if (channel.getChannelId().length() > 13) {
String gbCodeType = channel.getChannelId().substring(10, 13); String gbCodeType = channel.getChannelId().substring(10, 13);
node.setParent(gbCodeType.equals(ChannelIdType.BUSINESS_GROUP) || gbCodeType.equals(ChannelIdType.VIRTUAL_ORGANIZATION) ); node.setParent(gbCodeType.equals(ChannelIdType.BUSINESS_GROUP) || gbCodeType.equals(ChannelIdType.VIRTUAL_ORGANIZATION) );
}
}else { }else {
node.setParent(true); node.setParent(true);
} }

View File

@ -757,7 +757,7 @@ public class PlayServiceImpl implements IPlayService {
null); null);
return; return;
} }
logger.info("[录像下载] deviceId: {}, channelId: {},收流端口:{}, 收流模式:{}, SSRC: {}, SSRC校验{}", device.getDeviceId(), channelId, ssrcInfo.getPort(), device.getStreamMode(), ssrcInfo.getSsrc(), device.isSsrcCheck()); logger.info("[录像下载] deviceId: {}, channelId: {}, 下载速度:{}, 收流端口:{}, 收流模式:{}, SSRC: {}, SSRC校验{}", device.getDeviceId(), channelId, downloadSpeed, ssrcInfo.getPort(), device.getStreamMode(), ssrcInfo.getSsrc(), device.isSsrcCheck());
// 初始化redis中的invite消息状态 // 初始化redis中的invite消息状态
InviteInfo inviteInfo = InviteInfo.getinviteInfo(device.getDeviceId(), channelId, ssrcInfo.getStream(), ssrcInfo, InviteInfo inviteInfo = InviteInfo.getinviteInfo(device.getDeviceId(), channelId, ssrcInfo.getStream(), ssrcInfo,
mediaServerItem.getSdpIp(), ssrcInfo.getPort(), device.getStreamMode(), InviteSessionType.DOWNLOAD, mediaServerItem.getSdpIp(), ssrcInfo.getPort(), device.getStreamMode(), InviteSessionType.DOWNLOAD,
@ -888,7 +888,6 @@ public class PlayServiceImpl implements IPlayService {
cmder.streamByeCmd(device, channelId, ssrcInfo.getStream(), null, null); cmder.streamByeCmd(device, channelId, ssrcInfo.getStream(), null, null);
} catch (InvalidArgumentException | SipException | ParseException | SsrcTransactionNotFoundException e) { } catch (InvalidArgumentException | SipException | ParseException | SsrcTransactionNotFoundException e) {
logger.error("[命令发送失败] 停止点播, 发送BYE: {}", e.getMessage()); logger.error("[命令发送失败] 停止点播, 发送BYE: {}", e.getMessage());
} }
dynamicTask.stop(downLoadTimeOutTaskKey); dynamicTask.stop(downLoadTimeOutTaskKey);
@ -970,10 +969,12 @@ public class PlayServiceImpl implements IPlayService {
private StreamInfo onPublishHandlerForDownload(MediaServerItem mediaServerItemInuse, JSONObject response, String deviceId, String channelId, String startTime, String endTime) { private StreamInfo onPublishHandlerForDownload(MediaServerItem mediaServerItemInuse, JSONObject response, String deviceId, String channelId, String startTime, String endTime) {
StreamInfo streamInfo = onPublishHandler(mediaServerItemInuse, response, deviceId, channelId); StreamInfo streamInfo = onPublishHandler(mediaServerItemInuse, response, deviceId, channelId);
if (streamInfo != null) { if (streamInfo != null) {
streamInfo.setProgress(0);
streamInfo.setStartTime(startTime); streamInfo.setStartTime(startTime);
streamInfo.setEndTime(endTime); streamInfo.setEndTime(endTime);
InviteInfo inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.DOWNLOAD, deviceId, channelId); InviteInfo inviteInfo = inviteStreamService.getInviteInfo(InviteSessionType.DOWNLOAD, deviceId, channelId, streamInfo.getStream());
if (inviteInfo != null) { if (inviteInfo != null) {
logger.info("[录像下载] 更新invite消息中的stream信息");
inviteInfo.setStatus(InviteSessionStatus.ok); inviteInfo.setStatus(InviteSessionStatus.ok);
inviteInfo.setStreamInfo(streamInfo); inviteInfo.setStreamInfo(streamInfo);
inviteStreamService.updateInviteInfo(inviteInfo); inviteStreamService.updateInviteInfo(inviteInfo);

View File

@ -182,9 +182,11 @@
this.playerStyle["height"] = this.winHeight + "px"; this.playerStyle["height"] = this.winHeight + "px";
this.chooseDate = moment().format('YYYY-MM-DD') this.chooseDate = moment().format('YYYY-MM-DD')
this.dateChange(); this.dateChange();
window.addEventListener('beforeunload', this.stopPlayRecord)
}, },
destroyed() { destroyed() {
this.$destroy('recordVideoPlayer'); this.$destroy('recordVideoPlayer');
window.removeEventListener('beforeunload', this.stopPlayRecord)
}, },
methods: { methods: {
dateChange(){ dateChange(){
@ -338,6 +340,8 @@
}); });
}, },
stopPlayRecord: function (callback) { stopPlayRecord: function (callback) {
console.log("停止录像回放")
if (this.streamId !== "") {
this.$refs["recordVideoPlayer"].pause(); this.$refs["recordVideoPlayer"].pause();
this.videoUrl = ''; this.videoUrl = '';
this.$axios({ this.$axios({
@ -346,6 +350,8 @@
}).then(function (res) { }).then(function (res) {
if (callback) callback() if (callback) callback()
}); });
}
}, },
getDataWidth(item){ getDataWidth(item){
let timeForFile = this.getTimeForFile(item); let timeForFile = this.getTimeForFile(item);
@ -423,8 +429,14 @@
return hStr + ":" + mStr + ":" + sStr return hStr + ":" + mStr + ":" + sStr
}, },
goBack(){ goBack(){
window.history.go(-1); //
if (this.streamId !== "") {
this.stopPlayRecord(()=> {
this.streamId = "";
})
} }
window.history.go(-1);
},
} }
}; };
</script> </script>

View File

@ -21,7 +21,7 @@ import moment from "moment";
export default { export default {
name: 'recordDownload', name: 'recordDownload',
created() { created() {
window.addEventListener('beforeunload', this.stopDownloadRecord)
}, },
data() { data() {
@ -197,6 +197,9 @@ export default {
console.log(error); console.log(error);
}); });
} }
},
destroyed() {
window.removeEventListener('beforeunload', this.stopDownloadRecord)
} }
}; };
</script> </script>