package com.genersoft.iot.vmp.media.zlm;
|
|
import com.alibaba.fastjson.JSONObject;
|
import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
|
import com.genersoft.iot.vmp.gb28181.session.SsrcUtil;
|
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.Component;
|
|
import java.util.HashMap;
|
import java.util.Map;
|
|
@Component
|
public class ZLMRTPServerFactory {
|
|
private Logger logger = LoggerFactory.getLogger("ZLMRTPServerFactory");
|
|
@Value("${media.rtp.udpPortRange}")
|
private String udpPortRange;
|
|
@Autowired
|
private ZLMRESTfulUtils zlmresTfulUtils;
|
|
private int[] udpPortRangeArray = new int[2];
|
|
private int currentPort = 0;
|
|
public int createRTPServer(String streamId) {
|
Map<String, Object> param = new HashMap<>();
|
int result = -1;
|
int newPort = getPortFromUdpPortRange();
|
param.put("port", newPort);
|
param.put("enable_tcp", 1);
|
param.put("stream_id", streamId);
|
JSONObject jsonObject = zlmresTfulUtils.openRtpServer(param);
|
System.out.println(jsonObject);
|
|
if (jsonObject != null) {
|
switch (jsonObject.getInteger("code")){
|
case 0:
|
result= newPort;
|
break;
|
case -300: // id已经存在
|
result = newPort;
|
break;
|
case -400: // 端口占用
|
result= createRTPServer(streamId);
|
break;
|
default:
|
logger.error("创建RTP Server 失败: " + jsonObject.getString("msg"));
|
break;
|
}
|
}else {
|
// 检查ZLM状态
|
logger.error("创建RTP Server 失败: 请检查ZLM服务");
|
}
|
return result;
|
}
|
|
public boolean closeRTPServer(String streamId) {
|
boolean result = false;
|
Map<String, Object> param = new HashMap<>();
|
param.put("stream_id", streamId);
|
JSONObject jsonObject = zlmresTfulUtils.closeRtpServer(param);
|
if (jsonObject != null ) {
|
if (jsonObject.getInteger("code") == 0) {
|
result = jsonObject.getInteger("hit") == 1;
|
}else {
|
logger.error("关闭RTP Server 失败: " + jsonObject.getString("msg"));
|
}
|
}else {
|
// 检查ZLM状态
|
logger.error("关闭RTP Server 失败: 请检查ZLM服务");
|
}
|
return result;
|
}
|
|
private int getPortFromUdpPortRange() {
|
if (currentPort == 0) {
|
String[] udpPortRangeStrArray = udpPortRange.split(",");
|
udpPortRangeArray[0] = Integer.parseInt(udpPortRangeStrArray[0]);
|
udpPortRangeArray[1] = Integer.parseInt(udpPortRangeStrArray[1]);
|
}
|
|
if (currentPort == 0 || currentPort++ > udpPortRangeArray[1]) {
|
currentPort = udpPortRangeArray[0];
|
return udpPortRangeArray[0];
|
} else {
|
if (currentPort % 2 == 1) {
|
currentPort++;
|
}
|
return currentPort++;
|
}
|
}
|
|
/**
|
* 创建一个推流
|
* @param ip 推流ip
|
* @param port 推流端口
|
* @param ssrc 推流唯一标识
|
* @param platformId 平台id
|
* @param channelId 通道id
|
* @param tcp 是否为tcp
|
* @return SendRtpItem
|
*/
|
public SendRtpItem createSendRtpItem(String ip, int port, String ssrc, String platformId, String deviceId, String channelId, boolean tcp){
|
String playSsrc = SsrcUtil.getPlaySsrc();
|
int localPort = createRTPServer(SsrcUtil.getPlaySsrc());
|
if (localPort != -1) {
|
closeRTPServer(playSsrc);
|
}else {
|
logger.error("没有可用的端口");
|
return null;
|
}
|
SendRtpItem sendRtpItem = new SendRtpItem();
|
sendRtpItem.setIp(ip);
|
sendRtpItem.setPort(port);
|
sendRtpItem.setSsrc(ssrc);
|
sendRtpItem.setPlatformId(platformId);
|
sendRtpItem.setDeviceId(deviceId);
|
sendRtpItem.setChannelId(channelId);
|
sendRtpItem.setTcp(tcp);
|
sendRtpItem.setLocalPort(localPort);
|
return sendRtpItem;
|
}
|
|
/**
|
* 调用zlm RESTful API —— startSendRtp
|
*/
|
public Boolean startSendRtpStream(Map<String, Object>param) {
|
Boolean result = false;
|
JSONObject jsonObject = zlmresTfulUtils.startSendRtp(param);
|
System.out.println(jsonObject);
|
if (jsonObject == null) {
|
logger.error("RTP推流失败: 请检查ZLM服务");
|
} else if (jsonObject.getInteger("code") == 0) {
|
result= true;
|
logger.error("RTP推流请求成功,本地推流端口:" + jsonObject.getString("local_port"));
|
} else {
|
logger.error("RTP推流失败: " + jsonObject.getString("msg"));
|
}
|
return result;
|
}
|
|
/**
|
* 查询待转推的流是否就绪
|
*/
|
public Boolean isRtpReady(String streamId) {
|
JSONObject mediaInfo = zlmresTfulUtils.getMediaInfo("rtp", "rtmp", streamId);
|
return (mediaInfo.getInteger("code") == 0 && mediaInfo.getBoolean("online"));
|
}
|
|
/**
|
* 调用zlm RESTful API —— stopSendRtp
|
*/
|
public Boolean stopSendRtpStream(Map<String, Object>param) {
|
Boolean result = false;
|
JSONObject jsonObject = zlmresTfulUtils.stopSendRtp(param);
|
System.out.println(jsonObject);
|
if (jsonObject == null) {
|
logger.error("停止RTP推流失败: 请检查ZLM服务");
|
} else if (jsonObject.getInteger("code") == 0) {
|
result= true;
|
logger.error("停止RTP推流成功");
|
} else {
|
logger.error("停止RTP推流失败: " + jsonObject.getString("msg"));
|
}
|
return result;
|
}
|
}
|