一、整合依赖
该版本starter是自己实现的,功能只实现了部分,后续开源,需要的可以联系我
<dependency>
<groupId>org.nkk</groupId>
<artifactId>sip-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
二、配置sip服务并启用zlm流媒体
sip:
server:
ip: 0.0.0.0
port: 5060
id: 34020000002000000001
domain: 3402000000
password: 12345678
subscribe:
catalog: true
alarm: false
location: false
media:
ip: 172.8.84.25
port: 8880
media-id: bOAReJKF1LuPryvB
secret: MJs3UhLB41DGaLICUBeV6WoPBslHYMQw
三、启动项目
启动即可等待设备注册上线
2024-07-25 17:59:14.518 INFO 17318 --- [ main] org.nkk.sip.SipAutoConfiguration : 「SIP」 tcp://0.0.0.0:15060 启动成功
2024-07-25 17:59:14.526 INFO 17318 --- [ main] org.nkk.sip.SipAutoConfiguration : 「SIP」 upd://0.0.0.0:15060 启动成功
2024-07-25 17:59:14.591 INFO 17318 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 18080 (http) with context path ''
2024-07-25 17:59:14.606 INFO 17318 --- [ main] org.nkk.sip.server.TestMain : Started TestMain in 2.982 seconds (JVM running for 3.471)
2024-07-25 17:59:16.988 INFO 17318 --- [io-18080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2024-07-25 17:59:16.988 INFO 17318 --- [io-18080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2024-07-25 17:59:16.989 INFO 17318 --- [io-18080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms
2024-07-25 17:59:17.283 INFO 17318 --- [ Thread-13] org.nkk.sip.server.config.SipServer : 设备心跳:34020000001110000882
2024-07-25 17:59:19.257 INFO 17318 --- [ Thread-18] org.nkk.sip.server.config.SipServer : 设备心跳:34020000001110008301
四、核心类
4.1 SipMessageTemplate
SipMessageTemplate 是里面主要类。封装了已实现的常用功能,如设备查询、目录查询、状态查询、实时点播、回放点播等功能。所有方法都是返回异步结果,可以异步获取结果,或阻塞等待结果,如下:
@Slf4j
@SuppressWarnings("all")
public class SipMessageTemplate {
/**
* 获取设备信息
*
* @param toDevice 设备
* @return {@link FutureEvent}
*/
public FutureEvent<DeviceInfo> getDeviceInfo(ToDevice toDevice) {
DeviceQuery xmlQuery = DeviceQuery.builder()
.deviceId(toDevice.getDeviceId())
.sn(SipUtil.generateSn())
.cmdType(SipEnum.Cmd.DeviceInfo.name())
.build();
byte[] xmlData = XmlUtils.toByteXml(xmlQuery, SipConstant.CHARSET);
return SipBuilder
.buildRequest(toDevice)
.ofMessageRequest(xmlData)
.executeAsync();
}
}
4.1.1 获取设备信息
/**
* 获取设备详情
*
* @param ip IP
* @param port 端口
* @param deviceId 设备id
* @param trans 传输方式
* @return {@link DeviceInfo}
*/
@GetMapping("/info")
public DeviceInfo info(String ip, int port, String deviceId,String trans) {
ToDevice toDevice = ToDevice.builder()
.deviceId(deviceId)
.channelId(deviceId)
.ip(ip)
.port(port)
.transport(SipConstant.TransPort.UDP)
.build();
FutureEvent<DeviceInfo> udp = sipMessageTemplate.getDeviceInfo(toDevice);
// 阻塞等待异步结果
Message<DeviceInfo> deviceInfoMessage = udp.get();
return deviceInfoMessage.getData();
}
4.1.2 获取目录
/**
* 获取设备目录
*/
@GetMapping("/catalog")
public DeferredResult<DeviceCatalog> catalog(String ip, int port, String deviceId,String trans) {
DeferredResult<DeviceCatalog> result = new DeferredResult<>(60 * 1000L);
ToDevice toDevice = ToDevice.builder()
.deviceId(deviceId)
.channelId(deviceId)
.ip(ip)
.port(port)
.transport(SipConstant.TransPort.UDP)
.build();
FutureEvent<DeviceCatalog> udp = sipMessageTemplate.getDeviceCatalog(toDevice);
// 异步等待结果
udp.onSuccess(result::setResult);
udp.onError(data -> {
System.out.println("onError" + data);
result.setResult(null);
});
udp.onTimeOut(data -> {
System.out.println("onTimeOut" + data);
result.setResult(null);
});
return result;
}
4.1.3 点播预览
项目中使用zlm流媒体进行国标设备推流,需要安装 ZLMediaKit
/**
* 设备通道实时预览
* @param deviceId 设备ID
* @param channelId 通道ID
* @param ip 设备ip
* @param port 设备端口
*/
@RequestMapping("/live")
public DeferredResult<ZmlPlayUrl> live(String deviceId, String channelId, String ip, int port) {
DeferredResult<ZmlPlayUrl> result = new DeferredResult<>(60 * 1000L);
ToDevice toDevice = ToDevice.builder()
.deviceId(deviceId)
.channelId(channelId)
.ip(ip)
.port(port)
.transport(SipConstant.TransPort.UDP)
.build();
FutureEvent<ZmlPlayUrl> udp = sipMessageTemplate.realTimePlay(toDevice);
// 点播成功
udp.onSuccess(result::setResult);
// 超时处理
udp.onTimeOut(data -> {
System.out.println("超时了...");
result.setResult(new ZmlPlayUrl());
});
// 出错处理
udp.onError(ex -> {
System.out.println("出错了..." + ex.getMessage());
result.setResult(new ZmlPlayUrl());
});
return result;
}
4.2 SipEventProcess
国标设备状态监听