ssrc 生成
This commit is contained in:
parent
4bbf2987e3
commit
3dc59f2dfb
@ -0,0 +1,77 @@
|
|||||||
|
package cn.skcks.docking.gb28181.service.play;
|
||||||
|
|
||||||
|
import cn.skcks.docking.gb28181.common.json.JsonResponse;
|
||||||
|
import cn.skcks.docking.gb28181.common.redis.RedisUtil;
|
||||||
|
import cn.skcks.docking.gb28181.core.sip.gb28181.cache.CacheUtil;
|
||||||
|
import cn.skcks.docking.gb28181.media.dto.rtp.GetRtpInfoResp;
|
||||||
|
import cn.skcks.docking.gb28181.media.dto.rtp.OpenRtpServer;
|
||||||
|
import cn.skcks.docking.gb28181.media.dto.rtp.OpenRtpServerResp;
|
||||||
|
import cn.skcks.docking.gb28181.media.dto.status.ResponseStatus;
|
||||||
|
import cn.skcks.docking.gb28181.media.proxy.ZlmMediaService;
|
||||||
|
import cn.skcks.docking.gb28181.orm.mybatis.dynamic.model.DockingDevice;
|
||||||
|
import cn.skcks.docking.gb28181.service.docking.device.DockingDeviceService;
|
||||||
|
import cn.skcks.docking.gb28181.service.ssrc.SsrcService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.context.request.async.DeferredResult;
|
||||||
|
|
||||||
|
import javax.sip.ListeningPoint;
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class PlayService {
|
||||||
|
private static final String PREFIX = "RealTimePlay";
|
||||||
|
private final DockingDeviceService deviceService;
|
||||||
|
private final ZlmMediaService zlmMediaService;
|
||||||
|
private final SsrcService ssrcService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param deviceId 设备id
|
||||||
|
* @param channelId 通道id
|
||||||
|
*/
|
||||||
|
public DeferredResult<JsonResponse<String>> realTimePlay(String deviceId, String channelId, long timeout){
|
||||||
|
DeferredResult<JsonResponse<String>> result = new DeferredResult<>(TimeUnit.SECONDS.toMillis(timeout));
|
||||||
|
DockingDevice device = deviceService.getDevice(deviceId);
|
||||||
|
if (device == null) {
|
||||||
|
log.info("未能找到 编码为 => {} 的设备", deviceId);
|
||||||
|
result.setResult(JsonResponse.error(null, "未找到设备"));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
String streamId = CacheUtil.getKey(deviceId,channelId);
|
||||||
|
String key = CacheUtil.getKey(PREFIX, streamId);
|
||||||
|
if(RedisUtil.KeyOps.hasKey(key)){
|
||||||
|
String url = RedisUtil.StringOps.get(key);
|
||||||
|
result.setResult(JsonResponse.success(url));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetRtpInfoResp rtpInfo = zlmMediaService.getRtpInfo(streamId);
|
||||||
|
if(rtpInfo.getExist()){
|
||||||
|
result.setResult(JsonResponse.error(MessageFormat.format("实时流 {0} 已存在", streamId)));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int streamMode = device.getStreamMode() == null || device.getStreamMode().equalsIgnoreCase(ListeningPoint.UDP) ? 0 : 1;
|
||||||
|
OpenRtpServer openRtpServer = new OpenRtpServer();
|
||||||
|
openRtpServer.setPort(0);
|
||||||
|
openRtpServer.setStreamId(streamId);
|
||||||
|
openRtpServer.setTcpMode(streamMode);
|
||||||
|
OpenRtpServerResp openRtpServerResp = zlmMediaService.openRtpServer(openRtpServer);
|
||||||
|
if(!openRtpServerResp.getCode().equals(ResponseStatus.Success)){
|
||||||
|
result.setResult(JsonResponse.error(openRtpServerResp.getCode().getMsg()));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
// zlmMediaService.getRtpInfo();
|
||||||
|
// GetMediaList getMediaList = new GetMediaList();
|
||||||
|
// getMediaList.set
|
||||||
|
// zlmMediaService.getMediaList()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,98 @@
|
|||||||
|
package cn.skcks.docking.gb28181.service.ssrc;
|
||||||
|
|
||||||
|
import cn.skcks.docking.gb28181.common.redis.RedisUtil;
|
||||||
|
import cn.skcks.docking.gb28181.config.sip.SipConfig;
|
||||||
|
import cn.skcks.docking.gb28181.core.sip.gb28181.cache.CacheUtil;
|
||||||
|
import cn.skcks.docking.gb28181.media.config.ZlmMediaConfig;
|
||||||
|
import jakarta.annotation.PostConstruct;
|
||||||
|
import jakarta.annotation.PreDestroy;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class SsrcService {
|
||||||
|
private static final String PREFIX = "SSRC";
|
||||||
|
private static final int MAX_STREAM_COUNT = 10000;
|
||||||
|
private final SipConfig sipConfig;
|
||||||
|
private final ZlmMediaConfig mediaConfig;
|
||||||
|
|
||||||
|
private String ssrcKey;
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
private void init(){
|
||||||
|
String ssrcPrefix = sipConfig.getDomain().substring(3, 8);
|
||||||
|
ssrcKey = CacheUtil.getKey(PREFIX,sipConfig.getId(),mediaConfig.getId());
|
||||||
|
List<String> ssrcList = new ArrayList<>(MAX_STREAM_COUNT);
|
||||||
|
for (int i = 1; i < MAX_STREAM_COUNT; i++) {
|
||||||
|
String ssrc = String.format("%s%04d", ssrcPrefix, i);
|
||||||
|
ssrcList.add(ssrc);
|
||||||
|
}
|
||||||
|
|
||||||
|
RedisUtil.KeyOps.delete(ssrcKey);
|
||||||
|
RedisUtil.SetOps.sAdd(ssrcKey, ssrcList.toArray(String[]::new));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreDestroy
|
||||||
|
private void destroy(){
|
||||||
|
if(ssrcKey != null){
|
||||||
|
RedisUtil.KeyOps.delete(ssrcKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getSN() {
|
||||||
|
String sn;
|
||||||
|
long size = RedisUtil.SetOps.sSize(ssrcKey);
|
||||||
|
if (size == 0) {
|
||||||
|
throw new RuntimeException("ssrc已经用完");
|
||||||
|
} else {
|
||||||
|
// 在集合中移除并返回一个随机成员。
|
||||||
|
sn = RedisUtil.SetOps.sPop(ssrcKey);
|
||||||
|
RedisUtil.SetOps.sRemove(ssrcKey,sn);
|
||||||
|
}
|
||||||
|
return sn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置一个流媒体服务的所有ssrc
|
||||||
|
*
|
||||||
|
* @param mediaServerId 流媒体服务ID
|
||||||
|
*/
|
||||||
|
public void reset(String mediaServerId) {
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取视频预览的SSRC值,第一位固定为0
|
||||||
|
*
|
||||||
|
* @return ssrc
|
||||||
|
*/
|
||||||
|
public String getPlaySsrc() {
|
||||||
|
return "0" + getSN();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取录像回放的SSRC值,第一位固定为1
|
||||||
|
*/
|
||||||
|
public String getPlayBackSsrc(String mediaServerI) {
|
||||||
|
return "1" + getSN();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 释放ssrc,主要用完的ssrc一定要释放,否则会耗尽
|
||||||
|
*
|
||||||
|
* @param ssrc 需要重置的ssrc
|
||||||
|
*/
|
||||||
|
public void releaseSsrc(String mediaServerId, String ssrc) {
|
||||||
|
if (ssrc == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String sn = ssrc.substring(1);
|
||||||
|
RedisUtil.SetOps.sAdd(ssrcKey, sn);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user