修复协议端口配置不全导致前端播放页面无法弹出的问题

pull/685/head
648540858 2022-11-25 10:50:16 +08:00
parent 278264a2c6
commit fa2ccb4ec8
8 changed files with 144 additions and 69 deletions

View File

@ -169,25 +169,31 @@ public class StreamInfo implements Serializable, Cloneable{
public void setRtmp(String host, int port, int sslPort, String app, String stream, String callIdParam) { public void setRtmp(String host, int port, int sslPort, String app, String stream, String callIdParam) {
String file = String.format("%s/%s/%s", app, stream, callIdParam); String file = String.format("%s/%s/%s", app, stream, callIdParam);
if (port > 0) {
this.rtmp = new StreamURL("rtmp", host, port, file); this.rtmp = new StreamURL("rtmp", host, port, file);
if (sslPort != 0) { }
if (sslPort > 0) {
this.rtmps = new StreamURL("rtmps", host, sslPort, file); this.rtmps = new StreamURL("rtmps", host, sslPort, file);
} }
} }
public void setRtsp(String host, int port, int sslPort, String app, String stream, String callIdParam) { public void setRtsp(String host, int port, int sslPort, String app, String stream, String callIdParam) {
String file = String.format("%s/%s/%s", app, stream, callIdParam); String file = String.format("%s/%s/%s", app, stream, callIdParam);
if (port > 0) {
this.rtsp = new StreamURL("rtsp", host, port, file); this.rtsp = new StreamURL("rtsp", host, port, file);
if (sslPort != 0) { }
if (sslPort > 0) {
this.rtsps = new StreamURL("rtsps", host, sslPort, file); this.rtsps = new StreamURL("rtsps", host, sslPort, file);
} }
} }
public void setFlv(String host, int port, int sslPort, String app, String stream, String callIdParam) { public void setFlv(String host, int port, int sslPort, String app, String stream, String callIdParam) {
String file = String.format("%s/%s.live.flv%s", app, stream, callIdParam); String file = String.format("%s/%s.live.flv%s", app, stream, callIdParam);
if (port > 0) {
this.flv = new StreamURL("http", host, port, file); this.flv = new StreamURL("http", host, port, file);
}
this.ws_flv = new StreamURL("ws", host, port, file); this.ws_flv = new StreamURL("ws", host, port, file);
if (sslPort != 0) { if (sslPort > 0) {
this.https_flv = new StreamURL("https", host, sslPort, file); this.https_flv = new StreamURL("https", host, sslPort, file);
this.wss_flv = new StreamURL("wss", host, sslPort, file); this.wss_flv = new StreamURL("wss", host, sslPort, file);
} }
@ -195,9 +201,11 @@ public class StreamInfo implements Serializable, Cloneable{
public void setFmp4(String host, int port, int sslPort, String app, String stream, String callIdParam) { public void setFmp4(String host, int port, int sslPort, String app, String stream, String callIdParam) {
String file = String.format("%s/%s.live.mp4%s", app, stream, callIdParam); String file = String.format("%s/%s.live.mp4%s", app, stream, callIdParam);
if (port > 0) {
this.fmp4 = new StreamURL("http", host, port, file); this.fmp4 = new StreamURL("http", host, port, file);
this.ws_fmp4 = new StreamURL("ws", host, port, file); this.ws_fmp4 = new StreamURL("ws", host, port, file);
if (sslPort != 0) { }
if (sslPort > 0) {
this.https_fmp4 = new StreamURL("https", host, sslPort, file); this.https_fmp4 = new StreamURL("https", host, sslPort, file);
this.wss_fmp4 = new StreamURL("wss", host, sslPort, file); this.wss_fmp4 = new StreamURL("wss", host, sslPort, file);
} }
@ -205,9 +213,11 @@ public class StreamInfo implements Serializable, Cloneable{
public void setHls(String host, int port, int sslPort, String app, String stream, String callIdParam) { public void setHls(String host, int port, int sslPort, String app, String stream, String callIdParam) {
String file = String.format("%s/%s/hls.m3u8%s", app, stream, callIdParam); String file = String.format("%s/%s/hls.m3u8%s", app, stream, callIdParam);
if (port > 0) {
this.hls = new StreamURL("http", host, port, file); this.hls = new StreamURL("http", host, port, file);
this.ws_hls = new StreamURL("ws", host, port, file); this.ws_hls = new StreamURL("ws", host, port, file);
if (sslPort != 0) { }
if (sslPort > 0) {
this.https_hls = new StreamURL("https", host, sslPort, file); this.https_hls = new StreamURL("https", host, sslPort, file);
this.wss_hls = new StreamURL("wss", host, sslPort, file); this.wss_hls = new StreamURL("wss", host, sslPort, file);
} }
@ -215,9 +225,12 @@ public class StreamInfo implements Serializable, Cloneable{
public void setTs(String host, int port, int sslPort, String app, String stream, String callIdParam) { public void setTs(String host, int port, int sslPort, String app, String stream, String callIdParam) {
String file = String.format("%s/%s.live.ts%s", app, stream, callIdParam); String file = String.format("%s/%s.live.ts%s", app, stream, callIdParam);
if (port > 0) {
this.ts = new StreamURL("http", host, port, file); this.ts = new StreamURL("http", host, port, file);
this.ws_ts = new StreamURL("ws", host, port, file); this.ws_ts = new StreamURL("ws", host, port, file);
if (sslPort != 0) { }
if (sslPort > 0) {
this.https_ts = new StreamURL("https", host, sslPort, file); this.https_ts = new StreamURL("https", host, sslPort, file);
this.wss_ts = new StreamURL("wss", host, sslPort, file); this.wss_ts = new StreamURL("wss", host, sslPort, file);
} }
@ -225,41 +238,78 @@ public class StreamInfo implements Serializable, Cloneable{
public void setRtc(String host, int port, int sslPort, String app, String stream, String callIdParam) { public void setRtc(String host, int port, int sslPort, String app, String stream, String callIdParam) {
String file = String.format("index/api/webrtc?app=%s&stream=%s&type=play%s", app, stream, callIdParam); String file = String.format("index/api/webrtc?app=%s&stream=%s&type=play%s", app, stream, callIdParam);
if (port > 0) {
this.rtc = new StreamURL("http", host, port, file); this.rtc = new StreamURL("http", host, port, file);
if (sslPort != 0) { }
if (sslPort > 0) {
this.rtcs = new StreamURL("https", host, sslPort, file); this.rtcs = new StreamURL("https", host, sslPort, file);
} }
} }
public void channgeStreamIp(String localAddr) { public void channgeStreamIp(String localAddr) {
if (this.flv != null) {
this.flv.setHost(localAddr); this.flv.setHost(localAddr);
}
if (this.ws_flv != null ){
this.ws_flv.setHost(localAddr); this.ws_flv.setHost(localAddr);
}
if (this.hls != null ) {
this.hls.setHost(localAddr); this.hls.setHost(localAddr);
}
if (this.ws_hls != null ) {
this.ws_hls.setHost(localAddr); this.ws_hls.setHost(localAddr);
}
if (this.ts != null ) {
this.ts.setHost(localAddr); this.ts.setHost(localAddr);
}
if (this.ws_ts != null ) {
this.ws_ts.setHost(localAddr); this.ws_ts.setHost(localAddr);
}
if (this.fmp4 != null ) {
this.fmp4.setHost(localAddr); this.fmp4.setHost(localAddr);
}
if (this.ws_fmp4 != null ) {
this.ws_fmp4.setHost(localAddr); this.ws_fmp4.setHost(localAddr);
}
if (this.rtc != null ) {
this.rtc.setHost(localAddr); this.rtc.setHost(localAddr);
}
if (this.https_flv != null) { if (this.https_flv != null) {
this.https_flv.setHost(localAddr); this.https_flv.setHost(localAddr);
}
if (this.wss_flv != null) {
this.wss_flv.setHost(localAddr); this.wss_flv.setHost(localAddr);
}
if (this.https_hls != null) {
this.https_hls.setHost(localAddr); this.https_hls.setHost(localAddr);
}
if (this.wss_hls != null) {
this.wss_hls.setHost(localAddr); this.wss_hls.setHost(localAddr);
}
if (this.wss_ts != null) {
this.wss_ts.setHost(localAddr); this.wss_ts.setHost(localAddr);
}
if (this.https_fmp4 != null) {
this.https_fmp4.setHost(localAddr); this.https_fmp4.setHost(localAddr);
}
if (this.wss_fmp4 != null) {
this.wss_fmp4.setHost(localAddr); this.wss_fmp4.setHost(localAddr);
}
if (this.rtcs != null) {
this.rtcs.setHost(localAddr); this.rtcs.setHost(localAddr);
} }
if (this.rtsp != null) {
this.rtsp.setHost(localAddr); this.rtsp.setHost(localAddr);
}
if (this.rtsps != null) { if (this.rtsps != null) {
this.rtsps.setHost(localAddr); this.rtsps.setHost(localAddr);
} }
if (this.rtmp != null) {
this.rtmp.setHost(localAddr); this.rtmp.setHost(localAddr);
}
if (this.rtmps != null) { if (this.rtmps != null) {
this.rtmps.setHost(localAddr); this.rtmps.setHost(localAddr);
} }
} }

View File

@ -1,7 +1,5 @@
package com.genersoft.iot.vmp.gb28181.bean; package com.genersoft.iot.vmp.gb28181.bean;
import gov.nist.javax.sip.message.SIPRequest;
public class SendRtpItem { public class SendRtpItem {
/** /**
@ -108,6 +106,11 @@ public class SendRtpItem {
*/ */
private boolean onlyAudio = false; private boolean onlyAudio = false;
/**
* rtcp
*/
private boolean rtcp = false;
/** /**
* *
@ -281,4 +284,12 @@ public class SendRtpItem {
public void setToTag(String toTag) { public void setToTag(String toTag) {
this.toTag = toTag; this.toTag = toTag;
} }
public boolean isRtcp() {
return rtcp;
}
public void setRtcp(boolean rtcp) {
this.rtcp = rtcp;
}
} }

View File

@ -120,9 +120,9 @@ 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()) { if (!sendRtpItem.isTcp()) {
// 开启rtcp保活 // 开启rtcp保活
param.put("udp_rtcp_timeout", "1"); param.put("udp_rtcp_timeout", sendRtpItem.isRtcp()? "1":"0");
} }
if (mediaInfo == null) { if (mediaInfo == null) {

View File

@ -341,8 +341,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
return; return;
} }
SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId, SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId,
device.getDeviceId(), channelId, device.getDeviceId(), channelId, mediaTransmissionTCP, platform.isRtcp());
mediaTransmissionTCP);
if (tcpActive != null) { if (tcpActive != null) {
sendRtpItem.setTcpActive(tcpActive); sendRtpItem.setTcpActive(tcpActive);
@ -537,8 +536,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
if (streamReady) { if (streamReady) {
// 自平台内容 // 自平台内容
SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId, SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId,
gbStream.getApp(), gbStream.getStream(), channelId, gbStream.getApp(), gbStream.getStream(), channelId, mediaTransmissionTCP, platform.isRtcp());
mediaTransmissionTCP);
if (sendRtpItem == null) { if (sendRtpItem == null) {
logger.warn("服务器端口资源不足"); logger.warn("服务器端口资源不足");
@ -577,8 +575,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
if (streamReady) { if (streamReady) {
// 自平台内容 // 自平台内容
SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId, SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, port, ssrc, requesterId,
gbStream.getApp(), gbStream.getStream(), channelId, gbStream.getApp(), gbStream.getStream(), channelId, mediaTransmissionTCP, platform.isRtcp());
mediaTransmissionTCP);
if (sendRtpItem == null) { if (sendRtpItem == null) {
logger.warn("服务器端口资源不足"); logger.warn("服务器端口资源不足");
@ -695,7 +692,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
dynamicTask.stop(callIdHeader.getCallId()); dynamicTask.stop(callIdHeader.getCallId());
if (serverId.equals(userSetting.getServerId())) { if (serverId.equals(userSetting.getServerId())) {
SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, finalPort, ssrc, requesterId, SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, addressStr, finalPort, ssrc, requesterId,
app, stream, channelId, mediaTransmissionTCP); app, stream, channelId, mediaTransmissionTCP, platform.isRtcp());
if (sendRtpItem == null) { if (sendRtpItem == null) {
logger.warn("上级点时创建sendRTPItem失败可能是服务器端口资源不足"); logger.warn("上级点时创建sendRTPItem失败可能是服务器端口资源不足");
@ -757,7 +754,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
// 发送redis消息 // 发送redis消息
redisGbPlayMsgListener.sendMsg(streamPushItem.getServerId(), streamPushItem.getMediaServerId(), redisGbPlayMsgListener.sendMsg(streamPushItem.getServerId(), streamPushItem.getMediaServerId(),
streamPushItem.getApp(), streamPushItem.getStream(), addressStr, port, ssrc, requesterId, streamPushItem.getApp(), streamPushItem.getStream(), addressStr, port, ssrc, requesterId,
channelId, mediaTransmissionTCP, null, responseSendItemMsg -> { channelId, mediaTransmissionTCP, platform.isRtcp(),null, responseSendItemMsg -> {
SendRtpItem sendRtpItem = responseSendItemMsg.getSendRtpItem(); SendRtpItem sendRtpItem = responseSendItemMsg.getSendRtpItem();
if (sendRtpItem == null || responseSendItemMsg.getMediaServerItem() == null) { if (sendRtpItem == null || responseSendItemMsg.getMediaServerItem() == null) {
logger.warn("服务器端口资源不足"); logger.warn("服务器端口资源不足");

View File

@ -175,7 +175,7 @@ public class ZLMRTPServerFactory {
* @param tcp tcp * @param tcp tcp
* @return SendRtpItem * @return SendRtpItem
*/ */
public SendRtpItem createSendRtpItem(MediaServerItem serverItem, String ip, int port, String ssrc, String platformId, String deviceId, String channelId, boolean tcp){ public SendRtpItem createSendRtpItem(MediaServerItem serverItem, String ip, int port, String ssrc, String platformId, String deviceId, String channelId, boolean tcp, boolean rtcp){
// 默认为随机端口 // 默认为随机端口
int localPort = 0; int localPort = 0;
@ -195,6 +195,7 @@ public class ZLMRTPServerFactory {
sendRtpItem.setDeviceId(deviceId); sendRtpItem.setDeviceId(deviceId);
sendRtpItem.setChannelId(channelId); sendRtpItem.setChannelId(channelId);
sendRtpItem.setTcp(tcp); sendRtpItem.setTcp(tcp);
sendRtpItem.setRtcp(rtcp);
sendRtpItem.setApp("rtp"); sendRtpItem.setApp("rtp");
sendRtpItem.setLocalPort(localPort); sendRtpItem.setLocalPort(localPort);
sendRtpItem.setServerId(userSetting.getServerId()); sendRtpItem.setServerId(userSetting.getServerId());
@ -212,7 +213,7 @@ public class ZLMRTPServerFactory {
* @param tcp tcp * @param tcp tcp
* @return SendRtpItem * @return SendRtpItem
*/ */
public SendRtpItem createSendRtpItem(MediaServerItem serverItem, String ip, int port, String ssrc, String platformId, String app, String stream, String channelId, boolean tcp){ public SendRtpItem createSendRtpItem(MediaServerItem serverItem, String ip, int port, String ssrc, String platformId, String app, String stream, String channelId, boolean tcp, boolean rtcp){
// 默认为随机端口 // 默认为随机端口
int localPort = 0; int localPort = 0;
if (userSetting.getGbSendStreamStrict()) { if (userSetting.getGbSendStreamStrict()) {
@ -233,6 +234,7 @@ public class ZLMRTPServerFactory {
sendRtpItem.setLocalPort(localPort); sendRtpItem.setLocalPort(localPort);
sendRtpItem.setServerId(userSetting.getServerId()); sendRtpItem.setServerId(userSetting.getServerId());
sendRtpItem.setMediaServerId(serverItem.getId()); sendRtpItem.setMediaServerId(serverItem.getId());
sendRtpItem.setRtcp(rtcp);
return sendRtpItem; return sendRtpItem;
} }

View File

@ -63,10 +63,16 @@ public class RequestSendItemMsg {
private Boolean isTcp; private Boolean isTcp;
/**
* 使TCP
*/
private Boolean rtcp;
public static RequestSendItemMsg getInstance(String serverId, String mediaServerId, String app, String stream, String ip, int port, public static RequestSendItemMsg getInstance(String serverId, String mediaServerId, String app, String stream, String ip, int port,
String ssrc, String platformId, String channelId, Boolean isTcp, String platformName) { String ssrc, String platformId, String channelId, Boolean isTcp, Boolean rtcp, String platformName) {
RequestSendItemMsg requestSendItemMsg = new RequestSendItemMsg(); RequestSendItemMsg requestSendItemMsg = new RequestSendItemMsg();
requestSendItemMsg.setServerId(serverId); requestSendItemMsg.setServerId(serverId);
requestSendItemMsg.setMediaServerId(mediaServerId); requestSendItemMsg.setMediaServerId(mediaServerId);
@ -79,6 +85,7 @@ public class RequestSendItemMsg {
requestSendItemMsg.setPlatformName(platformName); requestSendItemMsg.setPlatformName(platformName);
requestSendItemMsg.setChannelId(channelId); requestSendItemMsg.setChannelId(channelId);
requestSendItemMsg.setTcp(isTcp); requestSendItemMsg.setTcp(isTcp);
requestSendItemMsg.setRtcp(rtcp);
return requestSendItemMsg; return requestSendItemMsg;
} }
@ -170,4 +177,12 @@ public class RequestSendItemMsg {
public void setTcp(Boolean tcp) { public void setTcp(Boolean tcp) {
isTcp = tcp; isTcp = tcp;
} }
public Boolean getRtcp() {
return rtcp;
}
public void setRtcp(Boolean rtcp) {
this.rtcp = rtcp;
}
} }

View File

@ -318,7 +318,7 @@ public class RedisGbPlayMsgListener implements MessageListener {
SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, content.getIp(), SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, content.getIp(),
content.getPort(), content.getSsrc(), content.getPlatformId(), content.getPort(), content.getSsrc(), content.getPlatformId(),
content.getApp(), content.getStream(), content.getChannelId(), content.getApp(), content.getStream(), content.getChannelId(),
content.getTcp()); content.getTcp(), content.getRtcp());
WVPResult<ResponseSendItemMsg> result = new WVPResult<>(); WVPResult<ResponseSendItemMsg> result = new WVPResult<>();
result.setCode(0); result.setCode(0);
@ -348,9 +348,9 @@ public class RedisGbPlayMsgListener implements MessageListener {
* @param callback * @param callback
*/ */
public void sendMsg(String serverId, String mediaServerId, String app, String stream, String ip, int port, String ssrc, public void sendMsg(String serverId, String mediaServerId, String app, String stream, String ip, int port, String ssrc,
String platformId, String channelId, boolean isTcp, String platformName, PlayMsgCallback callback, PlayMsgErrorCallback errorCallback) { String platformId, String channelId, boolean isTcp, boolean rtcp, String platformName, PlayMsgCallback callback, PlayMsgErrorCallback errorCallback) {
RequestSendItemMsg requestSendItemMsg = RequestSendItemMsg.getInstance( RequestSendItemMsg requestSendItemMsg = RequestSendItemMsg.getInstance(
serverId, mediaServerId, app, stream, ip, port, ssrc, platformId, channelId, isTcp, platformName); serverId, mediaServerId, app, stream, ip, port, ssrc, platformId, channelId, isTcp, rtcp, platformName);
requestSendItemMsg.setServerId(serverId); requestSendItemMsg.setServerId(serverId);
String key = UUID.randomUUID().toString(); String key = UUID.randomUUID().toString();
WvpRedisMsg redisMsg = WvpRedisMsg.getRequestInstance(userSetting.getServerId(), serverId, WvpRedisMsgCmd.GET_SEND_ITEM, WvpRedisMsg redisMsg = WvpRedisMsg.getRequestInstance(userSetting.getServerId(), serverId, WvpRedisMsgCmd.GET_SEND_ITEM,

View File

@ -53,91 +53,91 @@
更多地址<i class="el-icon-arrow-down el-icon--right"></i> 更多地址<i class="el-icon-arrow-down el-icon--right"></i>
</el-button> </el-button>
<el-dropdown-menu slot="dropdown" > <el-dropdown-menu slot="dropdown" >
<el-dropdown-item :command="streamInfo.flv.url"> <el-dropdown-item v-if="streamInfo.flv" :command="streamInfo.flv.url">
<el-tag >FLV:</el-tag> <el-tag >FLV:</el-tag>
<span>{{ streamInfo.flv.url }}</span> <span>{{ streamInfo.flv.url }}</span>
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item :command="streamInfo.https_flv.url"> <el-dropdown-item v-if="streamInfo.https_flv" :command="streamInfo.https_flv.url">
<el-tag >FLV(https):</el-tag> <el-tag >FLV(https):</el-tag>
<span>{{ streamInfo.https_flv.url }}</span> <span>{{ streamInfo.https_flv.url }}</span>
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item :command="streamInfo.ws_flv.url"> <el-dropdown-item v-if="streamInfo.ws_flv" :command="streamInfo.ws_flv.url">
<el-tag >FLV(ws):</el-tag> <el-tag >FLV(ws):</el-tag>
<span >{{ streamInfo.ws_flv.url }}</span> <span >{{ streamInfo.ws_flv.url }}</span>
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item :command="streamInfo.wss_flv.url"> <el-dropdown-item v-if="streamInfo.wss_flv" :command="streamInfo.wss_flv.url">
<el-tag >FLV(wss):</el-tag> <el-tag >FLV(wss):</el-tag>
<span>{{ streamInfo.wss_flv.url }}</span> <span>{{ streamInfo.wss_flv.url }}</span>
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item :command="streamInfo.fmp4.url"> <el-dropdown-item v-if="streamInfo.fmp4" :command="streamInfo.fmp4.url">
<el-tag >FMP4:</el-tag> <el-tag >FMP4:</el-tag>
<span>{{ streamInfo.fmp4.url }}</span> <span>{{ streamInfo.fmp4.url }}</span>
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item :command="streamInfo.https_fmp4.url"> <el-dropdown-item v-if="streamInfo.https_fmp4" :command="streamInfo.https_fmp4.url">
<el-tag >FMP4(https):</el-tag> <el-tag >FMP4(https):</el-tag>
<span>{{ streamInfo.https_fmp4.url }}</span> <span>{{ streamInfo.https_fmp4.url }}</span>
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item :command="streamInfo.ws_fmp4.url"> <el-dropdown-item v-if="streamInfo.ws_fmp4" :command="streamInfo.ws_fmp4.url">
<el-tag >FMP4(ws):</el-tag> <el-tag >FMP4(ws):</el-tag>
<span>{{ streamInfo.ws_fmp4.url }}</span> <span>{{ streamInfo.ws_fmp4.url }}</span>
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item :command="streamInfo.wss_fmp4.url"> <el-dropdown-item v-if="streamInfo.wss_fmp4" :command="streamInfo.wss_fmp4.url">
<el-tag >FMP4(wss):</el-tag> <el-tag >FMP4(wss):</el-tag>
<span>{{ streamInfo.wss_fmp4.url }}</span> <span>{{ streamInfo.wss_fmp4.url }}</span>
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item :command="streamInfo.hls.url"> <el-dropdown-item v-if="streamInfo.hls" :command="streamInfo.hls.url">
<el-tag>HLS:</el-tag> <el-tag>HLS:</el-tag>
<span>{{ streamInfo.hls.url }}</span> <span>{{ streamInfo.hls.url }}</span>
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item :command="streamInfo.https_hls.url"> <el-dropdown-item v-if="streamInfo.https_hls" :command="streamInfo.https_hls.url">
<el-tag >HLS(https):</el-tag> <el-tag >HLS(https):</el-tag>
<span>{{ streamInfo.https_hls.url }}</span> <span>{{ streamInfo.https_hls.url }}</span>
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item :command="streamInfo.ws_hls.url"> <el-dropdown-item v-if="streamInfo.ws_hls" :command="streamInfo.ws_hls.url">
<el-tag >HLS(ws):</el-tag> <el-tag >HLS(ws):</el-tag>
<span>{{ streamInfo.ws_hls.url }}</span> <span>{{ streamInfo.ws_hls.url }}</span>
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item :command="streamInfo.wss_hls.url"> <el-dropdown-item v-if="streamInfo.wss_hls" :command="streamInfo.wss_hls.url">
<el-tag >HLS(wss):</el-tag> <el-tag >HLS(wss):</el-tag>
<span>{{ streamInfo.wss_hls.url }}</span> <span>{{ streamInfo.wss_hls.url }}</span>
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item :command="streamInfo.ts.url"> <el-dropdown-item v-if="streamInfo.ts" :command="streamInfo.ts.url">
<el-tag>TS:</el-tag> <el-tag>TS:</el-tag>
<span>{{ streamInfo.ts.url }}</span> <span>{{ streamInfo.ts.url }}</span>
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item :command="streamInfo.https_ts.url"> <el-dropdown-item v-if="streamInfo.https_ts" :command="streamInfo.https_ts.url">
<el-tag>TS(https):</el-tag> <el-tag>TS(https):</el-tag>
<span>{{ streamInfo.https_ts.url }}</span> <span>{{ streamInfo.https_ts.url }}</span>
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item :command="streamInfo.ws_ts.url"> <el-dropdown-item v-if="streamInfo.ws_ts" :command="streamInfo.ws_ts.url">
<el-tag>TS(ws):</el-tag> <el-tag>TS(ws):</el-tag>
<span>{{ streamInfo.ws_ts.url }}</span> <span>{{ streamInfo.ws_ts.url }}</span>
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item :command="streamInfo.wss_ts.url"> <el-dropdown-item v-if="streamInfo.wss_ts" :command="streamInfo.wss_ts.url">
<el-tag>TS(wss):</el-tag> <el-tag>TS(wss):</el-tag>
<span>{{ streamInfo.wss_ts.url }}</span> <span>{{ streamInfo.wss_ts.url }}</span>
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item :command="streamInfo.rtc.url"> <el-dropdown-item v-if="streamInfo.rtc" :command="streamInfo.rtc.url">
<el-tag >RTC:</el-tag> <el-tag >RTC:</el-tag>
<span>{{ streamInfo.rtc.url }}</span> <span>{{ streamInfo.rtc.url }}</span>
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item :command="streamInfo.rtcs.url"> <el-dropdown-item v-if="streamInfo.rtcs" :command="streamInfo.rtcs.url">
<el-tag >RTCS:</el-tag> <el-tag >RTCS:</el-tag>
<span>{{ streamInfo.rtcs }}</span> <span>{{ streamInfo.rtcs }}</span>
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item :command="streamInfo.rtmp.url"> <el-dropdown-item v-if="streamInfo.rtmp" :command="streamInfo.rtmp.url">
<el-tag >RTMP:</el-tag> <el-tag >RTMP:</el-tag>
<span>{{ streamInfo.rtmp.url }}</span> <span>{{ streamInfo.rtmp.url }}</span>
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item :command="streamInfo.rtmps.url"> <el-dropdown-item v-if="streamInfo.rtmps" :command="streamInfo.rtmps.url">
<el-tag >RTMPS:</el-tag> <el-tag >RTMPS:</el-tag>
<span>{{ streamInfo.rtmps.url }}</span> <span>{{ streamInfo.rtmps.url }}</span>
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item :command="streamInfo.rtsp.url"> <el-dropdown-item v-if="streamInfo.rtsp" :command="streamInfo.rtsp.url">
<el-tag >RTSP:</el-tag> <el-tag >RTSP:</el-tag>
<span>{{ streamInfo.rtsp.url }}</span> <span>{{ streamInfo.rtsp.url }}</span>
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item :command="streamInfo.rtsps.url"> <el-dropdown-item v-if="streamInfo.rtsps" :command="streamInfo.rtsps.url">
<el-tag >RTSPS:</el-tag> <el-tag >RTSPS:</el-tag>
<span>{{ streamInfo.rtsps.url }}</span> <span>{{ streamInfo.rtsps.url }}</span>
</el-dropdown-item> </el-dropdown-item>