Merge branch 'wvp-28181-2.0' into wvp-jwt-token

# Conflicts:
#	src/main/java/com/genersoft/iot/vmp/conf/UserSetting.java
#	src/main/resources/all-application.yml
This commit is contained in:
648540858 2023-03-15 22:58:28 +08:00
commit 2bf07305aa
30 changed files with 320 additions and 90 deletions

6
sql/2.6.6-2.6.7更新.sql Executable file
View File

@ -0,0 +1,6 @@
alter table device
add asMessageChannel int default 0;
alter table parent_platform
add asMessageChannel int default 0;

View File

@ -47,6 +47,7 @@ CREATE TABLE `device` (
`mobilePositionSubmissionInterval` int DEFAULT '5', `mobilePositionSubmissionInterval` int DEFAULT '5',
`subscribeCycleForAlarm` int DEFAULT NULL, `subscribeCycleForAlarm` int DEFAULT NULL,
`ssrcCheck` int DEFAULT '0', `ssrcCheck` int DEFAULT '0',
`asMessageChannel` int DEFAULT '0',
`geoCoordSys` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `geoCoordSys` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
`treeType` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `treeType` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
`custom_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL, `custom_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,
@ -329,6 +330,7 @@ CREATE TABLE `parent_platform` (
`catalogId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `catalogId` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
`ptz` int DEFAULT NULL, `ptz` int DEFAULT NULL,
`rtcp` int DEFAULT NULL, `rtcp` int DEFAULT NULL,
`asMessageChannel` int DEFAULT '0',
`status` bit(1) DEFAULT NULL, `status` bit(1) DEFAULT NULL,
`startOfflinePush` int DEFAULT '0', `startOfflinePush` int DEFAULT '0',
`administrativeDivision` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `administrativeDivision` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,

View File

@ -48,6 +48,7 @@ public class UserSetting {
private Boolean syncChannelOnDeviceOnline = Boolean.FALSE; private Boolean syncChannelOnDeviceOnline = Boolean.FALSE;
private Boolean sipLog = Boolean.FALSE; private Boolean sipLog = Boolean.FALSE;
private Boolean sendToPlatformsWhenIdLost = Boolean.FALSE;
private String serverId = "000000"; private String serverId = "000000";
@ -228,4 +229,12 @@ public class UserSetting {
public void setAllowedOrigins(List<String> allowedOrigins) { public void setAllowedOrigins(List<String> allowedOrigins) {
this.allowedOrigins = allowedOrigins; this.allowedOrigins = allowedOrigins;
} }
public Boolean getSendToPlatformsWhenIdLost() {
return sendToPlatformsWhenIdLost;
}
public void setSendToPlatformsWhenIdLost(Boolean sendToPlatformsWhenIdLost) {
this.sendToPlatformsWhenIdLost = sendToPlatformsWhenIdLost;
}
} }

View File

@ -188,6 +188,9 @@ public class Device {
@Schema(description = "SIP交互IP设备访问平台的IP") @Schema(description = "SIP交互IP设备访问平台的IP")
private String localIp; private String localIp;
@Schema(description = "是否作为消息通道")
private boolean asMessageChannel;
public String getDeviceId() { public String getDeviceId() {
return deviceId; return deviceId;
@ -428,4 +431,12 @@ public class Device {
public void setKeepaliveIntervalTime(int keepaliveIntervalTime) { public void setKeepaliveIntervalTime(int keepaliveIntervalTime) {
this.keepaliveIntervalTime = keepaliveIntervalTime; this.keepaliveIntervalTime = keepaliveIntervalTime;
} }
public boolean isAsMessageChannel() {
return asMessageChannel;
}
public void setAsMessageChannel(boolean asMessageChannel) {
this.asMessageChannel = asMessageChannel;
}
} }

View File

@ -189,6 +189,9 @@ public class ParentPlatform {
@Schema(description = "树类型 国标规定了两种树的展现方式 行政区划 CivilCode 和业务分组:BusinessGrou") @Schema(description = "树类型 国标规定了两种树的展现方式 行政区划 CivilCode 和业务分组:BusinessGrou")
private String treeType; private String treeType;
@Schema(description = "是否作为消息通道")
private boolean asMessageChannel;
public Integer getId() { public Integer getId() {
return id; return id;
} }
@ -428,4 +431,12 @@ public class ParentPlatform {
public void setTreeType(String treeType) { public void setTreeType(String treeType) {
this.treeType = treeType; this.treeType = treeType;
} }
public boolean isAsMessageChannel() {
return asMessageChannel;
}
public void setAsMessageChannel(boolean asMessageChannel) {
this.asMessageChannel = asMessageChannel;
}
} }

View File

@ -1,6 +1,8 @@
package com.genersoft.iot.vmp.gb28181.bean; package com.genersoft.iot.vmp.gb28181.bean;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.Instant; import java.time.Instant;
import java.util.List; import java.util.List;
@ -9,22 +11,29 @@ import java.util.List;
* @author: swwheihei * @author: swwheihei
* @date: 2020年5月8日 下午2:05:56 * @date: 2020年5月8日 下午2:05:56
*/ */
@Schema(description = "设备录像查询结果信息")
public class RecordInfo { public class RecordInfo {
@Schema(description = "设备编号")
private String deviceId; private String deviceId;
@Schema(description = "通道编号")
private String channelId; private String channelId;
@Schema(description = "命令序列号")
private String sn; private String sn;
@Schema(description = "设备名称")
private String name; private String name;
@Schema(description = "列表总数")
private int sumNum; private int sumNum;
private int count; private int count;
private Instant lastTime; private Instant lastTime;
@Schema(description = "")
private List<RecordItem> recordList; private List<RecordItem> recordList;
public String getDeviceId() { public String getDeviceId() {

View File

@ -2,9 +2,9 @@ package com.genersoft.iot.vmp.gb28181.bean;
import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.utils.DateUtil;
import io.swagger.v3.oas.annotations.media.Schema;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.text.ParseException;
import java.time.Instant; import java.time.Instant;
import java.time.temporal.TemporalAccessor; import java.time.temporal.TemporalAccessor;
@ -13,26 +13,37 @@ import java.time.temporal.TemporalAccessor;
* @author: swwheihei * @author: swwheihei
* @date: 2020年5月8日 下午2:06:54 * @date: 2020年5月8日 下午2:06:54
*/ */
@Schema(description = "设备录像详情")
public class RecordItem implements Comparable<RecordItem>{ public class RecordItem implements Comparable<RecordItem>{
@Schema(description = "设备编号")
private String deviceId; private String deviceId;
@Schema(description = "名称")
private String name; private String name;
@Schema(description = "文件路径名 (可选)")
private String filePath; private String filePath;
@Schema(description = "录像文件大小,单位:Byte(可选)")
private String fileSize; private String fileSize;
@Schema(description = "录像地址(可选)")
private String address; private String address;
@Schema(description = "录像开始时间(可选)")
private String startTime; private String startTime;
@Schema(description = "录像结束时间(可选)")
private String endTime; private String endTime;
@Schema(description = "保密属性(必选)缺省为0;0:不涉密,1:涉密")
private int secrecy; private int secrecy;
@Schema(description = "录像产生类型(可选)time或alarm 或 manua")
private String type; private String type;
@Schema(description = "录像触发者ID(可选)")
private String recorderId; private String recorderId;
public String getDeviceId() { public String getDeviceId() {

View File

@ -122,7 +122,7 @@ public interface ISIPCommander {
*/ */
void downloadStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, void downloadStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId,
String startTime, String endTime, int downloadSpeed, InviteStreamCallback inviteStreamCallback, InviteStreamCallback hookEvent, String startTime, String endTime, int downloadSpeed, InviteStreamCallback inviteStreamCallback, InviteStreamCallback hookEvent,
SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException; SipSubscribe.Event errorEvent,SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException;
/** /**
* 视频流停止 * 视频流停止
@ -221,7 +221,6 @@ public interface ISIPCommander {
* *
* @param device 视频设备 * @param device 视频设备
* @param channelId 通道id非通道则是设备本身 * @param channelId 通道id非通道则是设备本身
* @param frontCmd 上级平台的指令如果存在则直接下发
* @param enabled 看守位使能1 = 开启0 = 关闭 * @param enabled 看守位使能1 = 开启0 = 关闭
* @param resetTime 自动归位时间间隔开启看守位时使用单位:(s) * @param resetTime 自动归位时间间隔开启看守位时使用单位:(s)
* @param presetIndex 调用预置位编号开启看守位时使用取值范围0~255 * @param presetIndex 调用预置位编号开启看守位时使用取值范围0~255

View File

@ -470,8 +470,9 @@ public class SIPCommander implements ISIPCommander {
*/ */
@Override @Override
public void downloadStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, public void downloadStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId,
String startTime, String endTime, int downloadSpeed, InviteStreamCallback inviteStreamCallback, InviteStreamCallback hookEvent, String startTime, String endTime, int downloadSpeed,
SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException { InviteStreamCallback inviteStreamCallback, InviteStreamCallback hookEvent,
SipSubscribe.Event errorEvent,SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException {
logger.info("{} 分配的ZLM为: {} [{}:{}]", ssrcInfo.getStream(), mediaServerItem.getId(), mediaServerItem.getIp(), ssrcInfo.getPort()); logger.info("{} 分配的ZLM为: {} [{}:{}]", ssrcInfo.getStream(), mediaServerItem.getId(), mediaServerItem.getIp(), ssrcInfo.getPort());
String sdpIp; String sdpIp;
@ -540,11 +541,14 @@ public class SIPCommander implements ISIPCommander {
content.append("a=downloadspeed:" + downloadSpeed + "\r\n"); content.append("a=downloadspeed:" + downloadSpeed + "\r\n");
content.append("y=" + ssrcInfo.getSsrc() + "\r\n");//ssrc content.append("y=" + ssrcInfo.getSsrc() + "\r\n");//ssrc
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, null, mediaServerItem.getId());
// 添加订阅 // 添加订阅
CallIdHeader newCallIdHeader = sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()), device.getTransport());
String callId=newCallIdHeader.getCallId();
subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, JSONObject json) -> { subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, JSONObject json) -> {
hookEvent.call(new InviteStreamInfo(mediaServerItem, json,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()).getCallId(), "rtp", ssrcInfo.getStream())); logger.debug("sipc 添加订阅===callId {}",callId);
hookEvent.call(new InviteStreamInfo(mediaServerItem, json,callId, "rtp", ssrcInfo.getStream()));
subscribe.removeSubscribe(hookSubscribe); subscribe.removeSubscribe(hookSubscribe);
hookSubscribe.getContent().put("regist", false); hookSubscribe.getContent().put("regist", false);
hookSubscribe.getContent().put("schema", "rtsp"); hookSubscribe.getContent().put("schema", "rtsp");
@ -553,7 +557,7 @@ public class SIPCommander implements ISIPCommander {
(MediaServerItem mediaServerItemForEnd, JSONObject jsonForEnd) -> { (MediaServerItem mediaServerItemForEnd, JSONObject jsonForEnd) -> {
logger.info("[录像]下载结束, 发送BYE"); logger.info("[录像]下载结束, 发送BYE");
try { try {
streamByeCmd(device, channelId, ssrcInfo.getStream(),sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()).getCallId()); streamByeCmd(device, channelId, ssrcInfo.getStream(),callId);
} catch (InvalidArgumentException | ParseException | SipException | } catch (InvalidArgumentException | ParseException | SipException |
SsrcTransactionNotFoundException e) { SsrcTransactionNotFoundException e) {
logger.error("[录像]下载结束, 发送BYE失败 {}", e.getMessage()); logger.error("[录像]下载结束, 发送BYE失败 {}", e.getMessage());
@ -561,15 +565,24 @@ public class SIPCommander implements ISIPCommander {
}); });
}); });
Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()), ssrcInfo.getSsrc()); Request request = headerProvider.createPlaybackInviteRequest(device, channelId, content.toString(), null, SipUtils.getNewFromTag(), null,newCallIdHeader, ssrcInfo.getSsrc());
if (inviteStreamCallback != null) { if (inviteStreamCallback != null) {
inviteStreamCallback.call(new InviteStreamInfo(mediaServerItem, null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport()).getCallId(), "rtp", ssrcInfo.getStream())); inviteStreamCallback.call(new InviteStreamInfo(mediaServerItem, null,callId, "rtp", ssrcInfo.getStream()));
} }
sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent, okEvent -> { sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent, event -> {
ResponseEvent responseEvent = (ResponseEvent) okEvent.event; ResponseEvent responseEvent = (ResponseEvent) event.event;
SIPResponse response = (SIPResponse) responseEvent.getResponse(); SIPResponse response = (SIPResponse) responseEvent.getResponse();
streamSession.put(device.getDeviceId(), channelId, response.getCallIdHeader().getCallId(), ssrcInfo.getStream(), ssrcInfo.getSsrc(), mediaServerItem.getId(), response, VideoStreamSessionManager.SessionType.download); String contentString =new String(response.getRawContent());
int ssrcIndex = contentString.indexOf("y=");
String ssrc=ssrcInfo.getSsrc();
if (ssrcIndex >= 0) {
ssrc = contentString.substring(ssrcIndex + 2, ssrcIndex + 12);
}
logger.debug("接收到的下载响应ssrc====>{}",ssrcInfo.getSsrc());
logger.debug("接收到的下载响应ssrc====>{}",ssrc);
streamSession.put(device.getDeviceId(), channelId, response.getCallIdHeader().getCallId(), ssrcInfo.getStream(), ssrc, mediaServerItem.getId(), response, VideoStreamSessionManager.SessionType.download);
okEvent.response(event);
}); });
} }
@ -801,7 +814,6 @@ public class SIPCommander implements ISIPCommander {
* *
* @param device 视频设备 * @param device 视频设备
* @param channelId 通道id非通道则是设备本身 * @param channelId 通道id非通道则是设备本身
* @param frontCmd 上级平台的指令如果存在则直接下发
* @param enabled 看守位使能1 = 开启0 = 关闭 * @param enabled 看守位使能1 = 开启0 = 关闭
* @param resetTime 自动归位时间间隔开启看守位时使用单位:(s) * @param resetTime 自动归位时间间隔开启看守位时使用单位:(s)
* @param presetIndex 调用预置位编号开启看守位时使用取值范围0~255 * @param presetIndex 调用预置位编号开启看守位时使用取值范围0~255
@ -1376,7 +1388,7 @@ public class SIPCommander implements ISIPCommander {
if (device == null) { if (device == null) {
return; return;
} }
logger.info("[发送 报警通知] {}/{}->{},{}", device.getDeviceId(), deviceAlarm.getChannelId(), logger.info("[发送报警通知]设备: {}/{}->{},{}", device.getDeviceId(), deviceAlarm.getChannelId(),
deviceAlarm.getLongitude(), deviceAlarm.getLatitude()); deviceAlarm.getLongitude(), deviceAlarm.getLatitude());
String characterSet = device.getCharset(); String characterSet = device.getCharset();

View File

@ -402,7 +402,7 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
if (parentPlatform == null) { if (parentPlatform == null) {
return; return;
} }
logger.info("[发送报警通知] {}/{}->{},{}: {}", parentPlatform.getServerGBId(), deviceAlarm.getChannelId(), logger.info("[发送报警通知]平台: {}/{}->{},{}: {}", parentPlatform.getServerGBId(), deviceAlarm.getChannelId(),
deviceAlarm.getLongitude(), deviceAlarm.getLatitude(), JSON.toJSONString(deviceAlarm)); deviceAlarm.getLongitude(), deviceAlarm.getLatitude(), JSON.toJSONString(deviceAlarm));
String characterSet = parentPlatform.getCharacterSet(); String characterSet = parentPlatform.getCharacterSet();
StringBuffer deviceStatusXml = new StringBuffer(600); StringBuffer deviceStatusXml = new StringBuffer(600);

View File

@ -163,7 +163,11 @@ public class RecordInfoResponseMessageHandler extends SIPRequestProcessorParent
public void releaseRequest(String deviceId, String sn,RecordInfo recordInfo){ public void releaseRequest(String deviceId, String sn,RecordInfo recordInfo){
String key = DeferredResultHolder.CALLBACK_CMD_RECORDINFO + deviceId + sn; String key = DeferredResultHolder.CALLBACK_CMD_RECORDINFO + deviceId + sn;
// 对数据进行排序 // 对数据进行排序
if(recordInfo!=null && recordInfo.getRecordList()!=null) {
Collections.sort(recordInfo.getRecordList()); Collections.sort(recordInfo.getRecordList());
}else{
recordInfo.setRecordList(new ArrayList<>());
}
RequestMessage msg = new RequestMessage(); RequestMessage msg = new RequestMessage();
msg.setKey(key); msg.setKey(key);

View File

@ -256,6 +256,7 @@ public class ZLMHttpHookListener {
return result; return result;
} }
/** /**
* rtsp/rtmp流注册或注销时触发此事件此事件对回复不敏感 * rtsp/rtmp流注册或注销时触发此事件此事件对回复不敏感
*/ */
@ -279,9 +280,12 @@ public class ZLMHttpHookListener {
subscribe.response(mediaInfo, json); subscribe.response(mediaInfo, json);
} }
} }
// 流消失移除redis play
List<OnStreamChangedHookParam.MediaTrack> tracks = param.getTracks(); List<OnStreamChangedHookParam.MediaTrack> tracks = param.getTracks();
// TODO 重构此处逻辑
if (param.isRegist()) { if (param.isRegist()) {
// 处理流注册的鉴权信息
if (param.getOriginType() == OriginType.RTMP_PUSH.ordinal() if (param.getOriginType() == OriginType.RTMP_PUSH.ordinal()
|| param.getOriginType() == OriginType.RTSP_PUSH.ordinal() || param.getOriginType() == OriginType.RTSP_PUSH.ordinal()
|| param.getOriginType() == OriginType.RTC_PUSH.ordinal()) { || param.getOriginType() == OriginType.RTC_PUSH.ordinal()) {
@ -300,16 +304,15 @@ public class ZLMHttpHookListener {
} }
if ("rtsp".equals(param.getSchema())) { if ("rtsp".equals(param.getSchema())) {
// 更新流媒体负载信息
if (param.isRegist()) { if (param.isRegist()) {
mediaServerService.addCount(param.getMediaServerId()); mediaServerService.addCount(param.getMediaServerId());
} else { } else {
mediaServerService.removeCount(param.getMediaServerId()); mediaServerService.removeCount(param.getMediaServerId());
} }
if (param.getOriginType() == OriginType.PULL.ordinal()
|| param.getOriginType() == OriginType.FFMPEG_PULL.ordinal()) {
// 设置拉流代理上线/离线 // 设置拉流代理上线/离线
streamProxyService.updateStatus(param.isRegist(), param.getApp(), param.getStream()); streamProxyService.updateStatus(param.isRegist(), param.getApp(), param.getStream());
}
if ("rtp".equals(param.getApp()) && !param.isRegist()) { if ("rtp".equals(param.getApp()) && !param.isRegist()) {
StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(param.getStream()); StreamInfo streamInfo = redisCatchStorage.queryPlayByStreamId(param.getStream());
if (streamInfo != null) { if (streamInfo != null) {

View File

@ -635,11 +635,8 @@ public class PlayServiceImpl implements IPlayService {
hookCallBack.call(downloadResult); hookCallBack.call(downloadResult);
streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream()); streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
}; };
InviteStreamCallback hookEvent = (InviteStreamInfo inviteStreamInfo) -> {
try { logger.info("收到订阅消息: " + inviteStreamInfo.getCallId());
cmder.downloadStreamCmd(mediaServerItem, ssrcInfo, device, channelId, startTime, endTime, downloadSpeed, infoCallBack,
inviteStreamInfo -> {
logger.info("收到订阅消息: " + inviteStreamInfo.getResponse().toJSONString());
dynamicTask.stop(downLoadTimeOutTaskKey); dynamicTask.stop(downLoadTimeOutTaskKey);
StreamInfo streamInfo = onPublishHandler(inviteStreamInfo.getMediaServerItem(), inviteStreamInfo.getResponse(), deviceId, channelId); StreamInfo streamInfo = onPublishHandler(inviteStreamInfo.getMediaServerItem(), inviteStreamInfo.getResponse(), deviceId, channelId);
streamInfo.setStartTime(startTime); streamInfo.setStartTime(startTime);
@ -651,7 +648,62 @@ public class PlayServiceImpl implements IPlayService {
downloadResult.setMediaServerItem(inviteStreamInfo.getMediaServerItem()); downloadResult.setMediaServerItem(inviteStreamInfo.getMediaServerItem());
downloadResult.setResponse(inviteStreamInfo.getResponse()); downloadResult.setResponse(inviteStreamInfo.getResponse());
hookCallBack.call(downloadResult); hookCallBack.call(downloadResult);
}, errorEvent); };
try {
cmder.downloadStreamCmd(mediaServerItem, ssrcInfo, device, channelId, startTime, endTime, downloadSpeed, infoCallBack,
hookEvent, errorEvent, eventResult ->
{
if (eventResult.type == SipSubscribe.EventResultType.response) {
ResponseEvent responseEvent = (ResponseEvent) eventResult.event;
String contentString = new String(responseEvent.getResponse().getRawContent());
// 获取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());
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(downLoadTimeOutTaskKey);
// hook响应
onPublishHandlerForPlayback(mediaServerItemInUse, response, device.getDeviceId(), channelId, hookCallBack);
hookEvent.call(new InviteStreamInfo(mediaServerItem, null, eventResult.callId, "rtp", ssrcInfo.getStream()));
});
}
// 关闭rtp server
mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream());
// 重新开启ssrc server
mediaServerService.openRTPServer(mediaServerItem, ssrcInfo.getStream(), ssrcInResponse, device.isSsrcCheck(), true, ssrcInfo.getPort());
}
}
}
});
} catch (InvalidArgumentException | SipException | ParseException e) { } catch (InvalidArgumentException | SipException | ParseException e) {
logger.error("[命令发送失败] 录像下载: {}", e.getMessage()); logger.error("[命令发送失败] 录像下载: {}", e.getMessage());

View File

@ -1,6 +1,7 @@
package com.genersoft.iot.vmp.service.redisMsg; package com.genersoft.iot.vmp.service.redisMsg;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.genersoft.iot.vmp.conf.UserSetting;
import com.genersoft.iot.vmp.gb28181.bean.*; import com.genersoft.iot.vmp.gb28181.bean.*;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform; import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
@ -44,8 +45,12 @@ public class RedisAlarmMsgListener implements MessageListener {
@Autowired @Autowired
private ThreadPoolTaskExecutor taskExecutor; private ThreadPoolTaskExecutor taskExecutor;
@Autowired
private UserSetting userSetting;
@Override @Override
public void onMessage(@NotNull Message message, byte[] bytes) { public void onMessage(@NotNull Message message, byte[] bytes) {
// 消息示例 PUBLISH alarm_receive '{ "gbId": "", "alarmSn": 1, "alarmType": "111", "alarmDescription": "222", }'
logger.info("收到来自REDIS的ALARM通知 {}", new String(message.getBody())); logger.info("收到来自REDIS的ALARM通知 {}", new String(message.getBody()));
boolean isEmpty = taskQueue.isEmpty(); boolean isEmpty = taskQueue.isEmpty();
taskQueue.offer(message); taskQueue.offer(message);
@ -74,6 +79,7 @@ public class RedisAlarmMsgListener implements MessageListener {
deviceAlarm.setLatitude(0); deviceAlarm.setLatitude(0);
if (ObjectUtils.isEmpty(gbId)) { if (ObjectUtils.isEmpty(gbId)) {
if (userSetting.getSendToPlatformsWhenIdLost()) {
// 发送给所有的上级 // 发送给所有的上级
List<ParentPlatform> parentPlatforms = storage.queryEnableParentPlatformList(true); List<ParentPlatform> parentPlatforms = storage.queryEnableParentPlatformList(true);
if (parentPlatforms.size() > 0) { if (parentPlatforms.size() > 0) {
@ -85,6 +91,32 @@ public class RedisAlarmMsgListener implements MessageListener {
} }
} }
} }
}else {
// 获取开启了消息推送的设备和平台
List<ParentPlatform> parentPlatforms = storage.queryEnablePlatformListWithAsMessageChannel();
if (parentPlatforms.size() > 0) {
for (ParentPlatform parentPlatform : parentPlatforms) {
try {
commanderForPlatform.sendAlarmMessage(parentPlatform, deviceAlarm);
} catch (SipException | InvalidArgumentException | ParseException e) {
logger.error("[命令发送失败] 国标级联 发送报警: {}", e.getMessage());
}
}
}
}
// 获取开启了消息推送的设备和平台
List<Device> devices = storage.queryDeviceWithAsMessageChannel();
if (devices.size() > 0) {
for (Device device : devices) {
try {
commander.sendAlarmMessage(device, deviceAlarm);
} catch (InvalidArgumentException | SipException | ParseException e) {
logger.error("[命令发送失败] 发送报警: {}", e.getMessage());
}
}
}
}else { }else {
Device device = storage.queryVideoDevice(gbId); Device device = storage.queryVideoDevice(gbId);
ParentPlatform platform = storage.queryParentPlatByServerGBId(gbId); ParentPlatform platform = storage.queryParentPlatByServerGBId(gbId);

View File

@ -378,4 +378,7 @@ public interface IVideoManagerStorage {
List<DeviceChannelExtend> queryChannelsByDeviceId(String serial, List<String> channelIds, Boolean online); List<DeviceChannelExtend> queryChannelsByDeviceId(String serial, List<String> channelIds, Boolean online);
List<ParentPlatform> queryEnablePlatformListWithAsMessageChannel();
List<Device> queryDeviceWithAsMessageChannel();
} }

View File

@ -344,10 +344,10 @@ public interface DeviceChannelMapper {
"select * " + "select * " +
"from device_channel " + "from device_channel " +
"where deviceId=#{deviceId}" + "where deviceId=#{deviceId}" +
" <if test='parentId != null and length != null' > and parentId = #{parentId} or left(channelId, #{parentId.length()}) = #{parentId} and length(channelId)=#{length} </if>" + " <if test='parentId != null and length != null' > and parentId = #{parentId} or left(channelId, LENGTH(#{parentId})) = #{parentId} and length(channelId)=#{length} </if>" +
" <if test='parentId == null and length != null' > and parentId = #{parentId} or length(channelId)=#{length} </if>" + " <if test='parentId == null and length != null' > and parentId = #{parentId} or length(channelId)=#{length} </if>" +
" <if test='parentId == null and length == null' > and parentId = #{parentId} </if>" + " <if test='parentId == null and length == null' > and parentId = #{parentId} </if>" +
" <if test='parentId != null and length == null' > and parentId = #{parentId} or left(channelId, #{parentId.length()}) = #{parentId} </if>" + " <if test='parentId != null and length == null' > and parentId = #{parentId} or left(channelId, LENGTH(#{parentId})) = #{parentId} </if>" +
" </script>"}) " </script>"})
List<DeviceChannel> getChannelsWithCivilCodeAndLength(String deviceId, String parentId, Integer length); List<DeviceChannel> getChannelsWithCivilCodeAndLength(String deviceId, String parentId, Integer length);

View File

@ -39,6 +39,7 @@ public interface DeviceMapper {
"mobilePositionSubmissionInterval," + "mobilePositionSubmissionInterval," +
"subscribeCycleForAlarm," + "subscribeCycleForAlarm," +
"ssrcCheck," + "ssrcCheck," +
"asMessageChannel," +
"geoCoordSys," + "geoCoordSys," +
"treeType," + "treeType," +
"online" + "online" +
@ -70,6 +71,7 @@ public interface DeviceMapper {
"mobilePositionSubmissionInterval," + "mobilePositionSubmissionInterval," +
"subscribeCycleForAlarm," + "subscribeCycleForAlarm," +
"ssrcCheck," + "ssrcCheck," +
"asMessageChannel," +
"geoCoordSys," + "geoCoordSys," +
"treeType," + "treeType," +
"online" + "online" +
@ -98,6 +100,7 @@ public interface DeviceMapper {
"#{mobilePositionSubmissionInterval}," + "#{mobilePositionSubmissionInterval}," +
"#{subscribeCycleForAlarm}," + "#{subscribeCycleForAlarm}," +
"#{ssrcCheck}," + "#{ssrcCheck}," +
"#{asMessageChannel}," +
"#{geoCoordSys}," + "#{geoCoordSys}," +
"#{treeType}," + "#{treeType}," +
"#{online}" + "#{online}" +
@ -152,6 +155,7 @@ public interface DeviceMapper {
"mobilePositionSubmissionInterval," + "mobilePositionSubmissionInterval," +
"subscribeCycleForAlarm," + "subscribeCycleForAlarm," +
"ssrcCheck," + "ssrcCheck," +
"asMessageChannel," +
"geoCoordSys," + "geoCoordSys," +
"treeType," + "treeType," +
"online," + "online," +
@ -192,6 +196,7 @@ public interface DeviceMapper {
"mobilePositionSubmissionInterval," + "mobilePositionSubmissionInterval," +
"subscribeCycleForAlarm," + "subscribeCycleForAlarm," +
"ssrcCheck," + "ssrcCheck," +
"asMessageChannel," +
"geoCoordSys," + "geoCoordSys," +
"treeType," + "treeType," +
"online " + "online " +
@ -222,6 +227,7 @@ public interface DeviceMapper {
"mobilePositionSubmissionInterval," + "mobilePositionSubmissionInterval," +
"subscribeCycleForAlarm," + "subscribeCycleForAlarm," +
"ssrcCheck," + "ssrcCheck," +
"asMessageChannel," +
"geoCoordSys," + "geoCoordSys," +
"treeType," + "treeType," +
"online" + "online" +
@ -243,6 +249,7 @@ public interface DeviceMapper {
"<if test=\"mobilePositionSubmissionInterval != null\">, mobilePositionSubmissionInterval=#{mobilePositionSubmissionInterval}</if>" + "<if test=\"mobilePositionSubmissionInterval != null\">, mobilePositionSubmissionInterval=#{mobilePositionSubmissionInterval}</if>" +
"<if test=\"subscribeCycleForAlarm != null\">, subscribeCycleForAlarm=#{subscribeCycleForAlarm}</if>" + "<if test=\"subscribeCycleForAlarm != null\">, subscribeCycleForAlarm=#{subscribeCycleForAlarm}</if>" +
"<if test=\"ssrcCheck != null\">, ssrcCheck=#{ssrcCheck}</if>" + "<if test=\"ssrcCheck != null\">, ssrcCheck=#{ssrcCheck}</if>" +
"<if test=\"asMessageChannel != null\">, asMessageChannel=#{asMessageChannel}</if>" +
"<if test=\"geoCoordSys != null\">, geoCoordSys=#{geoCoordSys}</if>" + "<if test=\"geoCoordSys != null\">, geoCoordSys=#{geoCoordSys}</if>" +
"<if test=\"treeType != null\">, treeType=#{treeType}</if>" + "<if test=\"treeType != null\">, treeType=#{treeType}</if>" +
"<if test=\"mediaServerId != null\">, mediaServerId=#{mediaServerId}</if>" + "<if test=\"mediaServerId != null\">, mediaServerId=#{mediaServerId}</if>" +
@ -259,6 +266,7 @@ public interface DeviceMapper {
"updateTime," + "updateTime," +
"charset," + "charset," +
"ssrcCheck," + "ssrcCheck," +
"asMessageChannel," +
"geoCoordSys," + "geoCoordSys," +
"treeType," + "treeType," +
"online" + "online" +
@ -271,6 +279,7 @@ public interface DeviceMapper {
"#{updateTime}," + "#{updateTime}," +
"#{charset}," + "#{charset}," +
"#{ssrcCheck}," + "#{ssrcCheck}," +
"#{asMessageChannel}," +
"#{geoCoordSys}," + "#{geoCoordSys}," +
"#{treeType}," + "#{treeType}," +
"#{online}" + "#{online}" +
@ -282,4 +291,7 @@ public interface DeviceMapper {
@Select("select * from device") @Select("select * from device")
List<Device> getAll(); List<Device> getAll();
@Select("select * from device where asMessageChannel = 1")
List<Device> queryDeviceWithAsMessageChannel();
} }

View File

@ -15,10 +15,10 @@ import java.util.List;
public interface ParentPlatformMapper { public interface ParentPlatformMapper {
@Insert("INSERT INTO parent_platform (enable, name, serverGBId, serverGBDomain, serverIP, serverPort, deviceGBId, deviceIp, " + @Insert("INSERT INTO parent_platform (enable, name, serverGBId, serverGBDomain, serverIP, serverPort, deviceGBId, deviceIp, " +
" devicePort, username, password, expires, keepTimeout, transport, characterSet, ptz, rtcp, " + " devicePort, username, password, expires, keepTimeout, transport, characterSet, ptz, rtcp, asMessageChannel, " +
" status, startOfflinePush, catalogId, administrativeDivision, catalogGroup, createTime, updateTime, treeType) " + " status, startOfflinePush, catalogId, administrativeDivision, catalogGroup, createTime, updateTime, treeType) " +
" VALUES (#{enable}, #{name}, #{serverGBId}, #{serverGBDomain}, #{serverIP}, #{serverPort}, #{deviceGBId}, #{deviceIp}, " + " VALUES (#{enable}, #{name}, #{serverGBId}, #{serverGBDomain}, #{serverIP}, #{serverPort}, #{deviceGBId}, #{deviceIp}, " +
" #{devicePort}, #{username}, #{password}, #{expires}, #{keepTimeout}, #{transport}, #{characterSet}, #{ptz}, #{rtcp}, " + " #{devicePort}, #{username}, #{password}, #{expires}, #{keepTimeout}, #{transport}, #{characterSet}, #{ptz}, #{rtcp}, #{asMessageChannel}, " +
" #{status}, #{startOfflinePush}, #{catalogId}, #{administrativeDivision}, #{catalogGroup}, #{createTime}, #{updateTime}, #{treeType})") " #{status}, #{startOfflinePush}, #{catalogId}, #{administrativeDivision}, #{catalogGroup}, #{createTime}, #{updateTime}, #{treeType})")
int addParentPlatform(ParentPlatform parentPlatform); int addParentPlatform(ParentPlatform parentPlatform);
@ -40,6 +40,7 @@ public interface ParentPlatformMapper {
"characterSet=#{characterSet}, " + "characterSet=#{characterSet}, " +
"ptz=#{ptz}, " + "ptz=#{ptz}, " +
"rtcp=#{rtcp}, " + "rtcp=#{rtcp}, " +
"asMessageChannel=#{asMessageChannel}, " +
"status=#{status}, " + "status=#{status}, " +
"startOfflinePush=#{startOfflinePush}, " + "startOfflinePush=#{startOfflinePush}, " +
"catalogGroup=#{catalogGroup}, " + "catalogGroup=#{catalogGroup}, " +
@ -68,9 +69,12 @@ public interface ParentPlatformMapper {
"FROM parent_platform pp ") "FROM parent_platform pp ")
List<ParentPlatform> getParentPlatformList(); List<ParentPlatform> getParentPlatformList();
@Select("SELECT * FROM parent_platform WHERE enable=#{enable}") @Select("SELECT * FROM parent_platform WHERE enable=#{enable} ")
List<ParentPlatform> getEnableParentPlatformList(boolean enable); List<ParentPlatform> getEnableParentPlatformList(boolean enable);
@Select("SELECT * FROM parent_platform WHERE enable=1 and asMessageChannel = 1")
List<ParentPlatform> queryEnablePlatformListWithAsMessageChannel();
@Select("SELECT * FROM parent_platform WHERE serverGBId=#{platformGbId}") @Select("SELECT * FROM parent_platform WHERE serverGBId=#{platformGbId}")
ParentPlatform getParentPlatByServerGBId(String platformGbId); ParentPlatform getParentPlatByServerGBId(String platformGbId);

View File

@ -177,12 +177,14 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
@Override @Override
public boolean startDownload(StreamInfo stream, String callId) { public boolean startDownload(StreamInfo stream, String callId) {
boolean result; boolean result;
String key=String.format("%S_%s_%s_%s_%s_%s_%s", VideoManagerConstants.DOWNLOAD_PREFIX,
userSetting.getServerId(), stream.getMediaServerId(), stream.getDeviceID(), stream.getChannelId(), stream.getStream(), callId);
if (stream.getProgress() == 1) { if (stream.getProgress() == 1) {
result = RedisUtil.set(String.format("%S_%s_%s_%s_%s_%s_%s", VideoManagerConstants.DOWNLOAD_PREFIX, logger.debug("添加下载缓存==已完成下载=》{}",key);
userSetting.getServerId(), stream.getMediaServerId(), stream.getDeviceID(), stream.getChannelId(), stream.getStream(), callId), stream); result = RedisUtil.set(key, stream);
}else { }else {
result = RedisUtil.set(String.format("%S_%s_%s_%s_%s_%s_%s", VideoManagerConstants.DOWNLOAD_PREFIX, logger.debug("添加下载缓存==未完成下载=》{}",key);
userSetting.getServerId(), stream.getMediaServerId(), stream.getDeviceID(), stream.getChannelId(), stream.getStream(), callId), stream, 60*60); result = RedisUtil.set(key, stream, 60*60);
} }
return result; return result;
} }
@ -617,7 +619,7 @@ public class RedisCatchStorageImpl implements IRedisCatchStorage {
stream, stream,
callId callId
); );
List<Object> streamInfoScan = RedisUtil.scan(key); List<Object> streamInfoScan = RedisUtil.scan2(key);
if (streamInfoScan.size() > 0) { if (streamInfoScan.size() > 0) {
return (StreamInfo) RedisUtil.get((String) streamInfoScan.get(0)); return (StreamInfo) RedisUtil.get((String) streamInfoScan.get(0));
}else { }else {

View File

@ -524,6 +524,16 @@ public class VideoManagerStorageImpl implements IVideoManagerStorage {
return platformMapper.getEnableParentPlatformList(enable); return platformMapper.getEnableParentPlatformList(enable);
} }
@Override
public List<ParentPlatform> queryEnablePlatformListWithAsMessageChannel() {
return platformMapper.queryEnablePlatformListWithAsMessageChannel();
}
@Override
public List<Device> queryDeviceWithAsMessageChannel() {
return deviceMapper.queryDeviceWithAsMessageChannel();
}
@Override @Override
public void outlineForAllParentPlatform() { public void outlineForAllParentPlatform() {
platformMapper.outlineForAllParentPlatform(); platformMapper.outlineForAllParentPlatform();

View File

@ -881,7 +881,13 @@ public class RedisUtil {
return new ArrayList<>(resultKeys); return new ArrayList<>(resultKeys);
} }
public static List<Object> scan2(String query) {
if (redisTemplate == null) {
redisTemplate = SpringBeanFactory.getBean("redisTemplate");
}
Set<String> keys = redisTemplate.keys(query);
return new ArrayList<>(keys);
}
// ============================== 消息发送与订阅 ============================== // ============================== 消息发送与订阅 ==============================
public static void convertAndSend(String channel, JSONObject msg) { public static void convertAndSend(String channel, JSONObject msg) {
if (redisTemplate == null) { if (redisTemplate == null) {

View File

@ -199,8 +199,8 @@ user-settings:
sip-use-source-ip-as-remote-address: false sip-use-source-ip-as-remote-address: false
# 是否开启sip日志 # 是否开启sip日志
sip-log: true sip-log: true
# 自动数据库升级,保证表结构完整 # 消息通道功能-缺少国标ID是否给所有上级发送消息
sync-db: true send-to-platforms-when-id-lost: true
# 跨域配置,配置你访问前端页面的地址即可, 可以配置多个 # 跨域配置,配置你访问前端页面的地址即可, 可以配置多个
allowed-origins: allowed-origins:
- http://localhost:8008 - http://localhost:8008

View File

@ -15,5 +15,6 @@
<script type="text/javascript" src="./static/js/ZLMRTCClient.js"></script> <script type="text/javascript" src="./static/js/ZLMRTCClient.js"></script>
<script type="text/javascript" src="./static/js/config.js"></script> <script type="text/javascript" src="./static/js/config.js"></script>
<div id="app"></div> <div id="app"></div>
</body> </body>
</html> </html>

View File

@ -1,5 +1,6 @@
<template> <template>
<div ref="container" @dblclick="fullscreenSwich" style="width:100%;height:100%;background-color: #000000;margin:0 auto;"> <div ref="container" @dblclick="fullscreenSwich"
style="width:100%;height:100%;background-color: #000000;margin:0 auto;">
<div class="buttons-box" id="buttonsBox"> <div class="buttons-box" id="buttonsBox">
<div class="buttons-box-left"> <div class="buttons-box-left">
<i v-if="!playing" class="iconfont icon-play jessibuca-btn" @click="playBtnClick"></i> <i v-if="!playing" class="iconfont icon-play jessibuca-btn" @click="playBtnClick"></i>
@ -12,7 +13,7 @@
<span class="jessibuca-btn">{{ kBps }} kb/s</span> <span class="jessibuca-btn">{{ kBps }} kb/s</span>
<!-- <i class="iconfont icon-file-record1 jessibuca-btn"></i>--> <!-- <i class="iconfont icon-file-record1 jessibuca-btn"></i>-->
<!-- <i class="iconfont icon-xiangqing2 jessibuca-btn" ></i>--> <!-- <i class="iconfont icon-xiangqing2 jessibuca-btn" ></i>-->
<i class="iconfont icon-camera1196054easyiconnet jessibuca-btn" @click="jessibuca.screenshot('截图','png',0.5)" <i class="iconfont icon-camera1196054easyiconnet jessibuca-btn" @click="screenshot"
style="font-size: 1rem !important"></i> style="font-size: 1rem !important"></i>
<i class="iconfont icon-shuaxin11 jessibuca-btn" @click="playBtnClick"></i> <i class="iconfont icon-shuaxin11 jessibuca-btn" @click="playBtnClick"></i>
<i v-if="!fullscreen" class="iconfont icon-weibiaoti10 jessibuca-btn" @click="fullscreenSwich"></i> <i v-if="!fullscreen" class="iconfont icon-weibiaoti10 jessibuca-btn" @click="fullscreenSwich"></i>
@ -92,29 +93,49 @@ export default {
jessibucaPlayer[this._uid] = new window.Jessibuca(Object.assign( jessibucaPlayer[this._uid] = new window.Jessibuca(Object.assign(
{ {
container: this.$refs.container, container: this.$refs.container,
videoBuffer: 0.2, // autoWasm: true,
isResize: true, background: "",
decoder: "static/js/jessibuca/decoder.js", controlAutoHide: false,
useMSE: false,
showBandwidth: false,
isFlv: true,
// text: "WVP-PRO",
// background: "static/images/zlm-logo.png",
loadingText: "加载中",
hasAudio: typeof (this.hasAudio) == "undefined" ? true : this.hasAudio,
debug: false, debug: false,
supportDblclickFullscreen: false, // decoder: "static/js/jessibuca/decoder.js",
forceNoOffscreen: true,
hasAudio: typeof (this.hasAudio) == "undefined" ? true : this.hasAudio,
hasVideo: true,
heartTimeout: 5,
heartTimeoutReplay: true,
heartTimeoutReplayTimes: 3,
hiddenAutoPause: false,
hotKey: false,
isFlv: false,
isFullResize: false,
isNotMute: this.isNotMute,
isResize: false,
keepScreenOn: false,
loadingText: "请稍等, 视频加载中......",
loadingTimeout: 10,
loadingTimeoutReplay: true,
loadingTimeoutReplayTimes: 3,
openWebglAlignment: false,
operateBtns: { operateBtns: {
fullscreen: false, fullscreen: false,
screenshot: false, screenshot: false,
play: false, play: false,
audio: false, audio: false,
recorder: false, record: false
}, },
record: "record", recordType: "webm",
vod: this.vod, rotate: 0,
forceNoOffscreen: this.forceNoOffscreen, showBandwidth: false,
isNotMute: this.isNotMute, supportDblclickFullscreen: false,
timeout: 10,
useMSE: location.hostname !== "localhost" && location.protocol !== "https:",
useOffscreen: false,
useWCS: location.hostname === "localhost" || location.protocol === "https",
useWebFullScreen: false,
videoBuffer: 0,
wasmDecodeAudioSyncVideo: true,
wasmDecodeErrorReplay: true,
wcsUseVideoRender: true
}, },
options options
)); ));
@ -243,6 +264,11 @@ export default {
this.err = ""; this.err = "";
this.performance = ""; this.performance = "";
}, },
screenshot: function () {
if (jessibucaPlayer[this._uid]) {
jessibucaPlayer[this._uid].screenshot();
}
},
mute: function () { mute: function () {
if (jessibucaPlayer[this._uid]) { if (jessibucaPlayer[this._uid]) {
jessibucaPlayer[this._uid].mute(); jessibucaPlayer[this._uid].mute();

View File

@ -66,6 +66,7 @@
</el-form-item> </el-form-item>
<el-form-item label="其他选项"> <el-form-item label="其他选项">
<el-checkbox label="SSRC校验" v-model="form.ssrcCheck" style="float: left"></el-checkbox> <el-checkbox label="SSRC校验" v-model="form.ssrcCheck" style="float: left"></el-checkbox>
<el-checkbox label="作为消息通道" v-model="form.asMessageChannel" style="float: left"></el-checkbox>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<div style="float: right;"> <div style="float: right;">

View File

@ -96,9 +96,10 @@
</el-form-item> </el-form-item>
<el-form-item label="其他选项"> <el-form-item label="其他选项">
<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-checkbox label="RTCP保活" v-model="platform.rtcp" @change="rtcpCheckBoxChange"></el-checkbox>
<el-checkbox label="作为消息通道" v-model="platform.asMessageChannel" ></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">{{
@ -145,6 +146,7 @@ export default {
enable: true, enable: true,
ptz: true, ptz: true,
rtcp: false, rtcp: false,
asMessageChannel: false,
name: null, name: null,
serverGBId: null, serverGBId: null,
serverGBDomain: null, serverGBDomain: null,
@ -213,6 +215,7 @@ export default {
this.platform.enable = platform.enable; this.platform.enable = platform.enable;
this.platform.ptz = platform.ptz; this.platform.ptz = platform.ptz;
this.platform.rtcp = platform.rtcp; this.platform.rtcp = platform.rtcp;
this.platform.rtcpasMessageChannel = platform.asMessageChannel;
this.platform.name = platform.name; this.platform.name = platform.name;
this.platform.serverGBId = platform.serverGBId; this.platform.serverGBId = platform.serverGBId;
this.platform.serverGBDomain = platform.serverGBDomain; this.platform.serverGBDomain = platform.serverGBDomain;
@ -290,6 +293,7 @@ export default {
enable: true, enable: true,
ptz: true, ptz: true,
rtcp: false, rtcp: false,
asMessageChannel: false,
name: null, name: null,
serverGBId: null, serverGBId: null,
administrativeDivision: null, administrativeDivision: null,

File diff suppressed because one or more lines are too long

View File

@ -62,7 +62,7 @@ declare namespace Jessibuca {
/** /**
* 1. `true`,canvas区域,,, `setScaleMode(2)` * 1. `true`,canvas区域,,, `setScaleMode(2)`
*/ */
isFullSize?: boolean; isFullResize?: boolean;
/** /**
* 1. `true`ws协议不检验是否以.flv为依据 * 1. `true`ws协议不检验是否以.flv为依据
*/ */
@ -120,7 +120,7 @@ declare namespace Jessibuca {
/** /**
* *
*/ */
loadingText?: boolean; loadingText?: string;
/** /**
* *
*/ */

File diff suppressed because one or more lines are too long