diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/config/ZLMediaKitConfig.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/config/ZLMediaKitConfig.java new file mode 100644 index 00000000..d6289ff2 --- /dev/null +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/config/ZLMediaKitConfig.java @@ -0,0 +1,24 @@ +package org.dromara.sis.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Data +@Configuration +@ConfigurationProperties(prefix = "zlm") +public class ZLMediaKitConfig { + + private String ip; + + private String apiSecret; + + private Short rtspPort; + + private Short rtmpPort; + + private Short httpPort; + + private String vhost; + +} diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/controller/zkmedia/ZKLmediaController.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/controller/zkmedia/ZKLmediaController.java new file mode 100644 index 00000000..08bfff36 --- /dev/null +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/controller/zkmedia/ZKLmediaController.java @@ -0,0 +1,125 @@ +package org.dromara.sis.controller.zkmedia; + +import cn.hutool.core.util.IdUtil; +import lombok.extern.slf4j.Slf4j; +import org.dromara.common.core.domain.R; +import org.dromara.sis.sdk.zkmedia.MediaServerUtils; +import org.dromara.sis.sdk.zkmedia.ZLMediaKitService; +import org.dromara.sis.sdk.zkmedia.model.AddStreamProxy; +import org.dromara.sis.sdk.zkmedia.model.AddStreamProxyResp; +import org.dromara.sis.sdk.zkmedia.model.StartStreamProxy; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +/** + * ZKLmedia 流媒体服务 + * + * @author lxj + * @since 2025-07-15 + */ +@Slf4j +@RestController +@RequestMapping("/stream") +public class ZKLmediaController { + + @Resource + private ZLMediaKitService zlMediaKitService; + + + private static final String HIK_REALTIME_RTSP_TEMPLATE = "rtsp://%s:%s@%s:%s/Streaming/Channels/%s"; + private static final String DAHUA_REALTIME_RTSP_TEMPLATE = "rtsp://%s:%s@%s:%s/cam/realmonitor?channel=%s&subtype=0"; + + private static final String HIK_HISTORY_RTSP_TEMPLATE = "rtsp://%s:%s@%s:%s/Streaming/tracks/%s?starttime=%s&endtime=%s"; + private static final String DAHUA_HISTORY_RTSP_TEMPLATE = "rtsp://%s:%s@%s:%s/cam/playback?channel=%s&subtype=0&starttime=%s&endtime=%s"; + + /** + * 创建拉流任务,返回null代表创建拉流任务失败 + * + * @param data 创建拉流设备信息(如果外网不建议使用这种方式) + * @return 返回拉流任务信息 + */ + @PostMapping("/realtime/add") + public R alarm(@RequestBody @Validated AddStreamProxy data) { + StartStreamProxy proxy = new StartStreamProxy(); + proxy.setApp("realtime"); + String s = IdUtil.fastSimpleUUID(); + proxy.setStream(s); + if ("DS1010".equals(data.getFactoryNo())) { + proxy.setUrl(String.format(HIK_REALTIME_RTSP_TEMPLATE, data.getAccount(), data.getPwd(), data.getVideoIp(), data.getVideoPort(), data.getChannelId())); + } else if ("DS1014".equals(data.getFactoryNo())) { + proxy.setUrl(String.format(DAHUA_REALTIME_RTSP_TEMPLATE, data.getAccount(), data.getPwd(), data.getVideoIp(), data.getVideoPort(), data.getChannelId())); + } else { + throw new RuntimeException("未知的设备类型!"); + } + AddStreamProxyResp addStreamProxyResp = zlMediaKitService.addStreamProxy(proxy); + if (addStreamProxyResp != null) { + return R.ok(addStreamProxyResp); + } + return R.fail(); + } + + /** + * 创建历史回放拉流任务,返回null代表创建拉流任务失败 + * + * @param data 创建拉流设备信息(如果外网不建议使用这种方式) + * @return 返回拉流任务信息 + */ + @PostMapping("/history/add") + public R history(@RequestBody @Validated AddStreamProxy data) throws InterruptedException { + StartStreamProxy proxy = new StartStreamProxy(); + proxy.setApp("history"); + String s = IdUtil.fastSimpleUUID(); + proxy.setStream(s); + if ("DS1010".equals(data.getFactoryNo())) { + String pattern = "yyyyMMdd'T'HHmmss'Z'"; + String startTime = MediaServerUtils.formatTimestamp(data.getStartTime(), "yyyyMMdd'T'HHmmss'Z'"); + String endTime = MediaServerUtils.formatTimestamp(data.getEndTime(), "yyyyMMdd'T'HHmmss'Z'"); + proxy.setUrl(String.format(HIK_HISTORY_RTSP_TEMPLATE, data.getAccount(), data.getPwd(), data.getVideoIp(), data.getVideoPort(), data.getChannelId(), startTime, endTime)); + } else if ("DS1014".equals(data.getFactoryNo())) { + String startTime = MediaServerUtils.formatTimestamp(data.getStartTime(), "yyyy_MM_dd_HH_mm_ss"); + String endTime = MediaServerUtils.formatTimestamp(data.getEndTime(), "yyyy_MM_dd_HH_mm_ss"); + proxy.setUrl(String.format(DAHUA_HISTORY_RTSP_TEMPLATE, data.getAccount(), data.getPwd(), data.getVideoIp(), data.getVideoPort(), data.getChannelId(), startTime, endTime)); + } else { + throw new RuntimeException("未知的设备类型!"); + } + AddStreamProxyResp addStreamProxyResp = zlMediaKitService.addStreamProxy(proxy); + if (addStreamProxyResp != null) { + return R.ok(addStreamProxyResp); + } + return R.fail(); + } + + /** + * 查询设备的信息 + * + * @param data 设备ip + * @return + */ + /*@PostMapping("/queryMediaInfo") + public R queryMediaInfo(@RequestBody VideoConfigTreeDTO data) { + if (StringUtils.isEmpty(data.getVideoIp())) { + throw new BizException(ErrorType.VIDEOIP_FAIL, "视频IP不能为空"); + } + logger.info("查询视频信息,参数:{}", JSONObject.toJSON(data.getVideoIp())); + TpEqpAcquisitionDTO result = tpEqpAcquisitionService.queryConfigByEqpNo(data.getVideoIp()); + logger.info("查询视频信息,返回信息:{}", JSONObject.toJSON(result)); + return BizResultVO.success(result); + } + + @PostMapping("/history/delete/{stream}") + public BizResultVO delete(@PathVariable("stream") String stream) throws InterruptedException { + StartStreamProxy proxy = new StartStreamProxy(); + proxy.setApp("history"); + proxy.setStream(stream); + String ss = zlMediaKitService.delStreamProxy(proxy); + if (ss != null) { + return BizResultVO.success(ss); + } + return BizResultVO.fail(ErrorType.ADD_STREAMPROXY_FAIL, null); + }*/ +} diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/HttpClientUtil.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/HttpClientUtil.java new file mode 100644 index 00000000..0c6da063 --- /dev/null +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/HttpClientUtil.java @@ -0,0 +1,94 @@ +package org.dromara.sis.sdk.zkmedia; + +import cn.hutool.core.collection.CollectionUtil; +import com.alibaba.fastjson2.JSONObject; +import com.alibaba.fastjson2.TypeReference; +import lombok.extern.slf4j.Slf4j; +import org.apache.http.HttpEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import org.dromara.sis.sdk.zkmedia.model.R; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +@Slf4j +public class HttpClientUtil { + + public static T get(String url, Map params, TypeReference reference) { + String s = get(url, params); + return JSONObject.parseObject(s, reference); + } + + public static R get(String url, Map params, Class cls) { + String s = get(url, params); + return JSONObject.parseObject(s, new TypeReference>(cls) { + }); + } + + public static String get(String url, Map params) { + if (params != null && !params.isEmpty()) { + List ls = new ArrayList<>(params.size()); + for (Map.Entry entry : params.entrySet()) { + ls.add(entry.getKey() + "=" + entry.getValue()); + } + url = url + "?" + CollectionUtil.join(ls, "&"); + } + + CloseableHttpResponse response; + try (CloseableHttpClient httpClient = HttpClients.createDefault()) { + HttpGet httpGet = new HttpGet(url); + response = httpClient.execute(httpGet); + log.info("ZLM请求成功,url={}, code={}", url, response.getStatusLine().getStatusCode()); + HttpEntity entity = response.getEntity(); + String res = EntityUtils.toString(entity); + log.info("ZLM请求成功,result={}", res); + return res; + } catch (Exception e) { + log.info("ZLM发起请求失败,msg={}", e.getMessage()); + return null; + } + } + + public static T post(String url, Map header, Map body, TypeReference reference) { + String res = post(url, header, body); + return JSONObject.parseObject(res, reference); + } + + public static R post(String url, Map header, Map body, Class cls) { + String res = post(url, header, body); + return JSONObject.parseObject(res, new TypeReference>(cls) { + }); + } + + + public static String post(String url, Map header, Map body) { + try (CloseableHttpClient httpClient = HttpClients.createDefault()) { + HttpPost httpPost = new HttpPost(url); + httpPost.setHeader("Content-Type", "application/json"); + if (header != null && !header.isEmpty()) { + for (Map.Entry entry : header.entrySet()) { + httpPost.setHeader(entry.getKey(), String.valueOf(entry.getValue())); + } + } + if (body != null && !body.isEmpty()) { + httpPost.setEntity(new StringEntity(JSONObject.toJSONString(body))); + } + CloseableHttpResponse response = httpClient.execute(httpPost); + HttpEntity entity = response.getEntity(); + return EntityUtils.toString(entity); + } catch (Exception e) { + log.info("ZLM发起请求失败,msg={}", e.getMessage()); + return null; + } + + + } + +} diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/MediaServerUtils.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/MediaServerUtils.java new file mode 100644 index 00000000..7d28fcac --- /dev/null +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/MediaServerUtils.java @@ -0,0 +1,36 @@ +package org.dromara.sis.sdk.zkmedia; + +import org.springframework.util.ObjectUtils; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +public class MediaServerUtils { + public static Map urlParamToMap(String params) { + HashMap map = new HashMap<>(); + if (ObjectUtils.isEmpty(params)) { + return map; + } + String[] paramsArray = params.split("&"); + if (paramsArray.length == 0) { + return map; + } + for (String param : paramsArray) { + String[] paramArray = param.split("="); + if (paramArray.length == 2) { + map.put(paramArray[0], paramArray[1]); + } + } + return map; + } + + + public static String formatTimestamp(String timestamp, String pattern) { + Date date = new Date(Long.parseLong(timestamp)); + SimpleDateFormat sdf = new SimpleDateFormat(pattern); + return sdf.format(date); + } + +} diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/ZLMediaKitService.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/ZLMediaKitService.java new file mode 100644 index 00000000..569ea4df --- /dev/null +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/ZLMediaKitService.java @@ -0,0 +1,159 @@ +package org.dromara.sis.sdk.zkmedia; + + +import org.dromara.sis.sdk.zkmedia.model.AddStreamProxyResp; +import org.dromara.sis.sdk.zkmedia.model.R; +import org.dromara.sis.sdk.zkmedia.model.StartStreamProxy; +import org.dromara.sis.sdk.zkmedia.model.ThreadsLoadDelay; + +import java.util.List; + +public interface ZLMediaKitService { + + /** + * 获取各后台 epoll(或 select)线程负载以及延时 + */ + R> getWorkThreadsLoad(); + + /** + * 获取ZLMediaKit服务器配置信息 + */ + Object getServerConfig(); + + /** + * 设置服务器配置 + */ + Object setServerConfig(); + + /** + * 重启服务器,只有 Daemon 方式才能重启,否则是直接关闭! + */ + Object restartServer(); + + /** + * 获取流列表,可选筛选参数 + */ + Object getMediaList(); + + /** + * 关闭流(目前所有类型的流都支持关闭) + */ + Object closeStreams(); + + /** + * 获取所有 TcpSession 列表(获取所有 tcp 客户端相关信息) + */ + Object getAllSession(); + + /** + * 断开 tcp 连接,比如说可以断开 rtsp、rtmp 播放器等 + */ + Object kickSession(); + + /** + * 断开 tcp 连接,比如说可以断开 rtsp、rtmp 播放器等 + */ + Object kickSessions(); + + /** + * 动态添加 rtsp/rtmp/hls/http-ts/http-flv 拉流代理(只支持 H264/H265/aac/G711/opus 负载) + */ + AddStreamProxyResp addStreamProxy(StartStreamProxy startStreamProxy); + + /** + * (流注册成功后,也可以使用close_streams接口替代) + * 关闭拉流代理 + */ + String delStreamProxy(StartStreamProxy startStreamProxy); + + /** + * 通过 fork FFmpeg 进程的方式拉流代理,支持任意协议 + */ + Object addFFmpegSource(); + + /** + * 流注册成功后,也可以使用close_streams接口替代 + */ + Object delFFmpegSource(); + + /** + * 获取 rtp 代理时的某路 ssrc rtp 信息 + */ + Object getRtpInfo(); + + /** + * 搜索文件系统,获取流对应的录像文件列表或日期文件夹列表 + */ + Object getMp4RecordFile(); + + /** + * 开始录制 hls 或 MP4 + */ + Object startRecord(); + + /** + * 停止录制流 + */ + Object stopRecord(); + + /** + * 获取流录制状态 + */ + Object isRecording(); + + /** + * 获取截图或生成实时截图并返回 + */ + Object getSnap(); + + /** + * 创建 GB28181 RTP 接收端口,如果该端口接收数据超时,则会自动被回收(不用调用 closeRtpServer 接口) + */ + Object openRtpServer(); + + /** + * 关闭 GB28181 RTP 接收端口 + */ + Object closeRtpServer(); + + /** + * 获取 openRtpServer 接口创建的所有 RTP 服务器 + */ + Object listRtpServer(); + + /** + * 作为 GB28181 客户端,启动 ps-rtp 推流,支持 rtp/udp 方式;该接口支持 rtsp/rtmp 等协议转 ps-rtp 推流。第一次推流失败会直接返回错误,成功一次后,后续失败也将无限重试。 + */ + Object startSendRtp(); + + /** + * 停止 GB28181 ps-rtp 推流 + */ + Object stopSendRtp(); + + /** + * 获取主要对象个数统计,主要用于分析内存性能 + */ + Object getStatistic(); + + /** + * 添加 rtsp/rtmp 主动推流(把本服务器的直播流推送到其他服务器去) + */ + Object addStreamPusherProxy(); + + /** + * 关闭推流,可以使用close_streams接口关闭源直播流也可以停止推流) + */ + Object delStreamPusherProxy(); + + /** + * 获取版本信息,如分支,commit id, 编译时间 + */ + Object getVersion(); + + /** + * 获取某个流观看者列表 + */ + Object getMediaPlayerList(); + +} diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/ZLMediaKitServiceImpl.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/ZLMediaKitServiceImpl.java new file mode 100644 index 00000000..ba519235 --- /dev/null +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/ZLMediaKitServiceImpl.java @@ -0,0 +1,248 @@ +package org.dromara.sis.sdk.zkmedia; + +import com.alibaba.fastjson2.TypeReference; +import lombok.extern.slf4j.Slf4j; +import org.dromara.sis.config.ZLMediaKitConfig; +import org.dromara.sis.sdk.zkmedia.model.AddStreamProxyResp; +import org.dromara.sis.sdk.zkmedia.model.R; +import org.dromara.sis.sdk.zkmedia.model.StartStreamProxy; +import org.dromara.sis.sdk.zkmedia.model.ThreadsLoadDelay; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Slf4j +@Service("com.parkclouds.media.service.ZLMediaKitServiceImpl") +public class ZLMediaKitServiceImpl implements ZLMediaKitService { + + @Resource + private ZLMediaKitConfig zlmConfig; + private static volatile String ZLM_REQUEST_PREFIX = null; + + public String getRequestUrl(String uri) { + if (ZLM_REQUEST_PREFIX == null) { + synchronized (ZLMediaKitServiceImpl.class) { + if (ZLM_REQUEST_PREFIX == null) { + ZLM_REQUEST_PREFIX = String.format("http://%s:%d/index/api/", zlmConfig.getIp(), zlmConfig.getHttpPort()); + } + } + } + return ZLM_REQUEST_PREFIX + uri; + } + + public Map getCommonParams() { + Map params = new HashMap<>(16); + params.put("secret", zlmConfig.getApiSecret()); + return params; + } + + @Override + public R> getWorkThreadsLoad() { + String url = getRequestUrl("getThreadsLoad"); + Map commonParams = getCommonParams(); + return HttpClientUtil.get(url, commonParams, new TypeReference>>() { + }); + } + + @Override + public Object getServerConfig() { + return null; + } + + @Override + public Object setServerConfig() { + return null; + } + + @Override + public Object restartServer() { + return null; + } + + @Override + public Object getMediaList() { + return null; + } + + @Override + public Object closeStreams() { + return null; + } + + @Override + public Object getAllSession() { + return null; + } + + @Override + public Object kickSession() { + return null; + } + + @Override + public Object kickSessions() { + return null; + } + + /** + * 获取拉流地址 + */ + private AddStreamProxyResp setPlayerUrl(String app, String streamId, AddStreamProxyResp resp) { + if (resp == null) { + resp = new AddStreamProxyResp(); + } + // RTMP 播放地址 + resp.setRtmp(String.format("rtmp://%s:%d/%s/%s", zlmConfig.getIp(), zlmConfig.getRtmpPort(), app, streamId)); + // RTSP 播放地址 + resp.setRtsp(String.format("rtsp://%s:%d/%s/%s", zlmConfig.getIp(), zlmConfig.getRtspPort(), app, streamId)); + // HTTP-FLV 播放地址 + resp.setFlv(String.format("http://%s:%d/%s/%s.live.flv", zlmConfig.getIp(), zlmConfig.getHttpPort(), app, streamId)); + resp.setWsFlv(String.format("ws://%s:%d/%s/%s.live.flv", zlmConfig.getIp(), zlmConfig.getHttpPort(), app, streamId)); + // HLS 播放地址 + resp.setHls(String.format("http://%s:%d/%s/%s/hls.m3u8", zlmConfig.getIp(), zlmConfig.getHttpPort(), app, streamId)); + // MP4 播放地址 + resp.setMp4(String.format("http://%s:%d/%s/%s.live.mp4", zlmConfig.getIp(), zlmConfig.getHttpPort(), app, streamId)); + return resp; + } + + + @Override + public AddStreamProxyResp addStreamProxy(StartStreamProxy startStreamProxy) { + Map commonParams = getCommonParams(); + commonParams.put("vhost", zlmConfig.getVhost()); + commonParams.put("app", startStreamProxy.getApp()); + commonParams.put("stream", startStreamProxy.getStream()); + commonParams.put("url", startStreamProxy.getUrl()); + commonParams.put("rtp_type", startStreamProxy.getRtpType()); + R result = HttpClientUtil.get(getRequestUrl("addStreamProxy"), commonParams, AddStreamProxyResp.class); + if (result != null) { + if (result.getCode() == 0) { + log.info("创建拉流任务成功."); + } + // 此处代表拉流任务已存在 + if (result.getCode() == -1) { + log.info("拉流任务已存在,返回播放地址。"); + } + return setPlayerUrl(startStreamProxy.getApp(), startStreamProxy.getStream(), result.getData()); + } + return null; + } + + @Override + public String delStreamProxy(StartStreamProxy startStreamProxy) { + Map commonParams = getCommonParams(); + commonParams.put("schema", "rtsp"); + commonParams.put("vhost", zlmConfig.getVhost()); + commonParams.put("app", startStreamProxy.getApp()); + commonParams.put("stream", startStreamProxy.getStream()); + commonParams.put("force", 1); + R result = HttpClientUtil.get(getRequestUrl("close_streams"), commonParams, AddStreamProxyResp.class); + if (result != null) { + String s =null; + if (result.getCode() == 0) { + s = "关闭流成功"; + } + // 此处代表拉流任务已存在 + if (result.getCode() == -1) { + s = "关闭流失败"; + } + log.info("{},关闭流数量:{}",s,result.getData()); + return s; + } + return null; + } + + @Override + public Object addFFmpegSource() { + return null; + } + + @Override + public Object delFFmpegSource() { + return null; + } + + @Override + public Object getRtpInfo() { + return null; + } + + @Override + public Object getMp4RecordFile() { + return null; + } + + @Override + public Object startRecord() { + return null; + } + + @Override + public Object stopRecord() { + return null; + } + + @Override + public Object isRecording() { + return null; + } + + @Override + public Object getSnap() { + return null; + } + + @Override + public Object openRtpServer() { + return null; + } + + @Override + public Object closeRtpServer() { + return null; + } + + @Override + public Object listRtpServer() { + return null; + } + + @Override + public Object startSendRtp() { + return null; + } + + @Override + public Object stopSendRtp() { + return null; + } + + @Override + public Object getStatistic() { + return null; + } + + @Override + public Object addStreamPusherProxy() { + return null; + } + + @Override + public Object delStreamPusherProxy() { + return null; + } + + @Override + public Object getVersion() { + return null; + } + + @Override + public Object getMediaPlayerList() { + return null; + } + +} diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/AddStreamProxy.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/AddStreamProxy.java new file mode 100644 index 00000000..b580cf08 --- /dev/null +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/AddStreamProxy.java @@ -0,0 +1,36 @@ +package org.dromara.sis.sdk.zkmedia.model; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +@Data +public class AddStreamProxy { + + @NotBlank + private String videoIp; + + @NotNull + private Integer videoPort; + + @NotBlank + private String factoryNo; + + @NotBlank + private String account; + + @NotBlank + private String pwd; + + @NotNull + private String channelId; + + + private String startTime; + + private String endTime; + + private String stream; + +} diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/AddStreamProxyResp.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/AddStreamProxyResp.java new file mode 100644 index 00000000..051e62a9 --- /dev/null +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/AddStreamProxyResp.java @@ -0,0 +1,23 @@ +package org.dromara.sis.sdk.zkmedia.model; + +import lombok.Data; + +import java.io.Serializable; + +@Data +public class AddStreamProxyResp implements Serializable { + + private String key; + + private String rtsp; + + private String rtmp; + + private String flv; + private String wsFlv; + + private String mp4; + + private String hls; + +} diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/HookParam.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/HookParam.java new file mode 100644 index 00000000..45cacf1b --- /dev/null +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/HookParam.java @@ -0,0 +1,14 @@ +package org.dromara.sis.sdk.zkmedia.model; + +import lombok.Data; + +/** + * zlm hook事件的参数 + * @author lin + */ +@Data +public class HookParam { + + private String mediaServerId; + +} diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/HookResult.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/HookResult.java new file mode 100644 index 00000000..8f77540a --- /dev/null +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/HookResult.java @@ -0,0 +1,28 @@ +package org.dromara.sis.sdk.zkmedia.model; + +import lombok.Data; +import lombok.experimental.Accessors; + +@Data +@Accessors(chain = true) +public class HookResult { + + private int code; + private String msg; + + // 此字段在部分返回结果中用到 + private Boolean close; + + + public HookResult() { + } + + public HookResult(int code, String msg) { + this.code = code; + this.msg = msg; + } + + public static HookResult SUCCESS() { + return new HookResult(0, "success"); + } +} diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/HookResultForOnPublish.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/HookResultForOnPublish.java new file mode 100644 index 00000000..011dc7e4 --- /dev/null +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/HookResultForOnPublish.java @@ -0,0 +1,17 @@ +package org.dromara.sis.sdk.zkmedia.model; + +import lombok.Getter; +import lombok.Setter; + +@Setter +@Getter +public class HookResultForOnPublish extends HookResult { + + private boolean enable_audio; + private boolean enable_mp4; + private int mp4_max_second; + private String mp4_save_path; + private String stream_replace; + private Integer modify_stamp; + +} diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/OnPlayHookParam.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/OnPlayHookParam.java new file mode 100644 index 00000000..0082bed5 --- /dev/null +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/OnPlayHookParam.java @@ -0,0 +1,22 @@ +package org.dromara.sis.sdk.zkmedia.model; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * zlm hook事件中的on_play事件的参数 + * + * @author lin + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class OnPlayHookParam extends HookParam { + private String id; + private String app; + private String stream; + private String ip; + private String params; + private int port; + private String schema; + private String vhost; +} diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/OnPushParam.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/OnPushParam.java new file mode 100644 index 00000000..26081e0e --- /dev/null +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/OnPushParam.java @@ -0,0 +1,29 @@ +package org.dromara.sis.sdk.zkmedia.model; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class OnPushParam extends HookParam{ + + private String app; + + private String id; + + private String ip; + + private String params; + + private Integer port; + + private String schema; + + private String stream; + + private String vhost; + + + + +} diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/OnServerKeepaliveHookParam.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/OnServerKeepaliveHookParam.java new file mode 100644 index 00000000..605ae9e5 --- /dev/null +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/OnServerKeepaliveHookParam.java @@ -0,0 +1,20 @@ +package org.dromara.sis.sdk.zkmedia.model; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * zlm hook事件中的on_play事件的参数 + * + * @author lin + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class OnServerKeepaliveHookParam extends HookParam { + + private Object data; + + private Integer hook_index; + + +} diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/OnStreamChangedHookParam.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/OnStreamChangedHookParam.java new file mode 100644 index 00000000..d2ed4948 --- /dev/null +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/OnStreamChangedHookParam.java @@ -0,0 +1,203 @@ +package org.dromara.sis.sdk.zkmedia.model; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.List; +import java.util.Map; + +/** + * @author lin + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class OnStreamChangedHookParam extends HookParam { + + /** + * 注册/注销 + */ + private boolean regist; + + /** + * 应用名 + */ + private String app; + + /** + * 流id + */ + private String stream; + + /** + * 推流鉴权Id + */ + private String callId; + + /** + * 观看总人数,包括hls/rtsp/rtmp/http-flv/ws-flv + */ + private int totalReaderCount; + + /** + * 协议 包括hls/rtsp/rtmp/http-flv/ws-flv + */ + private String schema; + + + /** + * 产生源类型, + * unknown = 0, + * rtmp_push=1, + * rtsp_push=2, + * rtp_push=3, + * pull=4, + * ffmpeg_pull=5, + * mp4_vod=6, + * device_chn=7 + */ + private int originType; + + /** + * 客户端和服务器网络信息,可能为null类型 + */ + private OriginSock originSock; + + /** + * 产生源类型的字符串描述 + */ + private String originTypeStr; + + /** + * 产生源的url + */ + private String originUrl; + + /** + * 服务器id + */ + private String severId; + + /** + * GMT unix系统时间戳,单位秒 + */ + private Long createStamp; + + /** + * 存活时间,单位秒 + */ + private Long aliveSecond; + + /** + * 数据产生速度,单位byte/s + */ + private Long bytesSpeed; + + /** + * 音视频轨道 + */ + private List tracks; + + /** + * 音视频轨道 + */ + private String vhost; + + /** + * 额外的参数字符串 + */ + private String params; + + /** + * 额外的参数 + */ + private Map paramMap; + + + @Data + public static class MediaTrack { + /** + * 音频通道数 + */ + private int channels; + + /** + * H264 = 0, H265 = 1, AAC = 2, G711A = 3, G711U = 4 + */ + private int codec_id; + + /** + * 编码类型名称 CodecAAC CodecH264 + */ + private String codec_id_name; + + /** + * Video = 0, Audio = 1 + */ + private int codec_type; + + /** + * 轨道是否准备就绪 + */ + private boolean ready; + + /** + * 音频采样位数 + */ + private int sample_bit; + + /** + * 音频采样率 + */ + private int sample_rate; + + /** + * 视频fps + */ + private float fps; + + /** + * 视频高 + */ + private int height; + + /** + * 视频宽 + */ + private int width; + + /** + * 帧数 + */ + private int frames; + + /** + * 关键帧数 + */ + private int key_frames; + + /** + * GOP大小 + */ + private int gop_size; + + /** + * GOP间隔时长(ms) + */ + private int gop_interval_ms; + + /** + * 丢帧率 + */ + private float loss; + } + + @Data + public static class OriginSock { + private String identifier; + private String local_ip; + private int local_port; + private String peer_ip; + private int peer_port; + + } +} diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/OnStreamNoneReaderHookParam.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/OnStreamNoneReaderHookParam.java new file mode 100644 index 00000000..8c1893ee --- /dev/null +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/OnStreamNoneReaderHookParam.java @@ -0,0 +1,15 @@ +package org.dromara.sis.sdk.zkmedia.model; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class OnStreamNoneReaderHookParam extends HookParam{ + + private String schema; + private String app; + private String stream; + private String vhost; + +} diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/OnStreamNotFoundHookParam.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/OnStreamNotFoundHookParam.java new file mode 100644 index 00000000..d6547d29 --- /dev/null +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/OnStreamNotFoundHookParam.java @@ -0,0 +1,21 @@ +package org.dromara.sis.sdk.zkmedia.model; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * zlm hook事件中的on_stream_not_found事件的参数 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class OnStreamNotFoundHookParam extends HookParam { + private String id; + private String app; + private String stream; + private String ip; + private String params; + private int port; + private String schema; + private String vhost; + +} diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/R.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/R.java new file mode 100644 index 00000000..16bcc1d6 --- /dev/null +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/R.java @@ -0,0 +1,12 @@ +package org.dromara.sis.sdk.zkmedia.model; + +import lombok.Data; + +@Data +public class R { + + private Integer code; + + private T data; + +} diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/ServerKeepaliveData.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/ServerKeepaliveData.java new file mode 100644 index 00000000..513420fc --- /dev/null +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/ServerKeepaliveData.java @@ -0,0 +1,25 @@ +package org.dromara.sis.sdk.zkmedia.model; + +import lombok.Data; + +@Data +public class ServerKeepaliveData { + + private Integer Buffer; + private String BufferLikeString; + private Integer BufferList; + private Integer BufferRaw; + private Integer Frame; + private Integer FrameImp; + private Integer MediaSource; + private Integer MultiMediaSourceMuxer; + private Integer RtmpPacket; + private Integer RtpPacket; + private Integer Socket; + private Integer TcpClient; + private Integer TcpServer; + private Integer TcpSession; + private Integer UdpServer; + private Integer UdpSession; + +} diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/StartStreamProxy.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/StartStreamProxy.java new file mode 100644 index 00000000..d25813c7 --- /dev/null +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/StartStreamProxy.java @@ -0,0 +1,18 @@ +package org.dromara.sis.sdk.zkmedia.model; + +import lombok.Data; + +import java.io.Serializable; + +@Data +public class StartStreamProxy implements Serializable { + + private String app = "live"; + + private String stream; + + private String url; + + private Integer rtpType = 1; + +} diff --git a/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/ThreadsLoadDelay.java b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/ThreadsLoadDelay.java new file mode 100644 index 00000000..631334aa --- /dev/null +++ b/ruoyi-modules/Sis/src/main/java/org/dromara/sis/sdk/zkmedia/model/ThreadsLoadDelay.java @@ -0,0 +1,18 @@ +package org.dromara.sis.sdk.zkmedia.model; + +import lombok.Data; + +@Data +public class ThreadsLoadDelay { + + /** + * 该线程延时 + */ + private Integer delay; + + /** + * 该线程负载,0 ~ 100 + */ + private Integer load; + +}