添加对海康平台录像回放的兼容,修复录像信息发送失败, 级联平台支持开启rtcp保活

pull/608/head
648540858 2022-09-05 17:10:21 +08:00
parent 0134488428
commit d5e8aa62a1
15 changed files with 202 additions and 69 deletions

View File

@ -113,7 +113,6 @@ public class ParentPlatform {
/** /**
* RTCP * RTCP
* TODO ,
*/ */
@Schema(description = "RTCP流保活") @Schema(description = "RTCP流保活")
private boolean rtcp; private boolean rtcp;

View File

@ -103,7 +103,7 @@ public interface ISIPCommander {
* @param startTime ,yyyy-MM-dd HH:mm:ss * @param startTime ,yyyy-MM-dd HH:mm:ss
* @param endTime ,yyyy-MM-dd HH:mm:ss * @param endTime ,yyyy-MM-dd HH:mm:ss
*/ */
void playbackStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInf, Device device, String channelId, String startTime, String endTime,InviteStreamCallback inviteStreamCallback, InviteStreamCallback event, SipSubscribe.Event errorEvent); void playbackStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInf, Device device, String channelId, String startTime, String endTime,InviteStreamCallback inviteStreamCallback, InviteStreamCallback event, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent);
/** /**
* *

View File

@ -456,7 +456,7 @@ public class SIPCommander implements ISIPCommander {
@Override @Override
public void playbackStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, public void playbackStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId,
String startTime, String endTime, InviteStreamCallback inviteStreamCallback, InviteStreamCallback hookEvent, String startTime, String endTime, InviteStreamCallback inviteStreamCallback, InviteStreamCallback hookEvent,
SipSubscribe.Event errorEvent) { SipSubscribe.Event okEvent,SipSubscribe.Event errorEvent) {
try { try {
logger.info("{} 分配的ZLM为: {} [{}:{}]", ssrcInfo.getStream(), mediaServerItem.getId(), mediaServerItem.getIp(), ssrcInfo.getPort()); logger.info("{} 分配的ZLM为: {} [{}:{}]", ssrcInfo.getStream(), mediaServerItem.getId(), mediaServerItem.getIp(), ssrcInfo.getPort());
@ -535,10 +535,11 @@ public class SIPCommander implements ISIPCommander {
}); });
Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, "fromplybck" + tm, null, callIdHeader, ssrcInfo.getSsrc()); Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, "fromplybck" + tm, null, callIdHeader, ssrcInfo.getSsrc());
transmitRequest(device, request, errorEvent, okEvent -> { transmitRequest(device, request, errorEvent, event -> {
ResponseEvent responseEvent = (ResponseEvent) okEvent.event; ResponseEvent responseEvent = (ResponseEvent) event.event;
streamSession.put(device.getDeviceId(), channelId, callIdHeader.getCallId(), ssrcInfo.getStream(), ssrcInfo.getSsrc(), mediaServerItem.getId(), responseEvent.getClientTransaction(), VideoStreamSessionManager.SessionType.playback); streamSession.put(device.getDeviceId(), channelId, callIdHeader.getCallId(), ssrcInfo.getStream(), ssrcInfo.getSsrc(), mediaServerItem.getId(), responseEvent.getClientTransaction(), VideoStreamSessionManager.SessionType.playback);
streamSession.put(device.getDeviceId(), channelId, callIdHeader.getCallId(), okEvent.dialog); streamSession.put(device.getDeviceId(), channelId, callIdHeader.getCallId(), event.dialog);
okEvent.response(event);
}); });
if (inviteStreamCallback != null) { if (inviteStreamCallback != null) {
inviteStreamCallback.call(new InviteStreamInfo(mediaServerItem, null, callIdHeader.getCallId(), "rtp", ssrcInfo.getStream())); inviteStreamCallback.call(new InviteStreamInfo(mediaServerItem, null, callIdHeader.getCallId(), "rtp", ssrcInfo.getStream()));

View File

@ -115,6 +115,11 @@ public class AckRequestProcessor extends SIPRequestProcessorParent implements In
param.put("pt", sendRtpItem.getPt()); param.put("pt", sendRtpItem.getPt());
param.put("use_ps", sendRtpItem.isUsePs() ? "1" : "0"); param.put("use_ps", sendRtpItem.isUsePs() ? "1" : "0");
param.put("only_audio", sendRtpItem.isOnlyAudio() ? "1" : "0"); param.put("only_audio", sendRtpItem.isOnlyAudio() ? "1" : "0");
if (!sendRtpItem.isTcp() && parentPlatform.isRtcp()) {
// 开启rtcp保活
param.put("udp_rtcp_timeout", "1");
}
if (mediaInfo == null) { if (mediaInfo == null) {
RequestPushStreamMsg requestPushStreamMsg = RequestPushStreamMsg.getInstance( RequestPushStreamMsg requestPushStreamMsg = RequestPushStreamMsg.getInstance(
sendRtpItem.getMediaServerId(), sendRtpItem.getApp(), sendRtpItem.getStreamId(), sendRtpItem.getMediaServerId(), sendRtpItem.getApp(), sendRtpItem.getStreamId(),

View File

@ -98,8 +98,8 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In
param.put("ssrc",sendRtpItem.getSsrc()); param.put("ssrc",sendRtpItem.getSsrc());
logger.info("收到bye:停止向上级推流:" + streamId); logger.info("收到bye:停止向上级推流:" + streamId);
MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId()); MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param);
redisCatchStorage.deleteSendRTPServer(platformGbId, channelId, callIdHeader.getCallId(), null); redisCatchStorage.deleteSendRTPServer(platformGbId, channelId, callIdHeader.getCallId(), null);
zlmrtpServerFactory.stopSendRtpStream(mediaInfo, param);
int totalReaderCount = zlmrtpServerFactory.totalReaderCount(mediaInfo, sendRtpItem.getApp(), streamId); int totalReaderCount = zlmrtpServerFactory.totalReaderCount(mediaInfo, sendRtpItem.getApp(), streamId);
if (totalReaderCount <= 0) { if (totalReaderCount <= 0) {
logger.info("收到bye: {} 无其它观看者,通知设备停止推流", streamId); logger.info("收到bye: {} 无其它观看者,通知设备停止推流", streamId);

View File

@ -563,6 +563,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
responseAck(evt, Response.BAD_REQUEST, "channel [" + gbStream.getGbId() + "] offline"); responseAck(evt, Response.BAD_REQUEST, "channel [" + gbStream.getGbId() + "] offline");
} else if ("push".equals(gbStream.getStreamType())) { } else if ("push".equals(gbStream.getStreamType())) {
if (!platform.isStartOfflinePush()) { if (!platform.isStartOfflinePush()) {
// 平台设置中关闭了拉起离线的推流则直接回复
responseAck(evt, Response.TEMPORARILY_UNAVAILABLE, "channel unavailable"); responseAck(evt, Response.TEMPORARILY_UNAVAILABLE, "channel unavailable");
return; return;
} }
@ -599,7 +600,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
app, stream, channelId, mediaTransmissionTCP); app, stream, channelId, mediaTransmissionTCP);
if (sendRtpItem == null) { if (sendRtpItem == null) {
logger.warn("服务器端口资源不足"); logger.warn("上级点时创建sendRTPItem失败可能是服务器端口资源不足");
try { try {
responseAck(evt, Response.BUSY_HERE); responseAck(evt, Response.BUSY_HERE);
} catch (SipException e) { } catch (SipException e) {

View File

@ -50,7 +50,7 @@ public class AssistRESTfulUtils {
if (mediaServerItem == null) { if (mediaServerItem == null) {
return null; return null;
} }
if (mediaServerItem.getRecordAssistPort() > 0) { if (mediaServerItem.getRecordAssistPort() <= 0) {
logger.warn("未启用Assist服务"); logger.warn("未启用Assist服务");
return null; return null;
} }

View File

@ -19,8 +19,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -544,6 +542,8 @@ public class ZLMHttpHookListener {
for (SendRtpItem sendRtpItem : sendRtpItems) { for (SendRtpItem sendRtpItem : sendRtpItems) {
ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(sendRtpItem.getPlatformId()); ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(sendRtpItem.getPlatformId());
commanderFroPlatform.streamByeCmd(parentPlatform, sendRtpItem.getCallId()); commanderFroPlatform.streamByeCmd(parentPlatform, sendRtpItem.getCallId());
redisCatchStorage.deleteSendRTPServer(parentPlatform.getServerGBId(), sendRtpItem.getChannelId(),
sendRtpItem.getCallId(), sendRtpItem.getStreamId());
} }
} }
} }
@ -573,14 +573,20 @@ public class ZLMHttpHookListener {
return ret; return ret;
}else { }else {
StreamProxyItem streamProxyItem = streamProxyService.getStreamProxyByAppAndStream(app, streamId); StreamProxyItem streamProxyItem = streamProxyService.getStreamProxyByAppAndStream(app, streamId);
if (streamProxyItem != null && streamProxyItem.isEnable_remove_none_reader()) { if (streamProxyItem != null ) {
if (streamProxyItem.isEnable_remove_none_reader()) {
// 无人观看自动移除
ret.put("close", true); ret.put("close", true);
streamProxyService.del(app, streamId); streamProxyService.del(app, streamId);
String url = streamProxyItem.getUrl() != null?streamProxyItem.getUrl():streamProxyItem.getSrc_url(); String url = streamProxyItem.getUrl() != null?streamProxyItem.getUrl():streamProxyItem.getSrc_url();
logger.info("[{}/{}]<-[{}] 拉流代理无人观看已经移除", app, streamId, url); logger.info("[{}/{}]<-[{}] 拉流代理无人观看已经移除", app, streamId, url);
}else if (streamProxyItem.isEnable_disable_none_reader()) {
// 无人观看停用
ret.put("close", true);
}else { }else {
ret.put("close", false); ret.put("close", false);
} }
}
return ret; return ret;
} }
} }
@ -649,6 +655,39 @@ public class ZLMHttpHookListener {
return ret; return ret;
} }
/**
* rtp(startSendRtp)
*/
@ResponseBody
@PostMapping(value = "/on_send_rtp_stopped", produces = "application/json;charset=UTF-8")
public JSONObject onSendRtpStopped(HttpServletRequest request, @RequestBody JSONObject jsonObject){
logger.info("[ ZLM HOOK ]on_send_rtp_stopped API调用参数" + jsonObject);
JSONObject ret = new JSONObject();
ret.put("code", 0);
ret.put("msg", "success");
// 查找对应的上级推流,发送停止
String app = jsonObject.getString("app");
if (!"rtp".equals(app)) {
return ret;
}
String stream = jsonObject.getString("stream");
List<SendRtpItem> sendRtpItems = redisCatchStorage.querySendRTPServerByStream(stream);
if (sendRtpItems.size() > 0) {
for (SendRtpItem sendRtpItem : sendRtpItems) {
ParentPlatform parentPlatform = storager.queryParentPlatByServerGBId(sendRtpItem.getPlatformId());
commanderFroPlatform.streamByeCmd(parentPlatform, sendRtpItem.getCallId());
redisCatchStorage.deleteSendRTPServer(parentPlatform.getServerGBId(), sendRtpItem.getChannelId(),
sendRtpItem.getCallId(), sendRtpItem.getStreamId());
}
}
return ret;
}
private Map<String, String> urlParamToMap(String params) { private Map<String, String> urlParamToMap(String params) {
HashMap<String, String> map = new HashMap<>(); HashMap<String, String> map = new HashMap<>();
if (ObjectUtils.isEmpty(params)) { if (ObjectUtils.isEmpty(params)) {

View File

@ -37,6 +37,9 @@ public class StreamProxyItem extends GbStream {
private boolean enable_mp4; private boolean enable_mp4;
@Schema(description = "是否 无人观看时删除") @Schema(description = "是否 无人观看时删除")
private boolean enable_remove_none_reader; private boolean enable_remove_none_reader;
@Schema(description = "是否 无人观看时不启用")
private boolean enable_disable_none_reader;
@Schema(description = "上级平台国标ID") @Schema(description = "上级平台国标ID")
private String platformGbId; private String platformGbId;
@Schema(description = "创建时间") @Schema(description = "创建时间")
@ -177,4 +180,11 @@ public class StreamProxyItem extends GbStream {
this.enable_remove_none_reader = enable_remove_none_reader; this.enable_remove_none_reader = enable_remove_none_reader;
} }
public boolean isEnable_disable_none_reader() {
return enable_disable_none_reader;
}
public void setEnable_disable_none_reader(boolean enable_disable_none_reader) {
this.enable_disable_none_reader = enable_disable_none_reader;
}
} }

View File

@ -531,6 +531,7 @@ public class MediaServerServiceImpl implements IMediaServerService {
param.put("hook.on_stream_none_reader",String.format("%s/on_stream_none_reader", hookPrex)); param.put("hook.on_stream_none_reader",String.format("%s/on_stream_none_reader", hookPrex));
param.put("hook.on_stream_not_found",String.format("%s/on_stream_not_found", hookPrex)); param.put("hook.on_stream_not_found",String.format("%s/on_stream_not_found", hookPrex));
param.put("hook.on_server_keepalive",String.format("%s/on_server_keepalive", hookPrex)); param.put("hook.on_server_keepalive",String.format("%s/on_server_keepalive", hookPrex));
param.put("hook.on_send_rtp_stopped",String.format("%s/on_send_rtp_stopped", hookPrex));
if (mediaServerItem.getRecordAssistPort() > 0) { if (mediaServerItem.getRecordAssistPort() > 0) {
param.put("hook.on_record_mp4",String.format("http://127.0.0.1:%s/api/record/on_record_mp4", mediaServerItem.getRecordAssistPort())); param.put("hook.on_record_mp4",String.format("http://127.0.0.1:%s/api/record/on_record_mp4", mediaServerItem.getRecordAssistPort()));
}else { }else {

View File

@ -73,7 +73,6 @@ public class MediaServiceImpl implements IMediaService {
}else { }else {
streamInfo = getStreamInfoByAppAndStream(mediaInfo, app, stream, tracks, addr,null); streamInfo = getStreamInfoByAppAndStream(mediaInfo, app, stream, tracks, addr,null);
} }
} }
} }
return streamInfo; return streamInfo;

