|
@@ -0,0 +1,121 @@
|
|
|
|
|
+package com.sckw.robot.service;
|
|
|
|
|
+
|
|
|
|
|
+import com.aizuda.zlm4j.core.ZLMApi;
|
|
|
|
|
+import com.aizuda.zlm4j.structure.MK_EVENTS;
|
|
|
|
|
+import com.aizuda.zlm4j.structure.MK_INI;
|
|
|
|
|
+import com.sun.jna.Native;
|
|
|
|
|
+import jakarta.annotation.PostConstruct;
|
|
|
|
|
+import jakarta.annotation.PreDestroy;
|
|
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * @author xucaiqin
|
|
|
|
|
+ * @date 2025-07-09 13:01:48
|
|
|
|
|
+ */
|
|
|
|
|
+@Slf4j
|
|
|
|
|
+@Component
|
|
|
|
|
+public class StreamService {
|
|
|
|
|
+ //动态链接库放在/resource/win32-x86-64&/resource/linux-x86-64下JNA会自动查找目录
|
|
|
|
|
+ public static ZLMApi ZLM_API = Native.load("mk_api", ZLMApi.class);
|
|
|
|
|
+
|
|
|
|
|
+ //Windows环境测试
|
|
|
|
|
+ //public static ZLMApi ZLM_API = Native.load("E:\\ZLMediaKit\\release\\windows\\Debug\\mk_api.dll", ZLMApi.class);
|
|
|
|
|
+ //Linux环境测试
|
|
|
|
|
+ //public static ZLMApi ZLM_API = Native.load("/opt/media/libmk_api.so", ZLMApi.class);
|
|
|
|
|
+ public static boolean isLinux() {
|
|
|
|
|
+ String osName = System.getProperty("os.name").toLowerCase();
|
|
|
|
|
+ return osName.contains("linux");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @PostConstruct
|
|
|
|
|
+ public void start() {
|
|
|
|
|
+ //初始化sdk配置
|
|
|
|
|
+ ZLM_API.mk_env_init2(1, 1, 1, null, 0, 0, null, 0, null, null);
|
|
|
|
|
+ //初始化环境配置 SDK参数配置详见ZLM4J参数配置
|
|
|
|
|
+ MK_INI mkIni = ZLM_API.mk_ini_default();
|
|
|
|
|
+ //配置参数 全部配置参数及说明见(resources/conf.ini)
|
|
|
|
|
+ ZLM_API.mk_ini_set_option(mkIni, "general.mediaServerId", "JMediaServer");
|
|
|
|
|
+ ZLM_API.mk_ini_set_option(mkIni, "http.notFound", "<h1 style=\"text-align:center;\">Media Server</h1>");
|
|
|
|
|
+ ZLM_API.mk_ini_set_option_int(mkIni, "protocol.auto_close", 0);
|
|
|
|
|
+ ZLM_API.mk_ini_set_option_int(mkIni, "general.streamNoneReaderDelayMS", 30000);
|
|
|
|
|
+ ZLM_API.mk_ini_set_option_int(mkIni, "general.maxStreamWaitMS", 30000);
|
|
|
|
|
+ ZLM_API.mk_ini_set_option_int(mkIni, "protocol.enable_ts", 1);
|
|
|
|
|
+ ZLM_API.mk_ini_set_option_int(mkIni, "protocol.enable_hls", 1);
|
|
|
|
|
+ ZLM_API.mk_ini_set_option_int(mkIni, "protocol.enable_fmp4", 1);
|
|
|
|
|
+ ZLM_API.mk_ini_set_option_int(mkIni, "protocol.enable_rtsp", 1);
|
|
|
|
|
+ ZLM_API.mk_ini_set_option_int(mkIni, "protocol.enable_rtmp", 1);
|
|
|
|
|
+ ZLM_API.mk_ini_set_option_int(mkIni, "protocol.enable_mp4", 1);
|
|
|
|
|
+ ZLM_API.mk_ini_set_option_int(mkIni, "protocol.enable_hls_fmp4", 1);
|
|
|
|
|
+ ZLM_API.mk_ini_set_option_int(mkIni, "protocol.enable_audio", 1);
|
|
|
|
|
+ ZLM_API.mk_ini_set_option_int(mkIni, "protocol.mp4_as_player", 1);
|
|
|
|
|
+ ZLM_API.mk_ini_set_option_int(mkIni, "protocol.mp4_max_second", 3600);
|
|
|
|
|
+ if (isLinux()) {
|
|
|
|
|
+ ZLM_API.mk_ini_set_option(mkIni, "http.rootPath", "/data/project/www");
|
|
|
|
|
+ ZLM_API.mk_ini_set_option(mkIni, "protocol.mp4_save_path", "/data/project/www");
|
|
|
|
|
+ ZLM_API.mk_ini_set_option(mkIni, "protocol.hls_save_path", "/data/project/www");
|
|
|
|
|
+
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ZLM_API.mk_ini_set_option(mkIni, "http.rootPath", "D:/www");
|
|
|
|
|
+ ZLM_API.mk_ini_set_option(mkIni, "protocol.mp4_save_path", "D:/www");
|
|
|
|
|
+ ZLM_API.mk_ini_set_option(mkIni, "protocol.hls_save_path", "D:/www");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ ZLM_API.mk_ini_set_option_int(mkIni, "protocol.hls_demand", 0);
|
|
|
|
|
+ ZLM_API.mk_ini_set_option_int(mkIni, "protocol.rtsp_demand", 0);
|
|
|
|
|
+ ZLM_API.mk_ini_set_option_int(mkIni, "protocol.rtmp_demand", 0);
|
|
|
|
|
+ ZLM_API.mk_ini_set_option_int(mkIni, "protocol.ts_demand", 0);
|
|
|
|
|
+ ZLM_API.mk_ini_set_option_int(mkIni, "protocol.fmp4_demand", 0);
|
|
|
|
|
+ //全局回调 全部回调见MK_EVENTS内所有的回调属性,如果配置了推流回调、播放回调请务必执行invoker_do,否则无法推流、回放
|
|
|
|
|
+ MK_EVENTS mkEvents = new MK_EVENTS();
|
|
|
|
|
+ //流状态改变回调
|
|
|
|
|
+ mkEvents.on_mk_media_changed = (regist, sender) -> {
|
|
|
|
|
+ log.info("app:" + ZLM_API.mk_media_source_get_app(sender));
|
|
|
|
|
+ log.info("stream:" + ZLM_API.mk_media_source_get_stream(sender));
|
|
|
|
|
+ log.info("schema:" + ZLM_API.mk_media_source_get_schema(sender));
|
|
|
|
|
+ log.info("这里是流改变回调通知:" + regist);
|
|
|
|
|
+ };
|
|
|
|
|
+ //无人观看回调
|
|
|
|
|
+ mkEvents.on_mk_media_no_reader = sender -> {
|
|
|
|
|
+ log.info("这里是无人观看回调通知");
|
|
|
|
|
+ ZLM_API.mk_media_source_close(sender, 1);
|
|
|
|
|
+ };
|
|
|
|
|
+ //推流回调 可控制鉴权、录制、转协议控制等
|
|
|
|
|
+ mkEvents.on_mk_media_publish = (url_info, invoker, sender) -> {
|
|
|
|
|
+ //这里拿到访问路径后(例如rtmp://xxxx/xxx/xxx?token=xxxx其中?后面就是拿到的参数)的参数
|
|
|
|
|
+ // err_msg返回 空字符串表示鉴权成功 否则鉴权失败提示
|
|
|
|
|
+ //String param = ZLM_API.mk_media_info_get_params(url_info);
|
|
|
|
|
+ MK_INI option = ZLM_API.mk_ini_create();
|
|
|
|
|
+ ZLM_API.mk_ini_set_option_int(option, "enable_mp4", 1);
|
|
|
|
|
+ ZLM_API.mk_ini_set_option_int(option, "enable_audio", 1);
|
|
|
|
|
+ ZLM_API.mk_ini_set_option_int(option, "enable_fmp4", 1);
|
|
|
|
|
+ ZLM_API.mk_ini_set_option_int(option, "enable_ts", 1);
|
|
|
|
|
+ ZLM_API.mk_ini_set_option_int(option, "enable_hls", 1);
|
|
|
|
|
+ ZLM_API.mk_ini_set_option_int(option, "enable_rtsp", 1);
|
|
|
|
|
+ ZLM_API.mk_ini_set_option_int(option, "enable_rtmp", 1);
|
|
|
|
|
+ ZLM_API.mk_ini_set_option_int(option, "auto_close", 0);
|
|
|
|
|
+ //流名称替换
|
|
|
|
|
+ //ZLM_API.mk_ini_set_option(option, "stream_replace", "test1");
|
|
|
|
|
+ ZLM_API.mk_publish_auth_invoker_do2(invoker, "", option);
|
|
|
|
|
+ ZLM_API.mk_ini_release(option);
|
|
|
|
|
+ //ZLM_API.mk_publish_auth_invoker_do(invoker, "", 0, 0);
|
|
|
|
|
+ };
|
|
|
|
|
+ //添加全局回调
|
|
|
|
|
+ ZLM_API.mk_events_listen(mkEvents);
|
|
|
|
|
+ //创建http服务器 0:失败,非0:端口号
|
|
|
|
|
+ short http_server_port = ZLM_API.mk_http_server_start((short) 7788, 0);
|
|
|
|
|
+ //创建rtsp服务器 0:失败,非0:端口号
|
|
|
|
|
+ short rtsp_server_port = ZLM_API.mk_rtsp_server_start((short) 554, 0);
|
|
|
|
|
+ //创建rtmp服务器 0:失败,非0:端口号
|
|
|
|
|
+ short rtmp_server_port = ZLM_API.mk_rtmp_server_start((short) 1935, 0);
|
|
|
|
|
+ //创建RTC服务器 0:失败,非0:端口号
|
|
|
|
|
+ short rtc_server_port = ZLM_API.mk_rtc_server_start((short) 8000);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @PreDestroy
|
|
|
|
|
+ public void stop() {
|
|
|
|
|
+ log.info("ZLMediaKit 服务关闭中...");
|
|
|
|
|
+ ZLM_API.mk_stop_all_server();
|
|
|
|
|
+ log.info("ZLMediaKit 服务已关闭");
|
|
|
|
|
+ }
|
|
|
|
|
+}
|