支持级联国标录像下载
parent
affbd89fdb
commit
a2da81f79a
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -429,8 +429,10 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
|
||||||
InviteErrorCallback<Object> errorEvent = ((statusCode, msg, data) -> {
|
InviteErrorCallback<Object> errorEvent = ((statusCode, msg, data) -> {
|
||||||
// 未知错误。直接转发设备点播的错误
|
// 未知错误。直接转发设备点播的错误
|
||||||
try {
|
try {
|
||||||
Response response = getMessageFactory().createResponse(statusCode, evt.getRequest());
|
if (statusCode > 0) {
|
||||||
sipSender.transmitRequest(request.getLocalAddress().getHostAddress(), response);
|
Response response = getMessageFactory().createResponse(statusCode, evt.getRequest());
|
||||||
|
sipSender.transmitRequest(request.getLocalAddress().getHostAddress(), response);
|
||||||
|
}
|
||||||
} catch (ParseException | SipException e) {
|
} catch (ParseException | SipException e) {
|
||||||
logger.error("未处理的异常 ", e);
|
logger.error("未处理的异常 ", e);
|
||||||
}
|
}
|
||||||
|
@ -455,7 +457,37 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
|
||||||
errorEvent.run(code, msg, data);
|
errorEvent.run(code, msg, data);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
}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 {
|
||||||
sendRtpItem.setPlayType(InviteStreamType.PLAY);
|
sendRtpItem.setPlayType(InviteStreamType.PLAY);
|
||||||
String streamId = null;
|
String streamId = null;
|
||||||
if (mediaServerItem.isRtpEnable()) {
|
if (mediaServerItem.isRtpEnable()) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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) {
|
||||||
String gbCodeType = channel.getChannelId().substring(10, 13);
|
if (channel.getChannelId().length() > 13) {
|
||||||
node.setParent(gbCodeType.equals(ChannelIdType.BUSINESS_GROUP) || gbCodeType.equals(ChannelIdType.VIRTUAL_ORGANIZATION) );
|
String gbCodeType = channel.getChannelId().substring(10, 13);
|
||||||
|
node.setParent(gbCodeType.equals(ChannelIdType.BUSINESS_GROUP) || gbCodeType.equals(ChannelIdType.VIRTUAL_ORGANIZATION) );
|
||||||
|
}
|
||||||
}else {
|
}else {
|
||||||
node.setParent(true);
|
node.setParent(true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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,14 +340,18 @@
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
stopPlayRecord: function (callback) {
|
stopPlayRecord: function (callback) {
|
||||||
this.$refs["recordVideoPlayer"].pause();
|
console.log("停止录像回放")
|
||||||
this.videoUrl = '';
|
if (this.streamId !== "") {
|
||||||
this.$axios({
|
this.$refs["recordVideoPlayer"].pause();
|
||||||
method: 'get',
|
this.videoUrl = '';
|
||||||
url: '/api/playback/stop/' + this.deviceId + "/" + this.channelId + "/" + this.streamId
|
this.$axios({
|
||||||
}).then(function (res) {
|
method: 'get',
|
||||||
if (callback) callback()
|
url: '/api/playback/stop/' + this.deviceId + "/" + this.channelId + "/" + this.streamId
|
||||||
});
|
}).then(function (res) {
|
||||||
|
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(){
|
||||||
|
// 如果正在进行录像回放则,发送停止
|
||||||
|
if (this.streamId !== "") {
|
||||||
|
this.stopPlayRecord(()=> {
|
||||||
|
this.streamId = "";
|
||||||
|
})
|
||||||
|
}
|
||||||
window.history.go(-1);
|
window.history.go(-1);
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in New Issue