国标28181-支持自动识别网卡监听,可以不再配置SIP.IP
| | |
| | | 设备接入主要是需要在设备上配置28181上级也就是WVP-PRO的信息,只有信息一致的情况才可以注册成功。设备注册成功后打开WVP->国标设备,可以看到新增加的设备;[设备使用](./_content/ability/device_use.md), |
| | | 主要有以下字段需要配置: |
| | | |
| | | - sip->ip |
| | | 本机IP,不要使用127.0.0.1/0.0.0.0, 除非你对项目及其熟悉 |
| | | |
| | | - sip->port |
| | | 28181服务监听的端口 |
| | | |
| | |
| | | 这里依然是参考网上教程,自行安装吧。 |
| | | |
| | | ## 4 编译ZLMediaKit |
| | | 参考ZLMediaKit[WIKI](https://github.com/ZLMediaKit/ZLMediaKit/wiki),截取一下关键步骤: |
| | | 参考ZLMediaKit[WIKI](https://github.com/ZLMediaKit/ZLMediaKit/wiki),如果需要使用语音对讲功能,请参考[zlm启用webrtc编译指南](https://github.com/ZLMediaKit/ZLMediaKit/wiki/zlm%E5%90%AF%E7%94%A8webrtc%E7%BC%96%E8%AF%91%E6%8C%87%E5%8D%97),开启zlm的webrtc功能。截取一下关键步骤: |
| | | ```bash |
| | | # 国内用户推荐从同步镜像网站gitee下载 |
| | | git clone --depth 1 https://gitee.com/xia-chu/ZLMediaKit |
| | |
| | | 基于spring boot的开发方式,配置文件的加载是很灵活的。默认在src/main/resources/application.yml,部分配置项是可选,你不需要全部配置在配置文件中, |
| | | 完全的配置说明可以参看all-application.yml。 |
| | | ### 1.1 默认加载配置文件方式 |
| | | 使用maven打包后的jar包里,已经存在了配置文件,但是每次打开jar包修改配置文件或者修改后再打包都是比较麻烦的,所以大家可通过指定配置文件路径来加载指定位置的配置文件。 |
| | | 使用maven打包后的target里,已经存在了配置文件,默认加载配置文件为application.yml,查看内容发现其中spring.profiles.active配置的内容,将入配置的值为dev,那么具体加载的配置文件就是application-dev.yml,如果配置的值找不到对应的配置文件,修改值为dev。 |
| | | ```shell |
| | | cd wvp-GB28181-pro/target |
| | | java -jar wvp-pro-*.jar --spring.config.location=../src/main/resources/application.yml |
| | | java -jar wvp-pro-*.jar |
| | | ``` |
| | | ### 1.2 迁移配置文件以方便启动 |
| | | 由于配置文件的命令比较长,所以为了启动方便通常我会把配置文件放到jar包的同级目录,类似这样, |
| | | 移除jar包内/BOOT-INF/classes/下所有以application开头的文件,使用解压缩工具打开jar即可,不需要解压出来。 |
| | | ```shell |
| | | cd wvp-GB28181-pro/target |
| | | mv ../src/main/resources/application-dev.yml application.yml |
| | | java -jar wvp-pro-*.jar |
| | | ``` |
| | | 这也是我自己最常用的方式。 |
| | | ## 2 配置WVP-PRO |
| | | wvp支持多种数据库,包括Mysql,Postgresql,金仓等,配置任选一种即可。 |
| | | ### 2.1 数据库配置 |
| | |
| | | 数据库名称以wvp为例 |
| | | ```yaml |
| | | spring: |
| | | datasource: |
| | | type: com.zaxxer.hikari.HikariDataSource |
| | | driver-class-name: com.mysql.cj.jdbc.Driver |
| | | url: jdbc:mysql://127.0.0.1:3306/wvp?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&serverTimezone=PRC&useSSL=false&allowMultiQueries=true&allowPublicKeyRetrieval=true |
| | | username: root |
| | | password: 12345678 |
| | | |
| | | mybatis: |
| | | configuration: |
| | | map-underscore-to-camel-case: true |
| | | dynamic: |
| | | primary: master |
| | | datasource: |
| | | master: |
| | | type: com.zaxxer.hikari.HikariDataSource |
| | | driver-class-name: com.mysql.cj.jdbc.Driver |
| | | url: jdbc:mysql://127.0.0.1:3306/wvp?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&serverTimezone=PRC&useSSL=false&allowMultiQueries=true |
| | | username: root |
| | | password: root123 |
| | | ``` |
| | | #### 2.1.3 Postgresql数据库配置 |
| | | 数据库名称以wvp为例 |
| | | ```yaml |
| | | spring: |
| | | datasource: |
| | | type: com.zaxxer.hikari.HikariDataSource |
| | | driver-class-name: org.postgresql.Driver |
| | | url: jdbc:postgresql://127.0.0.1:3306/wvp?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&serverTimezone=PRC&useSSL=false&allowMultiQueries=true&allowPublicKeyRetrieval=true |
| | | username: root |
| | | password: 12345678 |
| | | dynamic: |
| | | primary: master |
| | | datasource: |
| | | type: com.zaxxer.hikari.HikariDataSource |
| | | driver-class-name: org.postgresql.Driver |
| | | url: jdbc:postgresql://127.0.0.1:3306/wvp?useUnicode=true&characterEncoding=UTF8&rewriteBatchedStatements=true&serverTimezone=PRC&useSSL=false&allowMultiQueries=true&allowPublicKeyRetrieval=true |
| | | username: root |
| | | password: 12345678 |
| | | |
| | | pagehelper: |
| | | helper-dialect: postgresql |
| | |
| | | 数据库名称以wvp为例 |
| | | ```yaml |
| | | spring: |
| | | datasource: |
| | | type: com.zaxxer.hikari.HikariDataSource |
| | | driver-class-name: com.kingbase8.Driver |
| | | url: jdbc:kingbase8://127.0.0.1:3306/wvp?useUnicode=true&characterEncoding=utf8 |
| | | username: root |
| | | password: 12345678 |
| | | dynamic: |
| | | primary: master |
| | | datasource: |
| | | type: com.zaxxer.hikari.HikariDataSource |
| | | driver-class-name: com.kingbase8.Driver |
| | | url: jdbc:kingbase8://127.0.0.1:3306/wvp?useUnicode=true&characterEncoding=utf8 |
| | | username: root |
| | | password: 12345678 |
| | | |
| | | pagehelper: |
| | | helper-dialect: postgresql |
| | |
| | | ```yaml |
| | | # 作为28181服务器的配置 |
| | | sip: |
| | | # [必须修改] 本机的IP |
| | | ip: 192.168.1.3 |
| | | # [可选] 28181服务监听的端口 |
| | | port: 5060 |
| | | # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) |
| | |
| | | ```yaml |
| | | #zlm 默认服务器配置 |
| | | media: |
| | | # ZLMediaKit的服务ID,必须配置 |
| | | id: FQ3TF8yT83wh5Wvz |
| | | # [必须修改] zlm服务器的内网IP,sdp-ip与stream-ip使用默认值的情况下,这里不要使用127.0.0.1/0.0.0.0 |
| | | ip: 192.168.1.3 |
| | | # [必须修改] zlm服务器的http.port |
| | | http-port: 6080 |
| | | # [可选] zlm服务器的hook.admin_params=secret |
| | | secret: 035c73f7-bb6b-4889-a715-d9eb2d1925cc |
| | | # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 |
| | | rtp: |
| | | # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 |
| | | enable: true |
| | | # [可选] 在此范围内选择端口用于媒体流传输, |
| | | port-range: 30000,30500 # 端口范围 |
| | | # [可选] 国标级联在此范围内选择端口发送媒体流, |
| | | send-port-range: 30000,30500 # 端口范围 |
| | | # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用 |
| | | record-assist-port: 18081 |
| | | id: zlmediakit-local |
| | | # [必须修改] zlm服务器的内网IP |
| | | ip: 172.19.128.50 |
| | | # [可选] 有公网IP就配置公网IP, 不可用域名 |
| | | wan_ip: |
| | | # [必须修改] zlm服务器的http.port |
| | | http-port: 9092 |
| | | # [可选] zlm服务器访问WVP所使用的IP, 默认使用127.0.0.1,zlm和wvp没有部署在同一台服务器时必须配置 |
| | | hook-ip: 172.19.128.50 |
| | | # [必选选] zlm服务器的hook.admin_params=secret |
| | | secret: TWSYFgYJOQWB4ftgeYut8DW4wbs7pQnj |
| | | # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 |
| | | rtp: |
| | | # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 |
| | | enable: true |
| | | # [可选] 在此范围内选择端口用于媒体流传输, 必须提前在zlm上配置该属性,不然自动配置此属性可能不成功 |
| | | port-range: 30000,35000 # 端口范围 |
| | | # [可选] 国标级联在此范围内选择端口发送媒体流, |
| | | send-port-range: 40000,40300 # 端口范围 |
| | | ``` |
| | | ### 2.4 个性化定制信息配置 |
| | | ```yaml |
| | | # [根据业务需求配置] |
| | | user-settings: |
| | | # [可选] 服务ID,不写则为000000 |
| | | server-id: |
| | | # [可选] 自动点播, 使用固定流地址进行播放时,如果未点播则自动进行点播, 需要rtp.enable=true |
| | | auto-apply-play: false |
| | | # [可选] 部分设备需要扩展SDP,需要打开此设置 |
| | | senior-sdp: false |
| | | # 保存移动位置历史轨迹:true:保留历史数据,false:仅保留最后的位置(默认) |
| | | save-position-history: false |
| | | # 点播等待超时时间,单位:毫秒 |
| | | play-timeout: 3000 |
| | | # 等待音视频编码信息再返回, true: 可以根据编码选择合适的播放器,false: 可以更快点播 |
| | | wait-track: false |
| | | # 是否开启接口鉴权 |
| | | interface-authentication: true |
| | | # 自动配置redis 可以过期事件 |
| | | redis-config: true |
| | | # 接口鉴权例外的接口, 即不进行接口鉴权的接口,尽量详细书写,尽量不用/**,至少两级目录 |
| | | interface-authentication-excludes: |
| | | - /api/v1/** |
| | | # 推流直播是否录制 |
| | | record-push-live: true |
| | | # 国标是否录制 |
| | | record-sip: true |
| | | # 是否将日志存储进数据库 |
| | | logInDatabase: true |
| | | # 第三方匹配,用于从stream钟获取有效信息 |
| | | thirdPartyGBIdReg: [\s\S]* |
| | | # 点播/录像回放 等待超时时间,单位:毫秒 |
| | | play-timeout: 180000 |
| | | # [可选] 自动点播, 使用固定流地址进行播放时,如果未点播则自动进行点播, 需要rtp.enable=true |
| | | auto-apply-play: true |
| | | # 推流直播是否录制 |
| | | record-push-live: true |
| | | # 国标是否录制 |
| | | record-sip: true |
| | | # 国标点播 按需拉流, true:有人观看拉流,无人观看释放, false:拉起后不自动释放 |
| | | stream-on-demand: true |
| | | ``` |
| | | |
| | | 更多完整的配置信息参考all-application.yml文件,需要那个配置项,复制到正在使用的配置文件中对应的文件即可。 |
| | | |
| | | 如果配置信息无误,你可以启动zlm,再启动wvp来测试了,启动成功的话,你可以在wvp的日志下看到zlm已连接的提示。 |
| | | 接下来[部署到服务器](./_content/introduction/deployment.md), 如果你只是本地运行直接在本地运行即可。 |
| | |
| | | |
| | | 3. 测试环境部署建议所有服务部署在一台主机,关闭防火墙,减少因网络出现问题的可能; |
| | | 4. 生产环境按需开放端口,但是建议修改默认端口,尤其是5060端口,易受到攻击; |
| | | 5. zlm使用docker部署的情况,要求端口映射一致,比如映射5060,应将外部端口也映射为5060端口; |
| | | 5. zlm使用docker部署的情况,请使用host模式,或者端口映射一致,比如映射5060,应将外部端口也映射为5060端口; |
| | | 6. zlm与wvp会保持高频率的通信,所以不要去将wvp与zlm分属在两个网络,比如wvp在内网,zlm却在公网的情况。 |
| | | 7. 启动服务,以linux为例 |
| | | **启动WVP-PRO** |
| | |
| | | ### 前后端分离部署 |
| | | 前后端部署目前在最新的版本已经支持,请使用3月15日之后的版本部署 |
| | | 前端编译后的文件在`src/main/resources/static`中,将此目录下的文件部署。 |
| | | 前后端分离部署最大的问题是跨域的解决,之前版本使用cookie完成登录流程,而cookie是不可以在复杂跨域中使用的。所以当前版本使用JWT生成的TOKEN作为认证凭据, |
| | | 部署前端后需要在wvp中配置前端访问的地址以完成跨域流程。 |
| | | WVP默认开启全部接口支持跨域。部署前端文件到WEB容器,并将访问的地址设置为WVP的地址即可。 |
| | | **配置前端服务器** |
| | | 1. 假如你的服务有公网域名为xxx.com,公网IP为11.11.11.11, 那么你可以在wvp中这样配置: |
| | | ```yaml |
| | | user-settings: |
| | | # 跨域配置,配置你访问前端页面的地址即可, 可以配置多个 |
| | | allowed-origins: |
| | | - http://xxx.com:8008 |
| | | - http://11.11.11.11:8008 |
| | | ``` |
| | | 配置不是必须的,你使用哪个ip/域名访问就配置哪个即可。修改配置后重启wvp以使配置生效。 |
| | | 2. 在`src/main/resources/static/static/js/config.js`下配置服务器的地址,也就是wvp服务的地址 |
| | | 1. 在`src/main/resources/static/static/js/config.js`下配置服务器的地址,也就是wvp服务的地址 |
| | | ```javascript |
| | | window.baseUrl = "http://xxx.com:18080" |
| | | ``` |
| | |
| | | <!-- 侧边栏 --> |
| | | |
| | | * **编译与部署** |
| | | * [测试](_content/introduction/test.md) |
| | | * [编译](_content/introduction/compile.md) |
| | | * [配置](_content/introduction/config.md) |
| | | * [部署](_content/introduction/deployment.md) |
| | |
| | | @Value("${media.ip}") |
| | | private String ip; |
| | | |
| | | @Value("${media.hook-ip:}") |
| | | private String hookIp; |
| | | @Value("${media.wan_ip}") |
| | | private String wanIp; |
| | | |
| | | @Value("${sip.ip}") |
| | | private String sipIp; |
| | | @Value("${media.hook-ip:127.0.0.1}") |
| | | private String hookIp; |
| | | |
| | | @Value("${sip.domain}") |
| | | private String sipDomain; |
| | | |
| | | @Value("${media.sdp-ip:${media.ip}}") |
| | | @Value("${media.sdp-ip:${media.wan_ip}}") |
| | | private String sdpIp; |
| | | |
| | | @Value("${media.stream-ip:${media.ip}}") |
| | | @Value("${media.stream-ip:${media.wan_ip}}") |
| | | private String streamIp; |
| | | |
| | | @Value("${media.http-port:0}") |
| | |
| | | } |
| | | |
| | | public String getHookIp() { |
| | | if (ObjectUtils.isEmpty(hookIp)){ |
| | | return sipIp; |
| | | }else { |
| | | return hookIp; |
| | | } |
| | | |
| | | } |
| | | |
| | | public String getSipIp() { |
| | | if (sipIp == null) { |
| | | return this.ip; |
| | | }else { |
| | | return sipIp; |
| | | } |
| | | return hookIp; |
| | | } |
| | | |
| | | public int getHttpPort() { |
| | |
| | | } |
| | | |
| | | public String getShowIp() { |
| | | if (this.showIp == null) { |
| | | return this.ip; |
| | | } |
| | | return showIp; |
| | | } |
| | | |
| | |
| | | |
| | | private boolean registerKeepIntDialog = false; |
| | | |
| | | private int gbDeviceOnline = 0; |
| | | private int gbDeviceOnline = 1; |
| | | |
| | | public Boolean getSavePositionHistory() { |
| | | return savePositionHistory; |
| | |
| | | @Scheduled(fixedRate = 2 * 1000) //每3秒执行一次 |
| | | public void execute(){ |
| | | JSONObject jsonObject = new JSONObject(); |
| | | jsonObject.put("ip", sipConfig.getIp()); |
| | | jsonObject.put("ip", sipConfig.getShowIp()); |
| | | jsonObject.put("port", serverPort); |
| | | redisCatchStorage.updateWVPInfo(jsonObject, 3); |
| | | } |
| | |
| | | import org.springframework.util.ObjectUtils; |
| | | |
| | | import javax.sip.*; |
| | | import java.net.Inet4Address; |
| | | import java.net.InetAddress; |
| | | import java.net.NetworkInterface; |
| | | import java.util.*; |
| | | import java.util.concurrent.ConcurrentHashMap; |
| | | |
| | |
| | | @Override |
| | | public void run(String... args) { |
| | | List<String> monitorIps = new ArrayList<>(); |
| | | // 使用逗号分割多个ip |
| | | String separator = ","; |
| | | if (sipConfig.getIp().indexOf(separator) > 0) { |
| | | String[] split = sipConfig.getIp().split(separator); |
| | | monitorIps.addAll(Arrays.asList(split)); |
| | | if (ObjectUtils.isEmpty(sipConfig.getIp())) { |
| | | try { |
| | | // 获得本机的所有网络接口 |
| | | Enumeration<NetworkInterface> nifs = NetworkInterface.getNetworkInterfaces(); |
| | | while (nifs.hasMoreElements()) { |
| | | NetworkInterface nif = nifs.nextElement(); |
| | | // 获得与该网络接口绑定的 IP 地址,一般只有一个 |
| | | Enumeration<InetAddress> addresses = nif.getInetAddresses(); |
| | | while (addresses.hasMoreElements()) { |
| | | InetAddress addr = addresses.nextElement(); |
| | | if (addr instanceof Inet4Address) { |
| | | if (addr.getHostAddress().equals("127.0.0.1")){ |
| | | continue; |
| | | } |
| | | if (nif.getName().startsWith("docker")) { |
| | | continue; |
| | | } |
| | | logger.error("[自动配置SIP监听网卡] 网卡接口地址: {}", addr.getHostAddress());// 只关心 IPv4 地址 |
| | | monitorIps.add(addr.getHostAddress()); |
| | | } |
| | | } |
| | | } |
| | | }catch (Exception e) { |
| | | logger.error("[读取网卡信息失败]", e); |
| | | } |
| | | if (monitorIps.isEmpty()) { |
| | | logger.error("[自动配置SIP监听网卡信息失败], 请手动配置SIP.IP后重新启动"); |
| | | System.exit(1); |
| | | } |
| | | }else { |
| | | monitorIps.add(sipConfig.getIp()); |
| | | // 使用逗号分割多个ip |
| | | String separator = ","; |
| | | if (sipConfig.getIp().indexOf(separator) > 0) { |
| | | String[] split = sipConfig.getIp().split(separator); |
| | | monitorIps.addAll(Arrays.asList(split)); |
| | | }else { |
| | | monitorIps.add(sipConfig.getIp()); |
| | | } |
| | | } |
| | | |
| | | sipConfig.setShowIp(String.join(",", monitorIps)); |
| | | SipFactory.getInstance().setPathName("gov.nist"); |
| | | if (monitorIps.size() > 0) { |
| | | for (String monitorIp : monitorIps) { |
| | |
| | |
|
| | | return request;
|
| | | }
|
| | | public Request createBroadcastMessageRequest(Device device, String channelId, String content, String viaTag, String fromTag, String toTag, CallIdHeader callIdHeader) throws ParseException, InvalidArgumentException, PeerUnavailableException {
|
| | | Request request = null;
|
| | | // sipuri
|
| | | SipURI requestURI = SipFactory.getInstance().createAddressFactory().createSipURI(channelId, device.getHostAddress());
|
| | | // via
|
| | | ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
|
| | | ViaHeader viaHeader = SipFactory.getInstance().createHeaderFactory().createViaHeader(sipConfig.getIp(), sipConfig.getPort(), device.getTransport(), viaTag);
|
| | | viaHeader.setRPort();
|
| | | viaHeaders.add(viaHeader);
|
| | | // from
|
| | | SipURI fromSipURI = SipFactory.getInstance().createAddressFactory().createSipURI(sipConfig.getId(), sipConfig.getDomain());
|
| | | Address fromAddress = SipFactory.getInstance().createAddressFactory().createAddress(fromSipURI);
|
| | | FromHeader fromHeader = SipFactory.getInstance().createHeaderFactory().createFromHeader(fromAddress, fromTag);
|
| | | // to
|
| | | SipURI toSipURI = SipFactory.getInstance().createAddressFactory().createSipURI(channelId, device.getHostAddress());
|
| | | Address toAddress = SipFactory.getInstance().createAddressFactory().createAddress(toSipURI);
|
| | | ToHeader toHeader = SipFactory.getInstance().createHeaderFactory().createToHeader(toAddress, toTag);
|
| | |
|
| | | // Forwards
|
| | | MaxForwardsHeader maxForwards = SipFactory.getInstance().createHeaderFactory().createMaxForwardsHeader(70);
|
| | | // ceq
|
| | | CSeqHeader cSeqHeader = SipFactory.getInstance().createHeaderFactory().createCSeqHeader(redisCatchStorage.getCSEQ(), Request.MESSAGE);
|
| | |
|
| | | ContentTypeHeader contentTypeHeader = SipFactory.getInstance().createHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml");
|
| | |
|
| | | request = SipFactory.getInstance().createMessageFactory().createRequest(requestURI, Request.MESSAGE, callIdHeader, cSeqHeader, fromHeader,
|
| | | toHeader, viaHeaders, maxForwards, contentTypeHeader, content);
|
| | |
|
| | | request.addHeader(SipUtils.createUserAgentHeader(gitUtil));
|
| | |
|
| | | return request;
|
| | | }
|
| | | }
|
| | |
| | | package com.genersoft.iot.vmp.media; |
| | | |
| | | import com.genersoft.iot.vmp.conf.MediaConfig; |
| | | import com.genersoft.iot.vmp.media.bean.MediaServer; |
| | | import com.genersoft.iot.vmp.media.event.mediaServer.MediaServerChangeEvent; |
| | | import com.genersoft.iot.vmp.media.service.IMediaServerService; |
| | | import com.genersoft.iot.vmp.media.bean.MediaServer; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | |
| | | private String ip; |
| | | |
| | | @Schema(description = "hook使用的IP(zlm访问WVP使用的IP)") |
| | | private String hookIp; |
| | | private String hookIp = "127.0.0.1"; |
| | | |
| | | @Schema(description = "SDP IP") |
| | | private String sdpIp; |
| | |
| | | }
|
| | | }
|
| | |
|
| | |
|
| | | /**
|
| | | * rtsp/rtmp流注册或注销时触发此事件;此事件对回复不敏感。
|
| | | */
|
| | | // @ResponseBody
|
| | | // @PostMapping(value = "/on_stream_changed", produces = "application/json;charset=UTF-8")
|
| | | // public HookResult onStreamChanged(@RequestBody JSONObject param) {
|
| | | // System.out.println(11);
|
| | | // return HookResult.SUCCESS();
|
| | | // }
|
| | | /**
|
| | | * rtsp/rtmp流注册或注销时触发此事件;此事件对回复不敏感。
|
| | | */
|
| | |
| | | import com.genersoft.iot.vmp.conf.exception.ControllerException; |
| | | import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem; |
| | | import com.genersoft.iot.vmp.media.bean.MediaInfo; |
| | | import com.genersoft.iot.vmp.media.service.IMediaNodeServerService; |
| | | import com.genersoft.iot.vmp.media.bean.MediaServer; |
| | | import com.genersoft.iot.vmp.media.service.IMediaNodeServerService; |
| | | import com.genersoft.iot.vmp.media.zlm.dto.ZLMServerConfig; |
| | | import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; |
| | | import com.genersoft.iot.vmp.vmanager.bean.WVPResult; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.util.ObjectUtils; |
| | | |
| | |
| | | |
| | | @Autowired |
| | | private ZLMServerFactory zlmServerFactory; |
| | | |
| | | @Value("${sip.ip}") |
| | | private String sipIp; |
| | | |
| | | @Override |
| | | public int createRTPServer(MediaServer mediaServer, String streamId, long ssrc, Integer port, Boolean onlyAuto, Boolean disableAudio, Boolean reUsePort, Integer tcpMode) { |
| | |
| | | mediaServer.setRtpProxyPort(zlmServerConfig.getRtpProxyPort()); |
| | | mediaServer.setStreamIp(ip); |
| | | |
| | | mediaServer.setHookIp(sipIp.split(",")[0]); |
| | | mediaServer.setHookIp("127.0.0.1"); |
| | | mediaServer.setSdpIp(ip); |
| | | mediaServer.setType("zlm"); |
| | | return mediaServer; |
| | |
| | | if (callback == null) { |
| | | try { |
| | | Response response = client.newCall(request).execute(); |
| | | |
| | | if (response.isSuccessful()) { |
| | | ResponseBody responseBody = response.body(); |
| | | if (responseBody != null) { |
| | |
| | | @GetMapping("/server_config") |
| | | public JSONObject serverConfig() { |
| | | JSONObject result = new JSONObject(); |
| | | result.put("deviceIp", sipConfig.getIp()); |
| | | result.put("deviceIp", sipConfig.getShowIp()); |
| | | result.put("devicePort", sipConfig.getPort()); |
| | | result.put("username", sipConfig.getId()); |
| | | result.put("password", sipConfig.getPassword()); |
| | |
| | | result.put("Server",""); |
| | | result.put("SIPSerial", sipConfig.getId()); |
| | | result.put("SIPRealm", sipConfig.getDomain()); |
| | | result.put("SIPHost", sipConfig.getIp()); |
| | | result.put("SIPHost", sipConfig.getShowIp()); |
| | | result.put("SIPPort", sipConfig.getPort()); |
| | | result.put("ChannelCount","1000"); |
| | | result.put("VersionType",""); |
| | |
| | | id: |
| | | # [必须修改] zlm服务器的内网IP |
| | | ip: 192.168.0.100 |
| | | # [可选] 有公网IP就配置公网IP, 不可用域名 |
| | | wan_ip: |
| | | # [可选] 返回流地址时的ip,置空使用 media.ip |
| | | stream-ip: |
| | | # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip |
| | | sdp-ip: |
| | | # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip |
| | | hook-ip: |
| | | # [可选] zlm服务器访问WVP所使用的IP, 默认使用127.0.0.1,zlm和wvp没有部署在同一台服务器时必须配置 |
| | | hook-ip: 172.19.128.50 |
| | | # [必须修改] zlm服务器的http.port |
| | | http-port: 80 |
| | | # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 |
| | |
| | | - http://192.168.1.3:8008 |
| | | # 国标设备离线后的上线策略, |
| | | # 0: 国标标准实现,设备离线后不回复心跳,直到设备重新注册上线, |
| | | # 1: 对于离线设备,收到心跳就把设备设置为上线,并更新注册时间为上次这次心跳的时间。防止过期时间判断异常 |
| | | # 1(默认): 对于离线设备,收到心跳就把设备设置为上线,并更新注册时间为上次这次心跳的时间。防止过期时间判断异常 |
| | | gb-device-online: 0 |
| | | |
| | | # 关闭在线文档(生产环境建议关闭) |
| | |
| | | |
| | | # 作为28181服务器的配置 |
| | | sip: |
| | | # [必须修改] 本机的IP,对应你的网卡,监听什么ip就是使用什么网卡, |
| | | # 如果要监听多张网卡,可以使用逗号分隔多个IP, 例如: 192.168.1.4,10.0.0.4 |
| | | # 如果不明白,就使用0.0.0.0,大部分情况都是可以的 |
| | | # 请不要使用127.0.0.1,任何包括localhost在内的域名都是不可以的。 |
| | | ip: 172.19.128.50 |
| | | # [可选] 28181服务监听的端口 |
| | | port: 8116 |
| | | # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007) |
| | |
| | | id: zlmediakit-local |
| | | # [必须修改] zlm服务器的内网IP |
| | | ip: 172.19.128.50 |
| | | # [可选] 有公网IP就配置公网IP, 不可用域名 |
| | | wan_ip: |
| | | # [必须修改] zlm服务器的http.port |
| | | http-port: 9092 |
| | | # [可选] 返回流地址时的ip,置空使用 media.ip |
| | | stream-ip: 172.19.128.50 |
| | | # [可选] wvp在国标信令中使用的ip,此ip为摄像机可以访问到的ip, 置空使用 media.ip |
| | | sdp-ip: 172.19.128.50 |
| | | # [可选] zlm服务器的hook所使用的IP, 默认使用sip.ip |
| | | # [可选] zlm服务器访问WVP所使用的IP, 默认使用127.0.0.1,zlm和wvp没有部署在同一台服务器时必须配置 |
| | | hook-ip: 172.19.128.50 |
| | | # [可选] zlm服务器的http.sslport, 置空使用zlm配置文件配置 |
| | | http-ssl-port: 1443 |
| | | # [可选] zlm服务器的hook.admin_params=secret |
| | | secret: 10000 |
| | | # [必选选] zlm服务器的hook.admin_params=secret |
| | | secret: TWSYFgYJOQWB4ftgeYut8DW4wbs7pQnj |
| | | # 启用多端口模式, 多端口模式使用端口区分每路流,兼容性更好。 单端口使用流的ssrc区分, 点播超时建议使用多端口测试 |
| | | rtp: |
| | | # [可选] 是否启用多端口模式, 开启后会在portRange范围内选择端口用于媒体流传输 |
| | |
| | | port-range: 50000,50300 # 端口范围 |
| | | # [可选] 国标级联在此范围内选择端口发送媒体流, |
| | | send-port-range: 50000,50300 # 端口范围 |
| | | # 录像辅助服务, 部署此服务可以实现zlm录像的管理与下载, 0 表示不使用 |
| | | record-assist-port: 18081 |
| | | # [根据业务需求配置] |
| | | user-settings: |
| | | # 点播/录像回放 等待超时时间,单位:毫秒 |
| | | play-timeout: 180000 |
| | | # [可选] 自动点播, 使用固定流地址进行播放时,如果未点播则自动进行点播, 需要rtp.enable=true |
| | | auto-apply-play: true |
| | | # 设备/通道状态变化时发送消息 |
| | | device-status-notify: true |
| | | # 推流直播是否录制 |
| | | record-push-live: true |
| | | # 国标是否录制 |
| | | record-sip: true |
| | | # 国标点播 按需拉流, true:有人观看拉流,无人观看释放, false:拉起后不自动释放 |
| | | stream-on-demand: true |
| | | |