|  |  |  | 
|---|
|  |  |  | package com.ruoyi.media.service.impl; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import com.alibaba.fastjson2.JSONObject; | 
|---|
|  |  |  | import com.dtflys.forest.Forest; | 
|---|
|  |  |  | import com.dtflys.forest.exceptions.ForestNetworkException; | 
|---|
|  |  |  | import com.dtflys.forest.exceptions.ForestRuntimeException; | 
|---|
|  |  |  | import com.ruoyi.common.utils.DateUtils; | 
|---|
|  |  |  | import com.ruoyi.common.utils.SecurityUtils; | 
|---|
|  |  |  | import com.ruoyi.common.constant.HttpStatus; | 
|---|
|  |  |  | import com.ruoyi.common.core.page.TableDataInfo; | 
|---|
|  |  |  | import com.ruoyi.common.utils.StringUtils; | 
|---|
|  |  |  | import com.ruoyi.media.domain.*; | 
|---|
|  |  |  | import com.ruoyi.media.mapper.VtduMapper; | 
|---|
|  |  |  | import com.ruoyi.media.service.IMediaService; | 
|---|
|  |  |  | import com.ruoyi.utils.forest.MediaClient; | 
|---|
|  |  |  | import com.ruoyi.utils.tools.ArdTool; | 
|---|
|  |  |  | import com.ruoyi.utils.process.CmdUtils; | 
|---|
|  |  |  | import com.sun.jna.Platform; | 
|---|
|  |  |  | import io.swagger.models.auth.In; | 
|---|
|  |  |  | import lombok.extern.slf4j.Slf4j; | 
|---|
|  |  |  | import org.apache.poi.ss.formula.functions.T; | 
|---|
|  |  |  | import org.springframework.beans.factory.annotation.Value; | 
|---|
|  |  |  | import org.springframework.boot.ApplicationArguments; | 
|---|
|  |  |  | import org.springframework.boot.ApplicationRunner; | 
|---|
|  |  |  | import org.springframework.core.annotation.Order; | 
|---|
|  |  |  | import org.springframework.scheduling.annotation.Async; | 
|---|
|  |  |  | import org.springframework.stereotype.Service; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import javax.annotation.PostConstruct; | 
|---|
|  |  |  | import javax.annotation.PreDestroy; | 
|---|
|  |  |  | import javax.annotation.Resource; | 
|---|
|  |  |  | import java.io.File; | 
|---|
|  |  |  | import java.util.*; | 
|---|
|  |  |  | import java.util.regex.Matcher; | 
|---|
|  |  |  | import java.util.regex.Pattern; | 
|---|
|  |  |  | 
|---|
|  |  |  | * @Version: 1.0 | 
|---|
|  |  |  | **/ | 
|---|
|  |  |  | @Service | 
|---|
|  |  |  | @Slf4j(topic = "cmd") | 
|---|
|  |  |  | @Slf4j(topic = "vtdu") | 
|---|
|  |  |  | @Order(2) | 
|---|
|  |  |  | public class MediaServiceImpl implements IMediaService { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Value("${mediamtx.host}") | 
|---|
|  |  |  | String mediamtxHost; | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 添加流媒体 | 
|---|
|  |  |  | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | public Map<String, String> addPath(String name, String sourceUrl, String mode, String isCode) { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | String rtspUrl = "rtsp://" + mediamtxHost + ":8554/" + name; | 
|---|
|  |  |  | String rtmpUrl = "rtmp://" + mediamtxHost + ":1935/" + name; | 
|---|
|  |  |  | String webrtcUrl = "http://" + mediamtxHost + ":8889/" + name; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | Conf mediaInfo = new Conf(); | 
|---|
|  |  |  | String rootPath = System.getProperty("user.dir").replaceAll("\\\\", "/") + "/lib/mediamtx/"; | 
|---|
|  |  |  | if (isCode.equals("1")) { | 
|---|
|  |  |  | mediaInfo.setSource("publisher"); | 
|---|
|  |  |  | //默认软解码 | 
|---|
|  |  |  | String cmd = "ffmpeg -rtsp_transport tcp -i " + sourceUrl + " -vcodec libx264 -preset:v ultrafast -r 25 -keyint_min 25 -g 60 -sc_threshold 0 -threads 6  -b:v 2048k -acodec opus  -strict -2 -f rtsp rtsp://localhost:$RTSP_PORT/$MTX_PATH"; | 
|---|
|  |  |  | if (mode.equals("0")) {//硬解码 | 
|---|
|  |  |  | cmd = "ffmpeg -hwaccel cuvid -c:v hevc_cuvid  -rtsp_transport tcp  -i " + sourceUrl + " -c:v h264_nvenc  -r 25 -g 60 -sc_threshold 0 -threads 6  -b:v 2048k -bf 0 -acodec opus  -strict -2 -f rtsp rtsp://localhost:$RTSP_PORT/$MTX_PATH"; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | mediaInfo.setRunondemand(cmd); | 
|---|
|  |  |  | mediaInfo.setRunondemandrestart(true); | 
|---|
|  |  |  | mediaInfo.setRunondemandcloseafter("5s"); | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | mediaInfo.setSource(sourceUrl); | 
|---|
|  |  |  | mediaInfo.setSourceondemand(true); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | mediaInfo.setMaxReaders(100); | 
|---|
|  |  |  | mediaInfo.setSourceprotocol("tcp"); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | List<String> nameList=new ArrayList<>(); | 
|---|
|  |  |  | String paths = mediaClient.paths(); | 
|---|
|  |  |  | JsonsRoot jsonsRoot = JSONObject.parseObject(paths, JsonsRoot.class); | 
|---|
|  |  |  | List<Items> items = jsonsRoot.getItems(); | 
|---|
|  |  |  | for (Items item : items) { | 
|---|
|  |  |  | nameList.add(item.getName()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | if(!nameList.contains(name)) { | 
|---|
|  |  |  | mediaClient.addPath(name, mediaInfo); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | Map<String, String> map = new HashMap<>(); | 
|---|
|  |  |  | map.put("rtspUrl", rtspUrl); | 
|---|
|  |  |  | map.put("rtmpUrl", rtmpUrl); | 
|---|
|  |  |  | map.put("webrtcUrl", webrtcUrl); | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | String rtspUrl = "rtsp://" + mediamtxHost + ":8554/" + name; | 
|---|
|  |  |  | String rtmpUrl = "rtmp://" + mediamtxHost + ":1935/" + name; | 
|---|
|  |  |  | String webrtcUrl = "http://" + mediamtxHost + ":8889/" + name; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | Conf conf = new Conf(); | 
|---|
|  |  |  | String rootPath = System.getProperty("user.dir").replaceAll("\\\\", "/") + "/server/mediamtx/"; | 
|---|
|  |  |  | if (isCode.equals("1")) { | 
|---|
|  |  |  | conf.setSource("publisher"); | 
|---|
|  |  |  | //默认软解码 | 
|---|
|  |  |  | String cmd = "ffmpeg -rtsp_transport tcp -i " + sourceUrl + " -vcodec libx264 -preset:v ultrafast -r 25 -keyint_min 25 -g 60 -sc_threshold 0 -threads 6  -b:v 2048k -acodec opus  -strict -2 -f rtsp rtsp://localhost:$RTSP_PORT/$MTX_PATH"; | 
|---|
|  |  |  | if (mode.equals("0")) {//硬解码 | 
|---|
|  |  |  | cmd = rootPath + "ffmpeg -hwaccel cuvid -c:v hevc_cuvid  -rtsp_transport tcp  -i " + sourceUrl + " -c:v h264_nvenc  -r 25 -g 60 -sc_threshold 0 -threads 6  -b:v 2048k -bf 0 -acodec opus  -strict -2 -f rtsp rtsp://localhost:$RTSP_PORT/$MTX_PATH"; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | conf.setRunOnDemand(cmd); | 
|---|
|  |  |  | conf.setRunOnDemandRestart(true); | 
|---|
|  |  |  | conf.setRunOnDemandCloseAfter("5s"); | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | conf.setSource(sourceUrl); | 
|---|
|  |  |  | conf.setSourceOnDemand(true); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | conf.setMaxReaders(100); | 
|---|
|  |  |  | conf.setSourceProtocol("tcp"); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (!checkNameExist(name)) { | 
|---|
|  |  |  | mediaClient.addPath(name, conf); | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | mediaClient.editPath(name, conf); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | map.put("rtspUrl", rtspUrl); | 
|---|
|  |  |  | map.put("rtmpUrl", rtmpUrl); | 
|---|
|  |  |  | map.put("webrtcUrl", webrtcUrl); | 
|---|
|  |  |  | } catch (ForestNetworkException ex) { | 
|---|
|  |  |  | log.error("添加流媒体异常:" + ex.getMessage()); | 
|---|
|  |  |  | } catch (ForestRuntimeException ex) { | 
|---|
|  |  |  | log.error("添加流媒体异常:" + ex.getMessage()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return map; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  | String rtmpUrl = "rtmp://" + mediamtxHost + ":1935/" + name; | 
|---|
|  |  |  | String webrtcUrl = "http://" + mediamtxHost + ":8889/" + name; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | Conf mediaInfo = new Conf(); | 
|---|
|  |  |  | Conf conf = new Conf(); | 
|---|
|  |  |  | String rootPath = System.getProperty("user.dir").replaceAll("\\\\", "/") + "/lib/mediamtx/"; | 
|---|
|  |  |  | if (isCode.equals("1")) { | 
|---|
|  |  |  | mediaInfo.setSource("publisher"); | 
|---|
|  |  |  | conf.setSource("publisher"); | 
|---|
|  |  |  | //默认软解码 | 
|---|
|  |  |  | String cmd = "ffmpeg -rtsp_transport tcp -i " + sourceUrl + " -vcodec libx264 -preset:v ultrafast -r 25 -keyint_min 25 -g 60 -sc_threshold 0 -threads 6  -b:v 2048k -acodec opus  -strict -2 -f rtsp rtsp://localhost:$RTSP_PORT/$MTX_PATH"; | 
|---|
|  |  |  | if (mode.equals("0")) {//硬解码 | 
|---|
|  |  |  | cmd = "ffmpeg -hwaccel cuvid -c:v hevc_cuvid  -rtsp_transport tcp  -i " + sourceUrl + " -c:v h264_nvenc  -r 25 -g 60 -sc_threshold 0 -threads 6  -b:v 2048k -bf 0 -acodec opus  -strict -2 -f rtsp rtsp://localhost:$RTSP_PORT/$MTX_PATH"; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | mediaInfo.setRunondemand(cmd); | 
|---|
|  |  |  | mediaInfo.setRunondemandrestart(true); | 
|---|
|  |  |  | mediaInfo.setRunondemandcloseafter("5s"); | 
|---|
|  |  |  | conf.setRunOnDemand(cmd); | 
|---|
|  |  |  | conf.setRunOnDemandRestart(true); | 
|---|
|  |  |  | conf.setRunOnDemandCloseAfter("5s"); | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | mediaInfo.setSource(sourceUrl); | 
|---|
|  |  |  | conf.setSource(sourceUrl); | 
|---|
|  |  |  | conf.setSourceOnDemand(true); | 
|---|
|  |  |  | conf.setRunOnDemand(""); | 
|---|
|  |  |  | conf.setRunOnDemandRestart(false); | 
|---|
|  |  |  | conf.setRunOnDemandCloseAfter("5s"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | mediaInfo.setMaxReaders(100); | 
|---|
|  |  |  | mediaInfo.setSourceprotocol("tcp"); | 
|---|
|  |  |  | conf.setMaxReaders(100); | 
|---|
|  |  |  | conf.setSourceProtocol("tcp"); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | mediaClient.editPath(name, mediaInfo); | 
|---|
|  |  |  | if (checkNameExist(name)) { | 
|---|
|  |  |  | mediaClient.editPath(name, conf); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // Map<String,String> map=new HashMap<>(); | 
|---|
|  |  |  | map.put("rtspUrl", rtspUrl); | 
|---|
|  |  |  | map.put("rtmpUrl", rtmpUrl); | 
|---|
|  |  |  | map.put("webrtcUrl", webrtcUrl); | 
|---|
|  |  |  | } catch (ForestNetworkException ex) { | 
|---|
|  |  |  | log.error(ex.getMessage()); | 
|---|
|  |  |  | } catch (ForestRuntimeException ex) { | 
|---|
|  |  |  | log.error("修改流媒体异常:" + ex.getMessage()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return map; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | public StreamInfo getPathInfo(String name) { | 
|---|
|  |  |  | Items item = mediaClient.getPathInfo(name); | 
|---|
|  |  |  | Conf conf = mediaClient.getPathInfo(name); | 
|---|
|  |  |  | StreamInfo info = new StreamInfo(); | 
|---|
|  |  |  | //ID | 
|---|
|  |  |  | info.setName(name); | 
|---|
|  |  |  | String runOn; | 
|---|
|  |  |  | if (StringUtils.isNotEmpty(item.getConf().getRunondemand())) { | 
|---|
|  |  |  | runOn = item.getConf().getRunondemand(); | 
|---|
|  |  |  | String runOn = ""; | 
|---|
|  |  |  | if (StringUtils.isNotEmpty(conf.getRunOnDemand())) { | 
|---|
|  |  |  | runOn = conf.getRunOnDemand(); | 
|---|
|  |  |  | info.setMode("0"); | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | //runOn = item.getConf().getRunonready(); | 
|---|
|  |  |  | runOn = item.getConf().getRunoninit(); | 
|---|
|  |  |  | info.setMode("1"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | //RTSP源地址 | 
|---|
|  |  |  | 
|---|
|  |  |  | info.setRtspSource(matcher.group()); | 
|---|
|  |  |  | info.setIsCode("1"); | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | info.setRtspSource(item.getConf().getSource()); | 
|---|
|  |  |  | info.setRtspSource(conf.getSource()); | 
|---|
|  |  |  | info.setIsCode("0"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return info; | 
|---|
|  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | public void removePath(String[] names) { | 
|---|
|  |  |  | for (String name : names) { | 
|---|
|  |  |  | mediaClient.removePath(name); | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | for (String name : names) { | 
|---|
|  |  |  | if (checkNameExist(name)) { | 
|---|
|  |  |  | mediaClient.removePath(name); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } catch (Exception ex) { | 
|---|
|  |  |  | log.error("批量移除流媒体异常:" + ex.getMessage()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | public void removePath(String name) { | 
|---|
|  |  |  | mediaClient.removePath(name); | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | if (checkNameExist(name)) { | 
|---|
|  |  |  | mediaClient.removePath(name); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } catch (ForestRuntimeException ex) { | 
|---|
|  |  |  | log.error("移除流媒体异常:" + ex.getMessage()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | public List<StreamInfo> paths() { | 
|---|
|  |  |  | String list = mediaClient.paths(); | 
|---|
|  |  |  | JsonsRoot jsonsRoot = JSONObject.parseObject(list, JsonsRoot.class); | 
|---|
|  |  |  | List<Items> items = jsonsRoot.getItems(); | 
|---|
|  |  |  | public List<StreamInfo> paths(Integer pageNum, Integer pageSize) { | 
|---|
|  |  |  | Paths paths = mediaClient.paths(pageNum - 1, pageSize); | 
|---|
|  |  |  | List<Items> items = paths.getItems(); | 
|---|
|  |  |  | List<StreamInfo> pathInfoList = new ArrayList<>(); | 
|---|
|  |  |  | for (Items item : items) { | 
|---|
|  |  |  | StreamInfo info = new StreamInfo(); | 
|---|
|  |  |  | //ID | 
|---|
|  |  |  | String name = item.getName(); | 
|---|
|  |  |  | info.setName(name); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | Conf conf = mediaClient.getPathInfo(name); | 
|---|
|  |  |  | String runOn = ""; | 
|---|
|  |  |  | if (StringUtils.isNotEmpty(item.getConf().getRunondemand())) { | 
|---|
|  |  |  | runOn = item.getConf().getRunondemand(); | 
|---|
|  |  |  | if (StringUtils.isNotEmpty(conf.getRunOnDemand())) { | 
|---|
|  |  |  | runOn = conf.getRunOnDemand(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | //RTSP源地址 | 
|---|
|  |  |  | Matcher matcher = Pattern.compile("rtsp://[^\\s\"]+").matcher(runOn); | 
|---|
|  |  |  | 
|---|
|  |  |  | info.setRtspSource(matcher.group()); | 
|---|
|  |  |  | info.setIsCode("1"); | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | info.setRtspSource(item.getConf().getSource()); | 
|---|
|  |  |  | info.setRtspSource(conf.getSource()); | 
|---|
|  |  |  | info.setIsCode("0"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | //传输协议 | 
|---|
|  |  |  | 
|---|
|  |  |  | return pathInfoList; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | public RtspSession getRtspSessionById(String sessionId) { | 
|---|
|  |  |  | String list = mediaClient.getRtspsessionById(sessionId); | 
|---|
|  |  |  | RtspSession rtspSession = JSONObject.parseObject(list, RtspSession.class); | 
|---|
|  |  |  | return rtspSession; | 
|---|
|  |  |  | return mediaClient.getRtspsessionById(sessionId); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | public WebrtcSession getWebrtcSessionById(String sessionId) { | 
|---|
|  |  |  | String list = mediaClient.getWebrtcsessionById(sessionId); | 
|---|
|  |  |  | WebrtcSession webrtcSession = JSONObject.parseObject(list, WebrtcSession.class); | 
|---|
|  |  |  | return webrtcSession; | 
|---|
|  |  |  | return mediaClient.getWebrtcsessionById(sessionId); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | public RtmpSession getRtmpSessionById(String sessionId) { | 
|---|
|  |  |  | String list = mediaClient.getRtmpsessionById(sessionId); | 
|---|
|  |  |  | RtmpSession rtmpSession = JSONObject.parseObject(list, RtmpSession.class); | 
|---|
|  |  |  | return rtmpSession; | 
|---|
|  |  |  | return mediaClient.getRtmpsessionById(sessionId); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | 
|---|
|  |  |  | * 2023/8/29 9:37:05 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | public List<StreamInfo> getPushStreamList() { | 
|---|
|  |  |  | public TableDataInfo getPushStreamList(Integer pageNum, Integer pageSize) { | 
|---|
|  |  |  | TableDataInfo tableDataInfo = new TableDataInfo(); | 
|---|
|  |  |  | List<StreamInfo> PushStreamInfoList = new ArrayList<>(); | 
|---|
|  |  |  | String list = mediaClient.paths(); | 
|---|
|  |  |  | JsonsRoot jsonsRoot = JSONObject.parseObject(list, JsonsRoot.class); | 
|---|
|  |  |  | List<Items> items = jsonsRoot.getItems(); | 
|---|
|  |  |  | Paths paths = mediaClient.paths(pageNum - 1, pageSize); | 
|---|
|  |  |  | int itemCount = paths.getItemCount(); | 
|---|
|  |  |  | tableDataInfo.setTotal(itemCount); | 
|---|
|  |  |  | List<Items> items = paths.getItems(); | 
|---|
|  |  |  | for (Items item : items) { | 
|---|
|  |  |  | StreamInfo info = new StreamInfo(); | 
|---|
|  |  |  | //ID | 
|---|
|  |  |  | String name = item.getName(); | 
|---|
|  |  |  | info.setName(name); | 
|---|
|  |  |  | Conf conf = mediaClient.getPathInfo(name); | 
|---|
|  |  |  | //RTMP播放地址 | 
|---|
|  |  |  | String rtmpUrl = "rtmp://" + mediamtxHost + ":1935/" + name; | 
|---|
|  |  |  | info.setRtmpUrl(rtmpUrl); | 
|---|
|  |  |  | 
|---|
|  |  |  | if (source == null || source.getId().equals("")) { | 
|---|
|  |  |  | //会话ID | 
|---|
|  |  |  | info.setId("0"); | 
|---|
|  |  |  | //上行流量 | 
|---|
|  |  |  | //下行流量 | 
|---|
|  |  |  | long bytesReceived = item.getBytesReceived(); | 
|---|
|  |  |  | String formatReceivedSize = ArdTool.formatFileSize(bytesReceived); | 
|---|
|  |  |  | info.setUpTraffic(formatReceivedSize); | 
|---|
|  |  |  | info.setDownTraffic(formatReceivedSize); | 
|---|
|  |  |  | //上行流量 | 
|---|
|  |  |  | long bytesSent = item.getBytesSent(); | 
|---|
|  |  |  | String formatSentdSize = ArdTool.formatFileSize(bytesSent); | 
|---|
|  |  |  | info.setUpTraffic(formatSentdSize); | 
|---|
|  |  |  | info.setBeginTime(item.getReadyTime()); | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | RtspSession rtspSession = getRtspSessionById(source.getId()); | 
|---|
|  |  |  | //会话ID | 
|---|
|  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  | //RTSP源地址 | 
|---|
|  |  |  | String runOn = ""; | 
|---|
|  |  |  | if (StringUtils.isNotEmpty(item.getConf().getRunondemand())) { | 
|---|
|  |  |  | runOn = item.getConf().getRunondemand(); | 
|---|
|  |  |  | if (StringUtils.isNotEmpty(conf.getRunOnDemand())) { | 
|---|
|  |  |  | runOn = conf.getRunOnDemand(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | Matcher matcher = Pattern.compile("rtsp://[^\\s\"]+").matcher(runOn); | 
|---|
|  |  |  | if (matcher.find()) { | 
|---|
|  |  |  | info.setRtspSource(matcher.group()); | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | info.setRtspSource(item.getConf().getSource()); | 
|---|
|  |  |  | info.setRtspSource(conf.getSource()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | //传输协议 | 
|---|
|  |  |  | info.setProtocol(item.getConf().getSourceprotocol()); | 
|---|
|  |  |  | info.setProtocol(conf.getSourceProtocol()); | 
|---|
|  |  |  | //拉流数量 | 
|---|
|  |  |  | List<Readers> readers = item.getReaders(); | 
|---|
|  |  |  | info.setNum(readers.size()); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | PushStreamInfoList.add(info); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return PushStreamInfoList; | 
|---|
|  |  |  | tableDataInfo.setRows(PushStreamInfoList); | 
|---|
|  |  |  | tableDataInfo.setCode(HttpStatus.SUCCESS); | 
|---|
|  |  |  | tableDataInfo.setMsg("查询成功"); | 
|---|
|  |  |  | return tableDataInfo; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 获取拉流列表 | 
|---|
|  |  |  | * 获取webrtc拉流列表 | 
|---|
|  |  |  | * 刘苏义 | 
|---|
|  |  |  | * 2023/8/29 9:37:05 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | public List<StreamInfo> getPullStreamList() { | 
|---|
|  |  |  | List<StreamInfo> PullStreamInfoList = new ArrayList<>(); | 
|---|
|  |  |  | String list = mediaClient.paths(); | 
|---|
|  |  |  | JsonsRoot jsonsRoot = JSONObject.parseObject(list, JsonsRoot.class); | 
|---|
|  |  |  | List<Items> items = jsonsRoot.getItems(); | 
|---|
|  |  |  | for (Items item : items) { | 
|---|
|  |  |  | List<Readers> readers = item.getReaders(); | 
|---|
|  |  |  | for (Readers reader : readers) { | 
|---|
|  |  |  | StreamInfo info = new StreamInfo(); | 
|---|
|  |  |  | //ID | 
|---|
|  |  |  | String name = item.getName(); | 
|---|
|  |  |  | info.setName(name); | 
|---|
|  |  |  | //传输协议 | 
|---|
|  |  |  | info.setProtocol(item.getConf().getSourceprotocol()); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | String type = reader.getType(); | 
|---|
|  |  |  | switch (type) { | 
|---|
|  |  |  | case "rtmpConn": | 
|---|
|  |  |  | info.setSessionType("rtmp"); | 
|---|
|  |  |  | //webrtc播放地址 | 
|---|
|  |  |  | String url = "rtmp://" + mediamtxHost + ":1935/" + name; | 
|---|
|  |  |  | info.setRtspUrl(url); | 
|---|
|  |  |  | RtmpSession rtmpSession = getRtmpSessionById(reader.getId()); | 
|---|
|  |  |  | //会话ID | 
|---|
|  |  |  | info.setId(rtmpSession.getId()); | 
|---|
|  |  |  | //开始拉流时间 | 
|---|
|  |  |  | info.setBeginTime(rtmpSession.getCreated()); | 
|---|
|  |  |  | //上行流量 | 
|---|
|  |  |  | long bytesReceived = rtmpSession.getBytesReceived(); | 
|---|
|  |  |  | String formatReceivedSize = ArdTool.formatFileSize(bytesReceived); | 
|---|
|  |  |  | info.setUpTraffic(formatReceivedSize); | 
|---|
|  |  |  | //下行流量 | 
|---|
|  |  |  | long bytesSent = rtmpSession.getBytesSent(); | 
|---|
|  |  |  | String formatSentSize = ArdTool.formatFileSize(bytesSent); | 
|---|
|  |  |  | info.setDownTraffic(formatSentSize); | 
|---|
|  |  |  | //拉流服务器 | 
|---|
|  |  |  | info.setRemoteAddr(rtmpSession.getRemoteAddr()); | 
|---|
|  |  |  | PullStreamInfoList.add(info); | 
|---|
|  |  |  | break; | 
|---|
|  |  |  | case "webRTCSession": | 
|---|
|  |  |  | info.setSessionType("webrtc"); | 
|---|
|  |  |  | //webrtc播放地址 | 
|---|
|  |  |  | url = "http://" + mediamtxHost + ":8889/" + name; | 
|---|
|  |  |  | info.setRtspUrl(url); | 
|---|
|  |  |  | WebrtcSession webrtcSession = getWebrtcSessionById(reader.getId()); | 
|---|
|  |  |  | //会话ID | 
|---|
|  |  |  | info.setId(webrtcSession.getId()); | 
|---|
|  |  |  | //开始拉流时间 | 
|---|
|  |  |  | info.setBeginTime(webrtcSession.getCreated()); | 
|---|
|  |  |  | //上行流量 | 
|---|
|  |  |  | bytesReceived = webrtcSession.getBytesReceived(); | 
|---|
|  |  |  | formatReceivedSize = ArdTool.formatFileSize(bytesReceived); | 
|---|
|  |  |  | info.setUpTraffic(formatReceivedSize); | 
|---|
|  |  |  | //下行流量 | 
|---|
|  |  |  | bytesSent = webrtcSession.getBytesSent(); | 
|---|
|  |  |  | formatSentSize = ArdTool.formatFileSize(bytesSent); | 
|---|
|  |  |  | info.setDownTraffic(formatSentSize); | 
|---|
|  |  |  | //拉流服务器 | 
|---|
|  |  |  | info.setRemoteAddr(webrtcSession.getRemoteAddr()); | 
|---|
|  |  |  | PullStreamInfoList.add(info); | 
|---|
|  |  |  | break; | 
|---|
|  |  |  | case "rtspSession": | 
|---|
|  |  |  | info.setSessionType("rtsp"); | 
|---|
|  |  |  | //RTSP播放地址 | 
|---|
|  |  |  | String rtspUrl = "rtsp://" + mediamtxHost + ":8554/" + name; | 
|---|
|  |  |  | info.setRtspUrl(rtspUrl); | 
|---|
|  |  |  | RtspSession rtspSession = getRtspSessionById(reader.getId()); | 
|---|
|  |  |  | //会话ID | 
|---|
|  |  |  | info.setId(rtspSession.getId()); | 
|---|
|  |  |  | //开始拉流时间 | 
|---|
|  |  |  | info.setBeginTime(rtspSession.getCreated()); | 
|---|
|  |  |  | //上行流量 | 
|---|
|  |  |  | bytesReceived = rtspSession.getBytesReceived(); | 
|---|
|  |  |  | formatReceivedSize = ArdTool.formatFileSize(bytesReceived); | 
|---|
|  |  |  | info.setUpTraffic(formatReceivedSize); | 
|---|
|  |  |  | //下行流量 | 
|---|
|  |  |  | bytesSent = rtspSession.getBytesSent(); | 
|---|
|  |  |  | formatSentSize = ArdTool.formatFileSize(bytesSent); | 
|---|
|  |  |  | info.setDownTraffic(formatSentSize); | 
|---|
|  |  |  | //拉流服务器 | 
|---|
|  |  |  | info.setRemoteAddr(rtspSession.getRemoteAddr()); | 
|---|
|  |  |  | PullStreamInfoList.add(info); | 
|---|
|  |  |  | break; | 
|---|
|  |  |  | public TableDataInfo getPullWebrtcStreamList(Integer pageNum, Integer pageSize) { | 
|---|
|  |  |  | TableDataInfo tableDataInfo = new TableDataInfo(); | 
|---|
|  |  |  | WebrtcSessions WebrtcSessions = mediaClient.webrtcsessions(pageNum-1, pageSize); | 
|---|
|  |  |  | List<WebrtcSession> webrtcsessions = WebrtcSessions.getItems(); | 
|---|
|  |  |  | webrtcsessions.stream().forEach( | 
|---|
|  |  |  | webrtcSession -> { | 
|---|
|  |  |  | webrtcSession.setUpStream(ArdTool.formatFileSize(webrtcSession.getBytesReceived())); | 
|---|
|  |  |  | webrtcSession.setDownStream(ArdTool.formatFileSize(webrtcSession.getBytesSent())); | 
|---|
|  |  |  | webrtcSession.setBeginTime(webrtcSession.getCreated()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | Comparator<StreamInfo> comparator = Comparator.comparing(streamInfo -> streamInfo.getBeginTime()); // 使用Collections.sort方法进行排序 Collections.sort(personList, comparator); | 
|---|
|  |  |  | Collections.sort(PullStreamInfoList, comparator.reversed()); | 
|---|
|  |  |  | return PullStreamInfoList; | 
|---|
|  |  |  | ); | 
|---|
|  |  |  | tableDataInfo.setTotal(WebrtcSessions.getItemCount()); | 
|---|
|  |  |  | tableDataInfo.setRows(webrtcsessions); | 
|---|
|  |  |  | tableDataInfo.setCode(HttpStatus.SUCCESS); | 
|---|
|  |  |  | tableDataInfo.setMsg("查询成功"); | 
|---|
|  |  |  | return tableDataInfo; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 获取rtmp拉流列表 | 
|---|
|  |  |  | * 刘苏义 | 
|---|
|  |  |  | * 2023/8/29 9:37:05 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | public TableDataInfo getPullRtmpStreamList(Integer pageNum, Integer pageSize) { | 
|---|
|  |  |  | TableDataInfo tableDataInfo = new TableDataInfo(); | 
|---|
|  |  |  | RtmpSessions rtmpSessions = mediaClient.rtmpsessions(pageNum-1, pageSize); | 
|---|
|  |  |  | List<RtmpSession> webrtcsessions = rtmpSessions.getItems(); | 
|---|
|  |  |  | webrtcsessions.stream().forEach( | 
|---|
|  |  |  | webrtcSession -> { | 
|---|
|  |  |  | webrtcSession.setUpStream(ArdTool.formatFileSize(webrtcSession.getBytesReceived())); | 
|---|
|  |  |  | webrtcSession.setDownStream(ArdTool.formatFileSize(webrtcSession.getBytesSent())); | 
|---|
|  |  |  | webrtcSession.setBeginTime(webrtcSession.getCreated()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | ); | 
|---|
|  |  |  | tableDataInfo.setTotal(rtmpSessions.getItemCount()); | 
|---|
|  |  |  | tableDataInfo.setRows(webrtcsessions); | 
|---|
|  |  |  | tableDataInfo.setCode(HttpStatus.SUCCESS); | 
|---|
|  |  |  | tableDataInfo.setMsg("查询成功"); | 
|---|
|  |  |  | return tableDataInfo; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 获取rtsp拉流列表 | 
|---|
|  |  |  | * 刘苏义 | 
|---|
|  |  |  | * 2023/8/29 9:37:05 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | public TableDataInfo getPullRtspStreamList(Integer pageNum, Integer pageSize) { | 
|---|
|  |  |  | TableDataInfo tableDataInfo = new TableDataInfo(); | 
|---|
|  |  |  | RtspSessions rtspSessions = mediaClient.rtspsessions(pageNum-1, pageSize); | 
|---|
|  |  |  | List<RtspSession> webrtcsessions = rtspSessions.getItems(); | 
|---|
|  |  |  | webrtcsessions.stream().forEach( | 
|---|
|  |  |  | webrtcSession -> { | 
|---|
|  |  |  | webrtcSession.setUpStream(ArdTool.formatFileSize(webrtcSession.getBytesReceived())); | 
|---|
|  |  |  | webrtcSession.setDownStream(ArdTool.formatFileSize(webrtcSession.getBytesSent())); | 
|---|
|  |  |  | webrtcSession.setBeginTime(webrtcSession.getCreated()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | ); | 
|---|
|  |  |  | tableDataInfo.setTotal(rtspSessions.getItemCount()); | 
|---|
|  |  |  | tableDataInfo.setRows(webrtcsessions); | 
|---|
|  |  |  | tableDataInfo.setCode(HttpStatus.SUCCESS); | 
|---|
|  |  |  | tableDataInfo.setMsg("查询成功"); | 
|---|
|  |  |  | return tableDataInfo; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | *  获取流媒体name列表 | 
|---|
|  |  |  | * 获取流媒体name列表 | 
|---|
|  |  |  | * 刘苏义 | 
|---|
|  |  |  | * 2023/10/13 14:19:07 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | public List<String> getNameList() { | 
|---|
|  |  |  | List<String> nameList=new ArrayList<>(); | 
|---|
|  |  |  | String paths = mediaClient.paths(); | 
|---|
|  |  |  | JsonsRoot jsonsRoot = JSONObject.parseObject(paths, JsonsRoot.class); | 
|---|
|  |  |  | List<Items> items = jsonsRoot.getItems(); | 
|---|
|  |  |  | for (Items item : items) { | 
|---|
|  |  |  | nameList.add(item.getName()); | 
|---|
|  |  |  | List<String> nameList = new ArrayList<>(); | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | Paths paths = mediaClient.paths(0, 1000); | 
|---|
|  |  |  | List<Items> items = paths.getItems(); | 
|---|
|  |  |  | for (Items item : items) { | 
|---|
|  |  |  | nameList.add(item.getName()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } catch (Exception ex) { | 
|---|
|  |  |  | log.error("获取流媒体name列表异常:" + ex.getMessage()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return nameList; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 配置流媒体参数 | 
|---|
|  |  |  | * 检查name是否存在 | 
|---|
|  |  |  | * 刘苏义 | 
|---|
|  |  |  | * 2023/10/19 15:18:45 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | public String setConfig(Config config) { | 
|---|
|  |  |  | return mediaClient.setConfig(config); | 
|---|
|  |  |  | public boolean checkNameExist(String name) { | 
|---|
|  |  |  | boolean result = false; | 
|---|
|  |  |  | List<String> nameList = getNameList(); | 
|---|
|  |  |  | if (nameList.contains(name)) { | 
|---|
|  |  |  | result = true; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return result; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | } | 
|---|