From a064f27bf821dc70ba60a131dbb6154e970d8e95 Mon Sep 17 00:00:00 2001 From: lin <648540858@qq.com> Date: Thu, 18 Sep 2025 18:53:12 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81ABL=E9=A3=8E=E6=A0=BC?= =?UTF-8?q?=E5=9C=B0=E5=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../genersoft/iot/vmp/common/StreamInfo.java | 80 ++++-- .../genersoft/iot/vmp/conf/MediaConfig.java | 38 +-- .../media/abl/ABLMediaNodeServerService.java | 134 ++++++--- .../media/abl/ABLMediaServerStatusManger.java | 85 +++--- .../iot/vmp/media/abl/ABLRESTfulUtils.java | 14 + .../iot/vmp/media/bean/MediaServer.java | 15 +- .../service/IMediaNodeServerService.java | 6 +- .../media/service/IMediaServerService.java | 4 +- .../service/impl/MediaServerServiceImpl.java | 74 +---- .../media/zlm/ZLMMediaNodeServerService.java | 127 +++++---- .../iot/vmp/service/ICloudRecordService.java | 4 +- .../service/impl/CloudRecordServiceImpl.java | 8 +- .../vmp/storager/dao/MediaServerMapper.java | 4 + .../iot/vmp/vmanager/bean/StreamContent.java | 261 +----------------- .../cloudRecord/CloudRecordController.java | 10 +- web/src/api/cloudRecord.js | 6 +- web/src/views/cloudRecord/detail.vue | 2 + web/src/views/cloudRecord/index.vue | 22 +- 18 files changed, 346 insertions(+), 548 deletions(-) diff --git a/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java b/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java index 941bdebee..f2d1df4cb 100644 --- a/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java +++ b/src/main/java/com/genersoft/iot/vmp/common/StreamInfo.java @@ -101,84 +101,108 @@ public class StreamInfo implements Serializable, Cloneable{ @Schema(description = "使用的WVP ID") private String serverId; - public void setRtmp(String host, int port, int sslPort, String app, String stream, String callIdParam) { + @Schema(description = "流绑定的流媒体操作key") + private String key; + + public void setRtmp(String host, Integer port, Integer sslPort, String app, String stream, String callIdParam) { String file = String.format("%s/%s%s", app, stream, callIdParam); - if (port > 0) { + if (port != null && port > 0) { this.rtmp = new StreamURL("rtmp", host, port, file); } - if (sslPort > 0) { + if (sslPort != null && sslPort > 0) { 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, Integer port, Integer sslPort, String app, String stream, String callIdParam) { String file = String.format("%s/%s%s", app, stream, callIdParam); - if (port > 0) { + if (port != null && port > 0) { this.rtsp = new StreamURL("rtsp", host, port, file); } - if (sslPort > 0) { + if (sslPort != null && sslPort > 0) { this.rtsps = new StreamURL("rtsps", host, sslPort, file); } } - public void setFlv(String host, int port, int sslPort, String file) { - if (port > 0) { + public void setFlv(String host, Integer port, Integer sslPort, String file) { + if (port != null && port > 0) { this.flv = new StreamURL("http", host, port, file); } - this.ws_flv = new StreamURL("ws", host, port, file); - if (sslPort > 0) { + if (sslPort != null && sslPort > 0) { this.https_flv = new StreamURL("https", host, sslPort, file); - this.wss_flv = new StreamURL("wss", host, sslPort, file); } } - public void setWsFlv(String host, int port, int sslPort, String file) { - if (port > 0) { + public void setWsFlv(String host, Integer port, Integer sslPort, String file) { + if (port != null && port > 0) { this.ws_flv = new StreamURL("ws", host, port, file); } - if (sslPort > 0) { + if (sslPort != null && sslPort > 0) { this.wss_flv = new StreamURL("wss", host, sslPort, file); } } - 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); - if (port > 0) { + public void setFmp4(String host, Integer port, Integer sslPort, String file) { + if (port != null && port > 0) { this.fmp4 = new StreamURL("http", host, port, file); + } + if (sslPort != null && sslPort > 0) { + this.https_fmp4 = new StreamURL("https", host, sslPort, file); + } + } + + public void setWsMp4(String host, Integer port, Integer sslPort, String file) { + if (port != null && port > 0) { this.ws_fmp4 = new StreamURL("ws", host, port, file); } - if (sslPort > 0) { - this.https_fmp4 = new StreamURL("https", host, sslPort, file); + if (sslPort != null && sslPort > 0) { this.wss_fmp4 = new StreamURL("wss", host, sslPort, file); } } - public void setHls(String host, int port, int sslPort, String app, String stream, String callIdParam) { + public void setHls(String host, Integer port, Integer sslPort, String app, String stream, String callIdParam) { String file = String.format("%s/%s/hls.m3u8%s", app, stream, callIdParam); - if (port > 0) { + if (port != null && port > 0) { this.hls = new StreamURL("http", host, port, file); + } + if (sslPort != null && sslPort > 0) { + this.https_hls = new StreamURL("https", host, sslPort, file); + } + } + + public void setWsHls(String host, Integer port, Integer sslPort, String app, String stream, String callIdParam) { + String file = String.format("%s/%s/hls.m3u8%s", app, stream, callIdParam); + if (port != null && port > 0) { this.ws_hls = new StreamURL("ws", host, port, file); } - if (sslPort > 0) { - this.https_hls = new StreamURL("https", host, sslPort, file); + if (sslPort != null && sslPort > 0) { this.wss_hls = new StreamURL("wss", host, sslPort, file); } } - public void setTs(String host, int port, int sslPort, String app, String stream, String callIdParam) { + public void setTs(String host, Integer port, Integer sslPort, String app, String stream, String callIdParam) { String file = String.format("%s/%s.live.ts%s", app, stream, callIdParam); - if (port > 0) { + if (port != null && port > 0) { this.ts = new StreamURL("http", host, port, file); + } + if (sslPort != null && sslPort > 0) { + this.https_ts = new StreamURL("https", host, sslPort, file); + } + } + + public void setWsTs(String host, Integer port, Integer sslPort, String app, String stream, String callIdParam) { + String file = String.format("%s/%s.live.ts%s", app, stream, callIdParam); + + if (port != null && port > 0) { this.ws_ts = new StreamURL("ws", host, port, file); } - if (sslPort > 0) { - this.https_ts = new StreamURL("https", host, sslPort, file); + if (sslPort != null && sslPort > 0) { this.wss_ts = new StreamURL("wss", host, sslPort, file); } } - public void setRtc(String host, int port, int sslPort, String app, String stream, String callIdParam, boolean isPlay) { + public void setRtc(String host, Integer port, Integer sslPort, String app, String stream, String callIdParam, boolean isPlay) { if (callIdParam != null) { callIdParam = Objects.equals(callIdParam, "") ? callIdParam : callIdParam.replace("?", "&"); } diff --git a/src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java b/src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java index ab75494c5..51a586c97 100644 --- a/src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java +++ b/src/main/java/com/genersoft/iot/vmp/conf/MediaConfig.java @@ -59,9 +59,6 @@ public class MediaConfig{ @Value("${media.flv-ssl-port:0}") private Integer flvSSlPort = 0; - @Value("${media.mp4-ssl-port:0}") - private Integer mp4SSlPort = 0; - @Value("${media.ws-flv-ssl-port:0}") private Integer wsFlvSSlPort = 0; @@ -165,36 +162,11 @@ public class MediaConfig{ mediaServer.setSdpIp(getSdpIp()); mediaServer.setStreamIp(getStreamIp()); mediaServer.setHttpPort(httpPort); - if (flvPort == 0) { - mediaServer.setFlvPort(httpPort); - }else { - mediaServer.setFlvPort(flvPort); - } - if (mp4Port == 0) { - mediaServer.setMp4Port(httpPort); - }else { - mediaServer.setMp4Port(mp4Port); - } - if (wsFlvPort == 0) { - mediaServer.setWsFlvPort(httpPort); - }else { - mediaServer.setWsFlvPort(wsFlvPort); - } - if (flvSSlPort == 0) { - mediaServer.setFlvSSLPort(httpSSlPort); - }else { - mediaServer.setFlvSSLPort(flvSSlPort); - } - if (mp4SSlPort == 0) { - mediaServer.setMp4SSLPort(httpSSlPort); - }else { - mediaServer.setMp4SSLPort(mp4SSlPort); - } - if (wsFlvSSlPort == 0) { - mediaServer.setWsFlvSSLPort(httpSSlPort); - }else { - mediaServer.setWsFlvSSLPort(wsFlvSSlPort); - } + mediaServer.setFlvPort(flvPort); + mediaServer.setMp4Port(mp4Port); + mediaServer.setWsFlvPort(wsFlvPort); + mediaServer.setFlvSSLPort(flvSSlPort); + mediaServer.setWsFlvSSLPort(wsFlvSSlPort); mediaServer.setHttpSSlPort(httpSSlPort); mediaServer.setRtmpPort(rtmpPort); diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java index 403833f3d..3c1333bc1 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaNodeServerService.java @@ -26,6 +26,7 @@ import com.genersoft.iot.vmp.streamProxy.bean.StreamProxy; import com.genersoft.iot.vmp.utils.DateUtil; import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; import com.genersoft.iot.vmp.vmanager.bean.WVPResult; +import lombok.extern.slf4j.Slf4j; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -40,6 +41,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +@Slf4j @Service("abl") public class ABLMediaNodeServerService implements IMediaNodeServerService { @@ -169,7 +171,7 @@ public class ABLMediaNodeServerService implements IMediaNodeServerService { for (int i = 0; i < result.getMediaList().size(); i++) { ABLMedia ablMedia = result.getMediaList().get(i); MediaInfo mediaInfo = MediaInfo.getInstance(ablMedia, mediaServer); - StreamInfo streamInfo = getStreamInfoByAppAndStream(mediaServer, app, stream, mediaInfo, callId, true); + StreamInfo streamInfo = getStreamInfoByAppAndStream(mediaServer, app, stream, mediaInfo, null, callId, true); if (streamInfo != null) { streamInfoList.add(streamInfo); } @@ -177,27 +179,82 @@ public class ABLMediaNodeServerService implements IMediaNodeServerService { return streamInfoList; } - public StreamInfo getStreamInfoByAppAndStream(MediaServer mediaServer, String app, String stream, MediaInfo mediaInfo, String callId, boolean isPlay) { + @Override + public StreamInfo getStreamInfoByAppAndStream(MediaServer mediaServer, String app, String stream, MediaInfo mediaInfo, + String addr, String callId, boolean isPlay) { StreamInfo streamInfoResult = new StreamInfo(); streamInfoResult.setStream(stream); streamInfoResult.setApp(app); - String addr = mediaServer.getStreamIp(); + if (addr == null) { + addr = mediaServer.getStreamIp(); + } + streamInfoResult.setIp(addr); + if (mediaInfo != null) { + streamInfoResult.setServerId(mediaInfo.getServerId()); + }else { + streamInfoResult.setServerId(userSetting.getServerId()); + } + streamInfoResult.setMediaServer(mediaServer); - String callIdParam = ObjectUtils.isEmpty(callId)?"":"?callId=" + callId; + Map param = new HashMap<>(); + if (!ObjectUtils.isEmpty(callId)) { + param.put("callId", callId); + } + if (mediaInfo != null && !ObjectUtils.isEmpty(mediaInfo.getOriginTypeStr())) { + param.put("originTypeStr", mediaInfo.getOriginTypeStr()); + } + StringBuilder callIdParamBuilder = new StringBuilder(); + if (!param.isEmpty()) { + callIdParamBuilder.append("?"); + for (Map.Entry entry : param.entrySet()) { + callIdParamBuilder.append(entry.getKey()).append("=").append(entry.getValue()); + callIdParamBuilder.append("&"); + } + callIdParamBuilder.deleteCharAt(callIdParamBuilder.length() - 1); + } + + String callIdParam = callIdParamBuilder.toString(); + streamInfoResult.setRtmp(addr, mediaServer.getRtmpPort(),mediaServer.getRtmpSSlPort(), app, stream, callIdParam); streamInfoResult.setRtsp(addr, mediaServer.getRtspPort(),mediaServer.getRtspSSLPort(), app, stream, callIdParam); - String flvFile = String.format("%s/%s.flv%s", app, stream, callIdParam); - streamInfoResult.setFlv(addr, mediaServer.getFlvPort(),mediaServer.getHttpSSlPort(), flvFile); - streamInfoResult.setWsFlv(addr, mediaServer.getWsFlvPort(),mediaServer.getHttpSSlPort(), flvFile); - streamInfoResult.setFmp4(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam); - streamInfoResult.setHls(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam); - streamInfoResult.setTs(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam); - streamInfoResult.setRtc(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam, isPlay); - if (mediaInfo != null) { - streamInfoResult.setMediaInfo(mediaInfo); - streamInfoResult.setOriginType(mediaInfo.getOriginType()); + String flvFile = String.format("%s/%s.flv%s", app, stream, callIdParam); + if ((mediaServer.getFlvPort() & 1) == 1) { + // 奇数端口 默认ssl端口 + streamInfoResult.setFlv(addr, null, mediaServer.getFlvPort(), flvFile); + }else { + streamInfoResult.setFlv(addr, mediaServer.getFlvPort(),null, flvFile); + } + if ((mediaServer.getWsFlvPort() & 1) == 1) { + // 奇数端口 默认ssl端口 + streamInfoResult.setWsFlv(addr, null, mediaServer.getWsFlvPort(), flvFile); + }else { + streamInfoResult.setWsFlv(addr, mediaServer.getWsFlvPort(),null, flvFile); + } + + streamInfoResult.setWsFlv(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), flvFile); + + String mp4File = String.format("%s/%s.mp4%s", app, stream, callIdParam); + if ((mediaServer.getMp4Port() & 1) == 1) { + // 奇数端口 默认ssl端口 + streamInfoResult.setFmp4(addr, null, mediaServer.getMp4Port(), mp4File); + }else { + streamInfoResult.setFmp4(addr, mediaServer.getMp4Port(), null, mp4File); + } + + + streamInfoResult.setHls(addr, mediaServer.getHttpPort(), mediaServer.getHttpSSlPort(), app, stream, callIdParam); + streamInfoResult.setTs(addr, mediaServer.getHttpPort(), mediaServer.getHttpSSlPort(), app, stream, callIdParam); + streamInfoResult.setRtc(addr, mediaServer.getHttpPort(), mediaServer.getHttpSSlPort(), app, stream, callIdParam, isPlay); + + streamInfoResult.setMediaInfo(mediaInfo); + + if (!"broadcast".equalsIgnoreCase(app) && !ObjectUtils.isEmpty(mediaServer.getTranscodeSuffix()) && !"null".equalsIgnoreCase(mediaServer.getTranscodeSuffix())) { + String newStream = stream + "_" + mediaServer.getTranscodeSuffix(); + mediaServer.setTranscodeSuffix(null); + StreamInfo transcodeStreamInfo = getStreamInfoByAppAndStream(mediaServer, app, newStream, null, addr, callId, isPlay); + streamInfoResult.setTranscodeStream(transcodeStreamInfo); } return streamInfoResult; } @@ -420,48 +477,55 @@ public class ABLMediaNodeServerService implements IMediaNodeServerService { } String resultApp = ablResult.getApp(); String resultStream = ablResult.getStream(); - StreamInfo streamInfo = getStreamInfoByAppAndStream(mediaServer, resultApp, resultStream, null, null, true); + StreamInfo streamInfo = getStreamInfoByAppAndStream(mediaServer, resultApp, resultStream, null, null,null, true); + System.out.println(streamInfo.getRtsp()); + streamInfo.setKey(ablResult.getKey()); if (callback != null) { callback.run(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), streamInfo); } } @Override - public void seekRecordStamp(MediaServer mediaServer, String app, String stream, Double stamp, String schema) { - logger.warn("[abl-seekRecordStamp] 未实现"); + public void seekRecordStamp(MediaServer mediaServer, String app, String stream, String key, Double stamp, String schema) { + ABLResult ablResult = ablresTfulUtils.controlRecordPlay(mediaServer, key, "seek", ((int)(stamp/1000)) + ""); + if (ablResult.getCode() != 0) { + log.warn("[abl-seek] 失败:{}", ablResult.getMemo()); + } } @Override - public void setRecordSpeed(MediaServer mediaServer, String app, String stream, Integer speed, String schema) { - logger.warn("[abl-setRecordSpeed] 未实现"); + public void setRecordSpeed(MediaServer mediaServer, String app, String stream, String key, Integer speed, String schema) { + ABLResult ablResult = ablresTfulUtils.controlRecordPlay(mediaServer, key, "scale", speed + ""); + if (ablResult.getCode() != 0) { + log.warn("[abl-倍速] 失败:{}", ablResult.getMemo()); + } } @Override public DownloadFileInfo getDownloadFilePath(MediaServer mediaServer, RecordInfo recordInfo) { // 将filePath作为独立参数传入,避免%符号解析问题 - String pathTemplate = "%s://%s:%s/%s/%s__ReplayFMP4RecordFile__%s?download_speed=6"; + String pathTemplate = "%s://%s:%s/%s/%s__ReplayFMP4RecordFile__%s?download_speed=16"; DownloadFileInfo info = new DownloadFileInfo(); - - info.setHttpPath( - String.format( - pathTemplate, - "http", - mediaServer.getStreamIp(), - mediaServer.getHttpPort(), - recordInfo.getApp(), - recordInfo.getStream(), - recordInfo.getFileName() - ) - ); - - if (mediaServer.getHttpSSlPort() > 0) { + if ((mediaServer.getMp4Port() & 1) == 1) { info.setHttpsPath( String.format( pathTemplate, "https", mediaServer.getStreamIp(), - mediaServer.getHttpSSlPort(), + mediaServer.getMp4Port(), + recordInfo.getApp(), + recordInfo.getStream(), + recordInfo.getFileName() + ) + ); + }else { + info.setHttpPath( + String.format( + pathTemplate, + "http", + mediaServer.getStreamIp(), + mediaServer.getMp4Port(), recordInfo.getApp(), recordInfo.getStream(), recordInfo.getFileName() diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java index 377cdd346..f435fb825 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLMediaServerStatusManger.java @@ -174,74 +174,65 @@ public class ABLMediaServerStatusManger { } } - private void online(MediaServer mediaServerItem, AblServerConfig config) { - offlineABLPrimaryMap.remove(mediaServerItem.getId()); - offlineAblsecondaryMap.remove(mediaServerItem.getId()); - offlineAblTimeMap.remove(mediaServerItem.getId()); - if (!mediaServerItem.isStatus()) { - logger.info("[ABL-连接成功] ID:{}, 地址: {}:{}", mediaServerItem.getId(), mediaServerItem.getIp(), mediaServerItem.getHttpPort()); - mediaServerItem.setStatus(true); - mediaServerItem.setHookAliveInterval(10F); - mediaServerService.update(mediaServerItem); - if(mediaServerItem.isAutoConfig()) { + private void online(MediaServer mediaServer, AblServerConfig config) { + offlineABLPrimaryMap.remove(mediaServer.getId()); + offlineAblsecondaryMap.remove(mediaServer.getId()); + offlineAblTimeMap.remove(mediaServer.getId()); + if (!mediaServer.isStatus()) { + logger.info("[ABL-连接成功] ID:{}, 地址: {}:{}", mediaServer.getId(), mediaServer.getIp(), mediaServer.getHttpPort()); + mediaServer.setStatus(true); + mediaServer.setHookAliveInterval(10F); + mediaServerService.update(mediaServer); + if(mediaServer.isAutoConfig()) { if (config == null) { - ABLResult ablResult = ablResTfulUtils.getServerConfig(mediaServerItem); + ABLResult ablResult = ablResTfulUtils.getServerConfig(mediaServer); JSONArray data = ablResult.getParams(); if (data != null && !data.isEmpty()) { config = AblServerConfig.getInstance(data); } } if (config != null) { - initPort(mediaServerItem, config); - setAblConfig(mediaServerItem, false, config); + initPort(mediaServer, config); + setAblConfig(mediaServer, false, config); } } - mediaServerService.update(mediaServerItem); + mediaServerService.update(mediaServer); } // 设置两次心跳未收到则认为zlm离线 - String key = "ABL-keepalive-" + mediaServerItem.getId(); + String key = "ABL-keepalive-" + mediaServer.getId(); dynamicTask.startDelay(key, ()->{ - logger.warn("[ABL-心跳超时] ID:{}", mediaServerItem.getId()); - mediaServerItem.setStatus(false); - offlineABLPrimaryMap.put(mediaServerItem.getId(), mediaServerItem); - offlineAblTimeMap.put(mediaServerItem.getId(), System.currentTimeMillis()); + logger.warn("[ABL-心跳超时] ID:{}", mediaServer.getId()); + mediaServer.setStatus(false); + offlineABLPrimaryMap.put(mediaServer.getId(), mediaServer); + offlineAblTimeMap.put(mediaServer.getId(), System.currentTimeMillis()); // TODO 发送离线通知 - mediaServerService.update(mediaServerItem); - }, (int)(mediaServerItem.getHookAliveInterval() * 2 * 1000)); + mediaServerService.update(mediaServer); + }, (int)(mediaServer.getHookAliveInterval() * 2 * 1000)); } - private void initPort(MediaServer mediaServerItem, AblServerConfig ablServerConfig) { + private void initPort(MediaServer mediaServer, AblServerConfig ablServerConfig) { // 端口只会从配置中读取一次,一旦自己配置或者读取过了将不在配置 -// if (mediaServerItem.getHttpSSlPort() == 0) { -// mediaServerItem.setHttpSSlPort(ablServerConfig.getHttpSSLport()); -// } - if (mediaServerItem.getRtmpPort() != ablServerConfig.getRtmpPort()) { - mediaServerItem.setRtmpPort(ablServerConfig.getRtmpPort()); + if (ablServerConfig.getRtmpPort() != null && mediaServer.getRtmpPort() != ablServerConfig.getRtmpPort()) { + mediaServer.setRtmpPort(ablServerConfig.getRtmpPort()); } -// if (mediaServerItem.getRtmpSSlPort() == 0) { -// mediaServerItem.setRtmpSSlPort(ablServerConfig.getRtmpSslPort()); -// } - if (mediaServerItem.getRtspPort() != ablServerConfig.getRtspPort()) { - mediaServerItem.setRtspPort(ablServerConfig.getRtspPort()); + if (ablServerConfig.getRtspPort() != null && mediaServer.getRtspPort() != ablServerConfig.getRtspPort()) { + mediaServer.setRtspPort(ablServerConfig.getRtspPort()); } - if (mediaServerItem.getFlvPort() != ablServerConfig.getHttpFlvPort()) { - mediaServerItem.setFlvPort(ablServerConfig.getHttpFlvPort()); + if (ablServerConfig.getHttpFlvPort() != null && mediaServer.getFlvPort() != ablServerConfig.getHttpFlvPort()) { + mediaServer.setFlvPort(ablServerConfig.getHttpFlvPort()); } - if (mediaServerItem.getWsFlvPort() != ablServerConfig.getWsPort()) { - mediaServerItem.setWsFlvPort(ablServerConfig.getWsPort()); + if (ablServerConfig.getMp4Port() != null && mediaServer.getMp4Port() != ablServerConfig.getMp4Port()) { + mediaServer.setMp4Port(ablServerConfig.getMp4Port()); } - if (mediaServerItem.getRtpProxyPort() != ablServerConfig.getPsTsRecvPort()) { - mediaServerItem.setRtpProxyPort(ablServerConfig.getPsTsRecvPort()); + if (ablServerConfig.getWsPort() != null && mediaServer.getWsFlvPort() != ablServerConfig.getWsPort()) { + mediaServer.setWsFlvPort(ablServerConfig.getWsPort()); } - if (mediaServerItem.getRtpProxyPort() != ablServerConfig.getJtt1078RecvPort()) { - mediaServerItem.setJttProxyPort(ablServerConfig.getJtt1078RecvPort()); + if (ablServerConfig.getPsTsRecvPort() != null && mediaServer.getRtpProxyPort() != ablServerConfig.getPsTsRecvPort()) { + mediaServer.setRtpProxyPort(ablServerConfig.getPsTsRecvPort()); } -// if (mediaServerItem.getRtspSSLPort() == 0) { -// mediaServerItem.setRtspSSLPort(ablServerConfig.getRtspSSlport()); -// } -// if (mediaServerItem.getRtpProxyPort() == 0) { -// mediaServerItem.setRtpProxyPort(ablServerConfig.getRtpProxyPort()); -// } - mediaServerItem.setHookAliveInterval(10F); + if (ablServerConfig.getJtt1078RecvPort() != null && mediaServer.getRtpProxyPort() != ablServerConfig.getJtt1078RecvPort()) { + mediaServer.setJttProxyPort(ablServerConfig.getJtt1078RecvPort()); + } + mediaServer.setHookAliveInterval(10F); } public void setAblConfig(MediaServer mediaServerItem, boolean restart, AblServerConfig config) { diff --git a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLRESTfulUtils.java b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLRESTfulUtils.java index d3c85b8bd..5a95c9f84 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/abl/ABLRESTfulUtils.java +++ b/src/main/java/com/genersoft/iot/vmp/media/abl/ABLRESTfulUtils.java @@ -522,4 +522,18 @@ public class ABLRESTfulUtils { } } + public ABLResult controlRecordPlay(MediaServer mediaServer, String key, String command, String value) { + Map param = new HashMap<>(); + param.put("key", key); + param.put("command", command); + param.put("value", value); + String response = sendGet(mediaServer, "controlRecordPlay", param); + ABLResult ablResult = JSON.parseObject(response, ABLResult.class); + if (ablResult == null) { + return ABLResult.getFailForMediaServer(); + }else { + return ablResult; + } + } + } diff --git a/src/main/java/com/genersoft/iot/vmp/media/bean/MediaServer.java b/src/main/java/com/genersoft/iot/vmp/media/bean/MediaServer.java index 7a6f65fa7..63662db8c 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/bean/MediaServer.java +++ b/src/main/java/com/genersoft/iot/vmp/media/bean/MediaServer.java @@ -44,9 +44,6 @@ public class MediaServer { @Schema(description = "mp4端口") private int mp4Port; - @Schema(description = "https-mp4端口") - private int mp4SSLPort; - @Schema(description = "ws-flv端口") private int wsFlvPort; @@ -128,11 +125,7 @@ public class MediaServer { sdpIp = ObjectUtils.isEmpty(zlmServerConfig.getSdpIp())? zlmServerConfig.getIp(): zlmServerConfig.getSdpIp(); streamIp = ObjectUtils.isEmpty(zlmServerConfig.getStreamIp())? zlmServerConfig.getIp(): zlmServerConfig.getStreamIp(); httpPort = zlmServerConfig.getHttpPort(); - flvPort = zlmServerConfig.getHttpPort(); - wsFlvPort = zlmServerConfig.getHttpPort(); httpSSlPort = zlmServerConfig.getHttpSSLport(); - flvSSLPort = zlmServerConfig.getHttpSSLport(); - wsFlvSSLPort = zlmServerConfig.getHttpSSLport(); rtmpPort = zlmServerConfig.getRtmpPort(); rtmpSSlPort = zlmServerConfig.getRtmpSslPort(); rtpProxyPort = zlmServerConfig.getRtpProxyPort(); @@ -156,20 +149,14 @@ public class MediaServer { streamIp = config.getServerIp(); httpPort = config.getHttpServerPort(); flvPort = config.getHttpFlvPort(); + mp4Port = config.getMp4Port(); wsFlvPort = config.getWsPort(); -// httpSSlPort = config.getHttpSSLport(); -// flvSSLPort = config.getHttpSSLport(); -// wsFlvSSLPort = config.getHttpSSLport(); rtmpPort = config.getRtmpPort(); -// rtmpSSlPort = config.getRtmpSslPort(); rtpProxyPort = config.getJtt1078RecvPort(); rtspPort = config.getRtspPort(); -// rtspSSLPort = config.getRtspSSlport(); autoConfig = true; // 默认值true; secret = config.getSecret(); -// hookAliveInterval = config.getHookAliveInterval(); rtpEnable = false; // 默认使用单端口;直到用户自己设置开启多端口 -// rtpPortRange = config.getPortRange().replace("_",","); // 默认使用30000,30500作为级联时发送流的端口号 rtpPortRange = "30000,30500"; // 默认使用30000,30500作为级联时发送流的端口号 recordAssistPort = 0; // 默认关闭 } diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java index ca10adae3..f1e38a29c 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaNodeServerService.java @@ -79,9 +79,11 @@ public interface IMediaNodeServerService { void loadMP4File(MediaServer mediaServer, String app, String stream, String datePath, String dateDir, ErrorCallback callback); - void seekRecordStamp(MediaServer mediaServer, String app, String stream, Double stamp, String schema); + void seekRecordStamp(MediaServer mediaServer, String app, String stream, String key, Double stamp, String schema); - void setRecordSpeed(MediaServer mediaServer, String app, String stream, Integer speed, String schema); + void setRecordSpeed(MediaServer mediaServer, String app, String stream, String key, Integer speed, String schema); DownloadFileInfo getDownloadFilePath(MediaServer mediaServer, RecordInfo recordInfo); + + StreamInfo getStreamInfoByAppAndStream(MediaServer mediaServer, String app, String stream, MediaInfo mediaInfo, String addr, String callId, boolean isPlay); } diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java index f5ff1a8bd..1f2e1b204 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/IMediaServerService.java @@ -166,9 +166,9 @@ public interface IMediaServerService { void loadMP4File(MediaServer mediaServer, String app, String stream, String datePath, String dateDir, ErrorCallback callback); - void seekRecordStamp(MediaServer mediaServer, String app, String stream, Double stamp, String schema); + void seekRecordStamp(MediaServer mediaServer, String app, String stream, String key, Double stamp, String schema); - void setRecordSpeed(MediaServer mediaServer, String app, String stream, Integer speed, String schema); + void setRecordSpeed(MediaServer mediaServer, String app, String stream, String key, Integer speed, String schema); DownloadFileInfo getDownloadFilePath(MediaServer mediaServer, RecordInfo recordInfo); } diff --git a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java index bcc206d12..c60b3ce1c 100755 --- a/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/media/service/impl/MediaServerServiceImpl.java @@ -841,68 +841,12 @@ public class MediaServerServiceImpl implements IMediaServerService { @Override public StreamInfo getStreamInfoByAppAndStream(MediaServer mediaServer, String app, String stream, MediaInfo mediaInfo, String addr, String callId, boolean isPlay) { - StreamInfo streamInfoResult = new StreamInfo(); - streamInfoResult.setStream(stream); - streamInfoResult.setApp(app); - if (addr == null) { - addr = mediaServer.getStreamIp(); + IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType()); + if (mediaNodeServerService == null) { + log.info("[getStreamInfoByAppAndStream] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType()); + return null; } - - streamInfoResult.setIp(addr); - if (mediaInfo != null) { - streamInfoResult.setServerId(mediaInfo.getServerId()); - }else { - streamInfoResult.setServerId(userSetting.getServerId()); - } - - streamInfoResult.setMediaServer(mediaServer); - Map param = new HashMap<>(); - if (!ObjectUtils.isEmpty(callId)) { - param.put("callId", callId); - } - if (mediaInfo != null && !ObjectUtils.isEmpty(mediaInfo.getOriginTypeStr())) { - param.put("originTypeStr", mediaInfo.getOriginTypeStr()); - } - StringBuilder callIdParamBuilder = new StringBuilder(); - if (!param.isEmpty()) { - callIdParamBuilder.append("?"); - for (Map.Entry entry : param.entrySet()) { - callIdParamBuilder.append(entry.getKey()).append("=").append(entry.getValue()); - callIdParamBuilder.append("&"); - } - callIdParamBuilder.deleteCharAt(callIdParamBuilder.length() - 1); - } - - String callIdParam = callIdParamBuilder.toString(); - - streamInfoResult.setRtmp(addr, mediaServer.getRtmpPort(),mediaServer.getRtmpSSlPort(), app, stream, callIdParam); - streamInfoResult.setRtsp(addr, mediaServer.getRtspPort(),mediaServer.getRtspSSLPort(), app, stream, callIdParam); - - - if ("abl".equals(mediaServer.getType())) { - String flvFile = String.format("%s/%s.flv%s", app, stream, callIdParam); - streamInfoResult.setFlv(addr, mediaServer.getFlvPort(),mediaServer.getFlvSSLPort(), flvFile); - streamInfoResult.setWsFlv(addr, mediaServer.getWsFlvPort(),mediaServer.getWsFlvSSLPort(), flvFile); - }else { - String flvFile = String.format("%s/%s.live.flv%s", app, stream, callIdParam); - streamInfoResult.setFlv(addr, mediaServer.getFlvPort(),mediaServer.getFlvSSLPort(), flvFile); - streamInfoResult.setWsFlv(addr, mediaServer.getWsFlvPort(),mediaServer.getWsFlvSSLPort(), flvFile); - } - - streamInfoResult.setFmp4(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam); - streamInfoResult.setHls(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam); - streamInfoResult.setTs(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam); - streamInfoResult.setRtc(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam, isPlay); - - streamInfoResult.setMediaInfo(mediaInfo); - - if (!"broadcast".equalsIgnoreCase(app) && !ObjectUtils.isEmpty(mediaServer.getTranscodeSuffix()) && !"null".equalsIgnoreCase(mediaServer.getTranscodeSuffix())) { - String newStream = stream + "_" + mediaServer.getTranscodeSuffix(); - mediaServer.setTranscodeSuffix(null); - StreamInfo transcodeStreamInfo = getStreamInfoByAppAndStream(mediaServer, app, newStream, null, addr, callId, isPlay); - streamInfoResult.setTranscodeStream(transcodeStreamInfo); - } - return streamInfoResult; + return mediaNodeServerService.getStreamInfoByAppAndStream(mediaServer, app, stream, mediaInfo, addr, callId, isPlay); } @Override @@ -1019,23 +963,23 @@ public class MediaServerServiceImpl implements IMediaServerService { } @Override - public void seekRecordStamp(MediaServer mediaServer, String app, String stream, Double stamp, String schema) { + public void seekRecordStamp(MediaServer mediaServer, String app, String stream, String key, Double stamp, String schema) { IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType()); if (mediaNodeServerService == null) { log.info("[seekRecordStamp] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType()); throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到mediaServer对应的实现类"); } - mediaNodeServerService.seekRecordStamp(mediaServer, app, stream, stamp, schema); + mediaNodeServerService.seekRecordStamp(mediaServer, app, stream, key, stamp, schema); } @Override - public void setRecordSpeed(MediaServer mediaServer, String app, String stream, Integer speed, String schema) { + public void setRecordSpeed(MediaServer mediaServer, String app, String stream, String key, Integer speed, String schema) { IMediaNodeServerService mediaNodeServerService = nodeServerServiceMap.get(mediaServer.getType()); if (mediaNodeServerService == null) { log.info("[setRecordSpeed] 失败, mediaServer的类型: {},未找到对应的实现类", mediaServer.getType()); throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到mediaServer对应的实现类"); } - mediaNodeServerService.setRecordSpeed(mediaServer, app, stream, speed, schema); + mediaNodeServerService.setRecordSpeed(mediaServer, app, stream, key, speed, schema); } @Override diff --git a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java index cc0dc4ebb..572258655 100644 --- a/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java +++ b/src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMMediaNodeServerService.java @@ -109,8 +109,6 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { mediaServer.setServerId(userSetting.getServerId()); mediaServer.setIp(ip); mediaServer.setHttpPort(port); - mediaServer.setFlvPort(port); - mediaServer.setWsFlvPort(port); mediaServer.setSecret(secret); ZLMResult> mediaServerConfigResult = zlmresTfulUtils.getMediaServerConfig(mediaServer); if (mediaServerConfigResult == null) { @@ -126,8 +124,6 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { } mediaServer.setId(zlmServerConfig.getGeneralMediaServerId()); mediaServer.setHttpSSlPort(zlmServerConfig.getHttpSSLport()); - mediaServer.setFlvSSLPort(zlmServerConfig.getHttpSSLport()); - mediaServer.setWsFlvSSLPort(zlmServerConfig.getHttpSSLport()); mediaServer.setRtmpPort(zlmServerConfig.getRtmpPort()); mediaServer.setRtmpSSlPort(zlmServerConfig.getRtmpSslPort()); mediaServer.setRtspPort(zlmServerConfig.getRtspPort()); @@ -202,7 +198,8 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { for (int i = 0; i < zlmResult.getData().size(); i++) { JSONObject mediaJSON = zlmResult.getData().getJSONObject(0); MediaInfo mediaInfo = MediaInfo.getInstance(mediaJSON, mediaServer, userSetting.getServerId()); - StreamInfo streamInfo = getStreamInfoByAppAndStream(mediaServer, mediaInfo.getApp(), mediaInfo.getStream(), mediaInfo, callId, true); + StreamInfo streamInfo = getStreamInfoByAppAndStream(mediaServer, mediaInfo.getApp(), + mediaInfo.getStream(), mediaInfo, null, callId, true); if (streamInfo != null) { streamInfoList.add(streamInfo); } @@ -212,52 +209,6 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { return streamInfoList; } - public StreamInfo getStreamInfoByAppAndStream(MediaServer mediaServer, String app, String stream, MediaInfo mediaInfo, String callId, boolean isPlay) { - StreamInfo streamInfoResult = new StreamInfo(); - streamInfoResult.setServerId(userSetting.getServerId()); - streamInfoResult.setStream(stream); - streamInfoResult.setApp(app); - String addr = mediaServer.getStreamIp(); - streamInfoResult.setIp(addr); - streamInfoResult.setMediaServer(mediaServer); - - Map param = new HashMap<>(); - if (!ObjectUtils.isEmpty(callId)) { - param.put("callId", callId); - } - if (mediaInfo != null && !ObjectUtils.isEmpty(mediaInfo.getOriginTypeStr())) { - param.put("originTypeStr", mediaInfo.getOriginTypeStr()); - } - StringBuilder callIdParamBuilder = new StringBuilder(); - if (!param.isEmpty()) { - callIdParamBuilder.append("?"); - for (Map.Entry entry : param.entrySet()) { - callIdParamBuilder.append(entry.getKey()).append("=").append(entry.getValue()); - callIdParamBuilder.append("&"); - } - callIdParamBuilder.deleteCharAt(callIdParamBuilder.length() - 1); - } - - String callIdParam = callIdParamBuilder.toString(); - - streamInfoResult.setRtmp(addr, mediaServer.getRtmpPort(),mediaServer.getRtmpSSlPort(), app, stream, callIdParam); - streamInfoResult.setRtsp(addr, mediaServer.getRtspPort(),mediaServer.getRtspSSLPort(), app, stream, callIdParam); - String flvFile = String.format("%s/%s.live.flv%s", app, stream, callIdParam); - streamInfoResult.setFlv(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), flvFile); - streamInfoResult.setWsFlv(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), flvFile); - streamInfoResult.setFmp4(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam); - streamInfoResult.setHls(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam); - streamInfoResult.setTs(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam); - streamInfoResult.setRtc(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), app, stream, callIdParam, isPlay); - - streamInfoResult.setMediaInfo(mediaInfo); - if (mediaInfo != null) { - streamInfoResult.setOriginType(mediaInfo.getOriginType()); - streamInfoResult.setOriginTypeStr(mediaInfo.getOriginTypeStr()); - } - return streamInfoResult; - } - @Override public Boolean connectRtpServer(MediaServer mediaServer, String address, int port, String stream) { ZLMResult zlmResult = zlmresTfulUtils.connectRtpServer(mediaServer, address, port, stream); @@ -570,7 +521,7 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { MediaInfo mediaInfo = getMediaInfo(mediaServer, buildApp, buildStream); if (mediaInfo != null) { if (callback != null) { - StreamInfo streamInfo = getStreamInfoByAppAndStream(mediaServer, buildApp, buildStream, mediaInfo, null, true); + StreamInfo streamInfo = getStreamInfoByAppAndStream(mediaServer, buildApp, buildStream, mediaInfo, null, null, true); callback.run(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), streamInfo); } return; @@ -578,7 +529,7 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { Hook hook = Hook.getInstance(HookType.on_media_arrival, buildApp, buildStream, mediaServer.getServerId()); subscribe.addSubscribe(hook, (hookData) -> { - StreamInfo streamInfo = getStreamInfoByAppAndStream(mediaServer, buildApp, buildStream, hookData.getMediaInfo(), null, true); + StreamInfo streamInfo = getStreamInfoByAppAndStream(mediaServer, buildApp, buildStream, hookData.getMediaInfo(), null, null, true); if (callback != null) { callback.run(ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg(), streamInfo); } @@ -595,7 +546,7 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { } @Override - public void seekRecordStamp(MediaServer mediaServer, String app, String stream, Double stamp, String schema) { + public void seekRecordStamp(MediaServer mediaServer, String app, String stream, String key, Double stamp, String schema) { ZLMResult zlmResult = zlmresTfulUtils.seekRecordStamp(mediaServer, app, stream, stamp, schema); if (zlmResult == null) { throw new ControllerException(ErrorCode.ERROR100.getCode(), "请求失败"); @@ -606,7 +557,7 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { } @Override - public void setRecordSpeed(MediaServer mediaServer, String app, String stream, Integer speed, String schema) { + public void setRecordSpeed(MediaServer mediaServer, String app, String stream, String key, Integer speed, String schema) { ZLMResult zlmResult = zlmresTfulUtils.setRecordSpeed(mediaServer, app, stream, speed, schema); if (zlmResult == null) { throw new ControllerException(ErrorCode.ERROR100.getCode(), "请求失败"); @@ -641,4 +592,70 @@ public class ZLMMediaNodeServerService implements IMediaNodeServerService { } return info; } + + @Override + public StreamInfo getStreamInfoByAppAndStream(MediaServer mediaServer, String app, String stream, MediaInfo mediaInfo, String addr, String callId, boolean isPlay) { + StreamInfo streamInfoResult = new StreamInfo(); + streamInfoResult.setStream(stream); + streamInfoResult.setApp(app); + if (addr == null) { + addr = mediaServer.getStreamIp(); + } + + streamInfoResult.setIp(addr); + if (mediaInfo != null) { + streamInfoResult.setServerId(mediaInfo.getServerId()); + }else { + streamInfoResult.setServerId(userSetting.getServerId()); + } + + streamInfoResult.setMediaServer(mediaServer); + Map param = new HashMap<>(); + if (!ObjectUtils.isEmpty(callId)) { + param.put("callId", callId); + } + if (mediaInfo != null && !ObjectUtils.isEmpty(mediaInfo.getOriginTypeStr())) { + param.put("originTypeStr", mediaInfo.getOriginTypeStr()); + } + StringBuilder callIdParamBuilder = new StringBuilder(); + if (!param.isEmpty()) { + callIdParamBuilder.append("?"); + for (Map.Entry entry : param.entrySet()) { + callIdParamBuilder.append(entry.getKey()).append("=").append(entry.getValue()); + callIdParamBuilder.append("&"); + } + callIdParamBuilder.deleteCharAt(callIdParamBuilder.length() - 1); + } + + String callIdParam = callIdParamBuilder.toString(); + + streamInfoResult.setRtmp(addr, mediaServer.getRtmpPort(),mediaServer.getRtmpSSlPort(), app, stream, callIdParam); + streamInfoResult.setRtsp(addr, mediaServer.getRtspPort(),mediaServer.getRtspSSLPort(), app, stream, callIdParam); + + String flvFile = String.format("%s/%s.live.flv%s", app, stream, callIdParam); + streamInfoResult.setFlv(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), flvFile); + streamInfoResult.setWsFlv(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), flvFile); + + String mp4File = String.format("%s/%s.live.mp4%s", app, stream, callIdParam); + streamInfoResult.setFmp4(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), mp4File); + streamInfoResult.setWsMp4(addr, mediaServer.getHttpPort(),mediaServer.getHttpSSlPort(), mp4File); + + streamInfoResult.setHls(addr, mediaServer.getHttpPort(), mediaServer.getHttpSSlPort(), app, stream, callIdParam); + streamInfoResult.setWsHls(addr, mediaServer.getHttpPort(), mediaServer.getHttpSSlPort(), app, stream, callIdParam); + + streamInfoResult.setTs(addr, mediaServer.getHttpPort(), mediaServer.getHttpSSlPort(), app, stream, callIdParam); + streamInfoResult.setWsTs(addr, mediaServer.getHttpPort(), mediaServer.getHttpSSlPort(), app, stream, callIdParam); + + streamInfoResult.setRtc(addr, mediaServer.getHttpPort(), mediaServer.getHttpSSlPort(), app, stream, callIdParam, isPlay); + + streamInfoResult.setMediaInfo(mediaInfo); + + if (!"broadcast".equalsIgnoreCase(app) && !ObjectUtils.isEmpty(mediaServer.getTranscodeSuffix()) && !"null".equalsIgnoreCase(mediaServer.getTranscodeSuffix())) { + String newStream = stream + "_" + mediaServer.getTranscodeSuffix(); + mediaServer.setTranscodeSuffix(null); + StreamInfo transcodeStreamInfo = getStreamInfoByAppAndStream(mediaServer, app, newStream, null, addr, callId, isPlay); + streamInfoResult.setTranscodeStream(transcodeStreamInfo); + } + return streamInfoResult; + } } diff --git a/src/main/java/com/genersoft/iot/vmp/service/ICloudRecordService.java b/src/main/java/com/genersoft/iot/vmp/service/ICloudRecordService.java index 6fdda6df6..5b9031e66 100755 --- a/src/main/java/com/genersoft/iot/vmp/service/ICloudRecordService.java +++ b/src/main/java/com/genersoft/iot/vmp/service/ICloudRecordService.java @@ -61,9 +61,9 @@ public interface ICloudRecordService { */ void loadRecord(String app, String stream, String date, ErrorCallback callback); - void seekRecord(String mediaServerId,String app, String stream, Double seek, String schema); + void seekRecord(String mediaServerId,String app, String stream, String key, Double seek, String schema); - void setRecordSpeed(String mediaServerId, String app, String stream, Integer speed, String schema); + void setRecordSpeed(String mediaServerId, String app, String stream, String key, Integer speed, String schema); void deleteFileByIds(Set ids); } diff --git a/src/main/java/com/genersoft/iot/vmp/service/impl/CloudRecordServiceImpl.java b/src/main/java/com/genersoft/iot/vmp/service/impl/CloudRecordServiceImpl.java index 6a8588027..50c30e1f7 100644 --- a/src/main/java/com/genersoft/iot/vmp/service/impl/CloudRecordServiceImpl.java +++ b/src/main/java/com/genersoft/iot/vmp/service/impl/CloudRecordServiceImpl.java @@ -304,21 +304,21 @@ public class CloudRecordServiceImpl implements ICloudRecordService { } @Override - public void seekRecord(String mediaServerId,String app, String stream, Double seek, String schema) { + public void seekRecord(String mediaServerId,String app, String stream, String key, Double seek, String schema) { MediaServer mediaServer = mediaServerService.getOne(mediaServerId); if (mediaServer == null) { throw new ControllerException(ErrorCode.ERROR100.getCode(), "媒体节点不存在: " + mediaServerId); } - mediaServerService.seekRecordStamp(mediaServer, app, stream, seek, schema); + mediaServerService.seekRecordStamp(mediaServer, app, stream, key, seek, schema); } @Override - public void setRecordSpeed(String mediaServerId, String app, String stream, Integer speed, String schema) { + public void setRecordSpeed(String mediaServerId, String app, String stream, String key, Integer speed, String schema) { MediaServer mediaServer = mediaServerService.getOne(mediaServerId); if (mediaServer == null) { throw new ControllerException(ErrorCode.ERROR100.getCode(), "媒体节点不存在: " + mediaServerId); } - mediaServerService.setRecordSpeed(mediaServer, app, stream, speed, schema); + mediaServerService.setRecordSpeed(mediaServer, app, stream, key, speed, schema); } @Override diff --git a/src/main/java/com/genersoft/iot/vmp/storager/dao/MediaServerMapper.java b/src/main/java/com/genersoft/iot/vmp/storager/dao/MediaServerMapper.java index 5ac5c8a93..f892be273 100755 --- a/src/main/java/com/genersoft/iot/vmp/storager/dao/MediaServerMapper.java +++ b/src/main/java/com/genersoft/iot/vmp/storager/dao/MediaServerMapper.java @@ -26,6 +26,7 @@ public interface MediaServerMapper { "jtt_proxy_port,"+ "rtsp_port,"+ "flv_port," + + "mp4_port," + "flv_ssl_port," + "ws_flv_port," + "ws_flv_ssl_port," + @@ -60,6 +61,7 @@ public interface MediaServerMapper { "#{jttProxyPort}, " + "#{rtspPort}, " + "#{flvPort}, " + + "#{mp4Port}, " + "#{flvSSLPort}, " + "#{wsFlvPort}, " + "#{wsFlvSSLPort}, " + @@ -97,6 +99,7 @@ public interface MediaServerMapper { ", rtsp_port=#{rtspPort}" + ", rtsp_ssl_port=#{rtspSSLPort}" + ", flv_port=#{flvPort}" + + ", mp4_port=#{mp4Port}" + ", flv_ssl_port=#{flvSSLPort}" + ", ws_flv_port=#{wsFlvPort}" + ", ws_flv_ssl_port=#{wsFlvSSLPort}" + @@ -130,6 +133,7 @@ public interface MediaServerMapper { ", rtsp_port=#{rtspPort}" + ", rtsp_ssl_port=#{rtspSSLPort}" + ", flv_port=#{flvPort}" + + ", mp4_port=#{mp4Port}" + ", flv_ssl_port=#{flvSSLPort}" + ", ws_flv_port=#{wsFlvPort}" + ", ws_flv_ssl_port=#{wsFlvSSLPort}" + diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/bean/StreamContent.java b/src/main/java/com/genersoft/iot/vmp/vmanager/bean/StreamContent.java index e484dafa6..36a8837ed 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/bean/StreamContent.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/bean/StreamContent.java @@ -4,7 +4,9 @@ import com.genersoft.iot.vmp.common.StreamInfo; import com.genersoft.iot.vmp.media.bean.MediaInfo; import com.genersoft.iot.vmp.service.bean.DownloadFileInfo; import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +@Data @Schema(description = "流信息") public class StreamContent { @@ -103,6 +105,9 @@ public class StreamContent { private double progress; + @Schema(description = "拉流代理返回的KEY") + private String key; + public StreamContent(StreamInfo streamInfo) { if (streamInfo == null) { return; @@ -180,6 +185,7 @@ public class StreamContent { this.startTime = streamInfo.getStartTime(); this.endTime = streamInfo.getEndTime(); this.progress = streamInfo.getProgress(); + this.key = streamInfo.getKey(); if (streamInfo.getDownLoadFilePath() != null) { this.downLoadFilePath = streamInfo.getDownLoadFilePath(); @@ -189,259 +195,4 @@ public class StreamContent { } } - public StreamContent getTranscodeStream() { - return transcodeStream; - } - - public void setTranscodeStream(StreamContent transcodeStream) { - this.transcodeStream = transcodeStream; - } - - public String getApp() { - return app; - } - - public void setApp(String app) { - this.app = app; - } - - public String getStream() { - return stream; - } - - public void setStream(String stream) { - this.stream = stream; - } - - public String getIp() { - return ip; - } - - public void setIp(String ip) { - this.ip = ip; - } - - public String getFlv() { - return flv; - } - - public void setFlv(String flv) { - this.flv = flv; - } - - public String getHttps_flv() { - return https_flv; - } - - public void setHttps_flv(String https_flv) { - this.https_flv = https_flv; - } - - public String getWs_flv() { - return ws_flv; - } - - public void setWs_flv(String ws_flv) { - this.ws_flv = ws_flv; - } - - public String getWss_flv() { - return wss_flv; - } - - public void setWss_flv(String wss_flv) { - this.wss_flv = wss_flv; - } - - public String getFmp4() { - return fmp4; - } - - public void setFmp4(String fmp4) { - this.fmp4 = fmp4; - } - - public String getHttps_fmp4() { - return https_fmp4; - } - - public void setHttps_fmp4(String https_fmp4) { - this.https_fmp4 = https_fmp4; - } - - public String getWs_fmp4() { - return ws_fmp4; - } - - public void setWs_fmp4(String ws_fmp4) { - this.ws_fmp4 = ws_fmp4; - } - - public String getWss_fmp4() { - return wss_fmp4; - } - - public void setWss_fmp4(String wss_fmp4) { - this.wss_fmp4 = wss_fmp4; - } - - public String getHls() { - return hls; - } - - public void setHls(String hls) { - this.hls = hls; - } - - public String getHttps_hls() { - return https_hls; - } - - public void setHttps_hls(String https_hls) { - this.https_hls = https_hls; - } - - public String getWs_hls() { - return ws_hls; - } - - public void setWs_hls(String ws_hls) { - this.ws_hls = ws_hls; - } - - public String getWss_hls() { - return wss_hls; - } - - public void setWss_hls(String wss_hls) { - this.wss_hls = wss_hls; - } - - public String getTs() { - return ts; - } - - public void setTs(String ts) { - this.ts = ts; - } - - public String getHttps_ts() { - return https_ts; - } - - public void setHttps_ts(String https_ts) { - this.https_ts = https_ts; - } - - public String getWs_ts() { - return ws_ts; - } - - public void setWs_ts(String ws_ts) { - this.ws_ts = ws_ts; - } - - public String getWss_ts() { - return wss_ts; - } - - public void setWss_ts(String wss_ts) { - this.wss_ts = wss_ts; - } - - public String getRtmp() { - return rtmp; - } - - public void setRtmp(String rtmp) { - this.rtmp = rtmp; - } - - public String getRtmps() { - return rtmps; - } - - public void setRtmps(String rtmps) { - this.rtmps = rtmps; - } - - public String getRtsp() { - return rtsp; - } - - public void setRtsp(String rtsp) { - this.rtsp = rtsp; - } - - public String getRtsps() { - return rtsps; - } - - public void setRtsps(String rtsps) { - this.rtsps = rtsps; - } - - public String getRtc() { - return rtc; - } - - public void setRtc(String rtc) { - this.rtc = rtc; - } - - public String getRtcs() { - return rtcs; - } - - public void setRtcs(String rtcs) { - this.rtcs = rtcs; - } - - public String getMediaServerId() { - return mediaServerId; - } - - public void setMediaServerId(String mediaServerId) { - this.mediaServerId = mediaServerId; - } - - public MediaInfo getMediaInfo() { - return mediaInfo; - } - - public void setMediaInfo(MediaInfo mediaInfo) { - this.mediaInfo = mediaInfo; - } - - public String getStartTime() { - return startTime; - } - - public void setStartTime(String startTime) { - this.startTime = startTime; - } - - public String getEndTime() { - return endTime; - } - - public void setEndTime(String endTime) { - this.endTime = endTime; - } - - public double getProgress() { - return progress; - } - - public void setProgress(double progress) { - this.progress = progress; - } - - public DownloadFileInfo getDownLoadFilePath() { - return downLoadFilePath; - } - - public void setDownLoadFilePath(DownloadFileInfo downLoadFilePath) { - this.downLoadFilePath = downLoadFilePath; - } } diff --git a/src/main/java/com/genersoft/iot/vmp/vmanager/cloudRecord/CloudRecordController.java b/src/main/java/com/genersoft/iot/vmp/vmanager/cloudRecord/CloudRecordController.java index 291f7f9bd..0e4ebdd58 100755 --- a/src/main/java/com/genersoft/iot/vmp/vmanager/cloudRecord/CloudRecordController.java +++ b/src/main/java/com/genersoft/iot/vmp/vmanager/cloudRecord/CloudRecordController.java @@ -312,31 +312,37 @@ public class CloudRecordController { @GetMapping("/seek") @Operation(summary = "定位录像播放到制定位置") @Parameter(name = "mediaServerId", description = "使用的节点Id", required = true) + @Parameter(name = "app", description = "应用名", required = true) @Parameter(name = "stream", description = "流ID", required = true) + @Parameter(name = "key", description = "流绑定的key", required = true) @Parameter(name = "seek", description = "要定位的时间位置,从录像开始的时间算起", required = true) public void seekRecord( @RequestParam(required = true) String mediaServerId, @RequestParam(required = true) String app, @RequestParam(required = true) String stream, + @RequestParam(required = true) String key, @RequestParam(required = true) Double seek, @RequestParam(required = false) String schema ) { if (schema == null) { schema = "ts"; } - cloudRecordService.seekRecord(mediaServerId, app, stream, seek, schema); + cloudRecordService.seekRecord(mediaServerId, app, stream, key, seek, schema); } @ResponseBody @GetMapping("/speed") @Operation(summary = "设置录像播放速度") @Parameter(name = "mediaServerId", description = "使用的节点Id", required = true) + @Parameter(name = "app", description = "应用名", required = true) @Parameter(name = "stream", description = "流ID", required = true) + @Parameter(name = "key", description = "流绑定的key", required = true) @Parameter(name = "speed", description = "要设置的录像倍速", required = true) public void setRecordSpeed( @RequestParam(required = true) String mediaServerId, @RequestParam(required = true) String app, @RequestParam(required = true) String stream, + @RequestParam(required = true) String key, @RequestParam(required = true) Integer speed, @RequestParam(required = false) String schema ) { @@ -344,7 +350,7 @@ public class CloudRecordController { schema = "ts"; } - cloudRecordService.setRecordSpeed(mediaServerId, app, stream, speed, schema); + cloudRecordService.setRecordSpeed(mediaServerId, app, stream, key, speed, schema); } @ResponseBody diff --git a/web/src/api/cloudRecord.js b/web/src/api/cloudRecord.js index dabf7deda..2a52b8f20 100644 --- a/web/src/api/cloudRecord.js +++ b/web/src/api/cloudRecord.js @@ -41,7 +41,7 @@ export function loadRecord(params) { } export function seek(params) { - const { mediaServerId, app, stream, seek, schema } = params + const { mediaServerId, app, stream, key, seek, schema } = params return request({ method: 'get', url: `/api/cloud/record/seek`, @@ -49,6 +49,7 @@ export function seek(params) { mediaServerId: mediaServerId, app: app, stream: stream, + key: key, seek: seek, schema: schema } @@ -56,7 +57,7 @@ export function seek(params) { } export function speed(params) { - const { mediaServerId, app, stream, speed, schema } = params + const { mediaServerId, app, stream, key, speed, schema } = params return request({ method: 'get', url: `/api/cloud/record/speed`, @@ -64,6 +65,7 @@ export function speed(params) { mediaServerId: mediaServerId, app: app, stream: stream, + key: key, speed: speed, schema: schema } diff --git a/web/src/views/cloudRecord/detail.vue b/web/src/views/cloudRecord/detail.vue index 897ed1502..36adfa70c 100755 --- a/web/src/views/cloudRecord/detail.vue +++ b/web/src/views/cloudRecord/detail.vue @@ -225,6 +225,7 @@ export default { app: this.streamInfo.app, stream: this.streamInfo.stream, speed: this.playSpeed, + seek: this.playSeekValue, schema: 'ts' }) this.$refs.recordVideoPlayer.setPlaybackRate(this.playSpeed) @@ -369,6 +370,7 @@ export default { mediaServerId: this.streamInfo.mediaServerId, app: this.streamInfo.app, stream: this.streamInfo.stream, + key: this.streamInfo.key, seek: this.playSeekValue, schema: 'fmp4' }) diff --git a/web/src/views/cloudRecord/index.vue b/web/src/views/cloudRecord/index.vue index 82579ce25..b79e6fc17 100755 --- a/web/src/views/cloudRecord/index.vue +++ b/web/src/views/cloudRecord/index.vue @@ -237,9 +237,27 @@ export default { const link = document.createElement('a') link.target = '_blank' if (location.protocol === 'https:') { - link.href = data.httpsPath + '&save_name=' + row.fileName + if (data.httpsPath) { + link.href = data.httpsPath + '&save_name=' + row.fileName + }else if (data.httpPath){ + link.href = data.httpPath + '&save_name=' + row.fileName + }else { + this.$message.error({ + showClose: true, + message: '获取下载地址失败' + }) + } } else { - link.href = data.httpPath + '&save_name=' + row.fileName + if (data.httpPath) { + link.href = data.httpPath + '&save_name=' + row.fileName + }else if (data.httpsPath){ + link.href = data.httpsPath + '&save_name=' + row.fileName + }else { + this.$message.error({ + showClose: true, + message: '获取下载地址失败' + }) + } } link.click() })