View File

@ -291,7 +291,7 @@ public class PlayServiceImpl implements IPlayService {
} }
logger.info("[点播消息] 收到invite 200, 发现下级自定义了ssrc: {}", ssrcInResponse ); logger.info("[点播消息] 收到invite 200, 发现下级自定义了ssrc: {}", ssrcInResponse );
if (!mediaServerItem.isRtpEnable() || device.isSsrcCheck()) { if (!mediaServerItem.isRtpEnable() || device.isSsrcCheck()) {
logger.info("[SIP 消息] SSRC修正 {}->{}", ssrc, ssrcInResponse); logger.info("[点播消息] SSRC修正 {}->{}", ssrc, ssrcInResponse);
if (!mediaServerItem.getSsrcConfig().checkSsrc(ssrcInResponse)) { if (!mediaServerItem.getSsrcConfig().checkSsrc(ssrcInResponse)) {
// ssrc 不可用 // ssrc 不可用
@ -441,9 +441,19 @@ public class PlayServiceImpl implements IPlayService {
resultHolder.exist(DeferredResultHolder.CALLBACK_CMD_PLAYBACK + deviceId + channelId, uuid); resultHolder.exist(DeferredResultHolder.CALLBACK_CMD_PLAYBACK + deviceId + channelId, uuid);
}, userSetting.getPlayTimeout()); }, userSetting.getPlayTimeout());
cmder.playbackStreamCmd(mediaServerItem, ssrcInfo, device, channelId, startTime, endTime, infoCallBack, SipSubscribe.Event errorEvent = event -> {
(InviteStreamInfo inviteStreamInfo) -> { dynamicTask.stop(playBackTimeOutTaskKey);
logger.info("收到订阅消息: " + inviteStreamInfo.getResponse().toJSONString()); requestMessage.setData(WVPResult.fail(ErrorCode.ERROR100.getCode(), String.format("回放失败, 错误码: %s, %s", event.statusCode, event.msg)));
playBackResult.setCode(ErrorCode.ERROR100.getCode());
playBackResult.setMsg(String.format("回放失败, 错误码: %s, %s", event.statusCode, event.msg));
playBackResult.setData(requestMessage);
playBackResult.setEvent(event);
playBackCallback.call(playBackResult);
streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
};
InviteStreamCallback hookEvent = (InviteStreamInfo inviteStreamInfo) -> {
logger.info("收到回放订阅消息: " + inviteStreamInfo.getResponse().toJSONString());
dynamicTask.stop(playBackTimeOutTaskKey); dynamicTask.stop(playBackTimeOutTaskKey);
StreamInfo streamInfo = onPublishHandler(inviteStreamInfo.getMediaServerItem(), inviteStreamInfo.getResponse(), deviceId, channelId); StreamInfo streamInfo = onPublishHandler(inviteStreamInfo.getMediaServerItem(), inviteStreamInfo.getResponse(), deviceId, channelId);
if (streamInfo == null) { if (streamInfo == null) {
@ -462,16 +472,61 @@ public class PlayServiceImpl implements IPlayService {
playBackResult.setMediaServerItem(inviteStreamInfo.getMediaServerItem()); playBackResult.setMediaServerItem(inviteStreamInfo.getMediaServerItem());
playBackResult.setResponse(inviteStreamInfo.getResponse()); playBackResult.setResponse(inviteStreamInfo.getResponse());
playBackCallback.call(playBackResult); playBackCallback.call(playBackResult);
}, event -> { };
dynamicTask.stop(playBackTimeOutTaskKey);
requestMessage.setData(WVPResult.fail(ErrorCode.ERROR100.getCode(), String.format("回放失败, 错误码: %s, %s", event.statusCode, event.msg))); cmder.playbackStreamCmd(mediaServerItem, ssrcInfo, device, channelId, startTime, endTime, infoCallBack,
playBackResult.setCode(ErrorCode.ERROR100.getCode()); hookEvent, eventResult -> {
playBackResult.setMsg(String.format("回放失败, 错误码: %s, %s", event.statusCode, event.msg)); if (eventResult.type == SipSubscribe.EventResultType.response) {
playBackResult.setData(requestMessage); ResponseEvent responseEvent = (ResponseEvent)eventResult.event;
playBackResult.setEvent(event); String contentString = new String(responseEvent.getResponse().getRawContent());
playBackCallback.call(playBackResult); // 获取ssrc
int ssrcIndex = contentString.indexOf("y=");
// 检查是否有y字段
if (ssrcIndex >= 0) {
//ssrc规定长度为10字节不取余下长度以避免后续还有“f=”字段 TODO 后续对不规范的非10位ssrc兼容
String ssrcInResponse = contentString.substring(ssrcIndex + 2, ssrcIndex + 12);
// 查询到ssrc不一致且开启了ssrc校验则需要针对处理
if (ssrcInfo.getSsrc().equals(ssrcInResponse)) {
return;
}
logger.info("[回放消息] 收到invite 200, 发现下级自定义了ssrc: {}", ssrcInResponse );
if (!mediaServerItem.isRtpEnable() || device.isSsrcCheck()) {
logger.info("[回放消息] SSRC修正 {}->{}", ssrcInfo.getSsrc(), ssrcInResponse);
if (!mediaServerItem.getSsrcConfig().checkSsrc(ssrcInResponse)) {
// ssrc 不可用
// 释放ssrc
mediaServerService.releaseSsrc(mediaServerItem.getId(), ssrcInfo.getSsrc());
streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream()); streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
eventResult.msg = "下级自定义了ssrc,但是此ssrc不可用";
eventResult.statusCode = 400;
errorEvent.response(eventResult);
return;
}
// 单端口模式streamId也有变化需要重新设置监听
if (!mediaServerItem.isRtpEnable()) {
// 添加订阅
HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", ssrcInfo.getStream(), true, "rtsp", mediaServerItem.getId());
subscribe.removeSubscribe(hookSubscribe);
hookSubscribe.getContent().put("stream", String.format("%08x", Integer.parseInt(ssrcInResponse)).toUpperCase());
subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, JSONObject response)->{
logger.info("[ZLM HOOK] ssrc修正后收到订阅消息 " + response.toJSONString());
dynamicTask.stop(playBackTimeOutTaskKey);
// hook响应
onPublishHandlerForPlay(mediaServerItemInUse, response, device.getDeviceId(), channelId, uuid);
hookEvent.call(new InviteStreamInfo(mediaServerItem, null, eventResult.callId, "rtp", ssrcInfo.getStream()));
}); });
}
// 关闭rtp server
mediaServerService.closeRTPServer(device.getDeviceId(), channelId, ssrcInfo.getStream());
// 重新开启ssrc server
mediaServerService.openRTPServer(mediaServerItem, ssrcInfo.getStream(), ssrcInResponse, device.isSsrcCheck(), true, ssrcInfo.getPort());
}
}
}
}, errorEvent);
return result; return result;
} }

View File

@ -236,4 +236,6 @@ public interface IRedisCatchStorage {
void sendStreamPushRequestedMsgForStatus(); void sendStreamPushRequestedMsgForStatus();
List<SendRtpItem> querySendRTPServerByChnnelId(String channelId); List<SendRtpItem> querySendRTPServerByChnnelId(String channelId);
List<SendRtpItem> querySendRTPServerByStream(String stream);
} }

View File

@ -387,6 +387,24 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
return result; return result;
} }
@Override
public List<SendRtpItem> querySendRTPServerByStream(String stream) {
if (stream == null) {
return null;
}
String platformGbId = "*";
String callId = "*";
String channelId = "*";
String key = VideoManagerConstants.PLATFORM_SEND_RTP_INFO_PREFIX + userSetting.getServerId() + "_" + platformGbId
+ "_" + channelId + "_" + stream + "_" + callId;
List<Object> scan = RedisUtil.scan(key);
List<SendRtpItem> result = new ArrayList<>();
for (Object o : scan) {
result.add((SendRtpItem) RedisUtil.get((String) o));
}
return result;
}
@Override @Override
public List<SendRtpItem> querySendRTPServer(String platformGbId) { public List<SendRtpItem> querySendRTPServer(String platformGbId) {
if (platformGbId == null) { if (platformGbId == null) {

View File

@ -37,13 +37,13 @@
<el-form-item label="本地端口" prop="devicePort"> <el-form-item label="本地端口" prop="devicePort">
<el-input v-model="platform.devicePort" :disabled="true" type="number"></el-input> <el-input v-model="platform.devicePort" :disabled="true" type="number"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="SIP认证用户名" prop="username">
<el-input v-model="platform.username"></el-input>
</el-form-item>
</el-form> </el-form>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form ref="platform2" :rules="rules" :model="platform" label-width="160px"> <el-form ref="platform2" :rules="rules" :model="platform" label-width="160px">
<el-form-item label="SIP认证用户名" prop="username">
<el-input v-model="platform.username"></el-input>
</el-form-item>
<el-form-item label="行政区划" prop="administrativeDivision"> <el-form-item label="行政区划" prop="administrativeDivision">
<el-input v-model="platform.administrativeDivision" clearable></el-input> <el-input v-model="platform.administrativeDivision" clearable></el-input>
</el-form-item> </el-form-item>
@ -79,7 +79,7 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="目录结构" prop="treeType" > <el-form-item label="目录结构" prop="treeType" >
<el-select v-model="platform.treeType" style="width: 100%" > <el-select v-model="platform.treeType" style="width: 100%" @change="treeTypeChange">
<el-option key="WGS84" label="行政区划" value="CivilCode"></el-option> <el-option key="WGS84" label="行政区划" value="CivilCode"></el-option>
<el-option key="GCJ02" label="业务分组" value="BusinessGroup"></el-option> <el-option key="GCJ02" label="业务分组" value="BusinessGroup"></el-option>
</el-select> </el-select>
@ -98,6 +98,7 @@
<el-checkbox label="启用" v-model="platform.enable" @change="checkExpires"></el-checkbox> <el-checkbox label="启用" v-model="platform.enable" @change="checkExpires"></el-checkbox>
<el-checkbox label="云台控制" v-model="platform.ptz"></el-checkbox> <el-checkbox label="云台控制" v-model="platform.ptz"></el-checkbox>
<el-checkbox label="拉起离线推流" v-model="platform.startOfflinePush"></el-checkbox> <el-checkbox label="拉起离线推流" v-model="platform.startOfflinePush"></el-checkbox>
<el-checkbox label="RTCP保活" v-model="platform.rtcp" @change="rtcpCheckBoxChange"></el-checkbox>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" @click="onSubmit">{{ <el-button type="primary" @click="onSubmit">{{
@ -251,21 +252,7 @@ export default {
}, },
onSubmit: function () { onSubmit: function () {
if (this.onSubmit_text === "保存") {
this.$confirm("修改目录结构会导致关联目录与通道数据被清空", '提示', {
dangerouslyUseHTMLString: true,
confirmButtonText: '确定',
cancelButtonText: '取消',
center: true,
type: 'warning'
}).then(() => {
this.saveForm() this.saveForm()
}).catch(() => {
});
}else {
this.saveForm()
}
}, },
saveForm: function (){ saveForm: function (){
this.$axios({ this.$axios({
@ -343,6 +330,22 @@ export default {
if (this.platform.enable && this.platform.expires == "0") { if (this.platform.enable && this.platform.expires == "0") {
this.platform.expires = "300"; this.platform.expires = "300";
} }
},
rtcpCheckBoxChange: function (result){
if (result) {
this.$message({
showClose: true,
message: "开启RTCP保活需要上级平台支持可以避免无效推流",
type: "warning",
});
}
},
treeTypeChange: function (){
this.$message({
showClose: true,
message: "修改目录结构会导致关联目录与通道数据被清空,保存后生效",
type: "warning",
});
} }
}, },
}; };