优化子码流切换逻辑,去除主子多开逻辑。优化单端口模式ssrc变化导致的无法移出点播缓存 #895
parent
f4e5e03962
commit
155838ce2e
|
@ -29,7 +29,7 @@ public class InviteInfo {
|
|||
private StreamInfo streamInfo;
|
||||
|
||||
|
||||
public static InviteInfo getinviteInfo(String deviceId, String channelId, String stream, SSRCInfo ssrcInfo,
|
||||
public static InviteInfo getInviteInfo(String deviceId, String channelId, String stream, SSRCInfo ssrcInfo,
|
||||
String receiveIp, Integer receivePort, String streamMode,
|
||||
InviteSessionType type, InviteSessionStatus status) {
|
||||
InviteInfo inviteInfo = new InviteInfo();
|
||||
|
@ -138,25 +138,6 @@ public class InviteInfo {
|
|||
this.subStream = subStream;
|
||||
}
|
||||
|
||||
public static InviteInfo getInviteInfo(String deviceId, String channelId,Boolean isSubStream, String stream, SSRCInfo ssrcInfo,
|
||||
String receiveIp, Integer receivePort, String streamMode,
|
||||
InviteSessionType type, InviteSessionStatus status) {
|
||||
InviteInfo inviteInfo = new InviteInfo();
|
||||
inviteInfo.setDeviceId(deviceId);
|
||||
inviteInfo.setChannelId(channelId);
|
||||
inviteInfo.setStream(stream);
|
||||
inviteInfo.setSsrcInfo(ssrcInfo);
|
||||
inviteInfo.setReceiveIp(receiveIp);
|
||||
inviteInfo.setReceivePort(receivePort);
|
||||
inviteInfo.setStreamMode(streamMode);
|
||||
inviteInfo.setType(type);
|
||||
inviteInfo.setStatus(status);
|
||||
if(isSubStream != null){
|
||||
inviteInfo.setSubStream(isSubStream);
|
||||
}
|
||||
return inviteInfo;
|
||||
}
|
||||
/*=========================设备主子码流逻辑END====================*/
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -542,17 +542,5 @@ public class StreamInfo implements Serializable, Cloneable{
|
|||
this.subStream = subStream;
|
||||
}
|
||||
|
||||
public static String getPlayStream(String deviceId,String channelId,boolean isSubStream){
|
||||
String streamId;
|
||||
if(isSubStream){
|
||||
streamId = String.format("%s_%s_%s","sub",deviceId, channelId);
|
||||
}else {
|
||||
streamId = String.format("%s_%s_%s","main", deviceId, channelId);
|
||||
}
|
||||
return streamId;
|
||||
}
|
||||
|
||||
/*=========================设备主子码流逻辑END====================*/
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -45,7 +45,6 @@ public class DynamicTask {
|
|||
* @return
|
||||
*/
|
||||
public void startCron(String key, Runnable task, int cycleForCatalog) {
|
||||
System.out.println(cycleForCatalog);
|
||||
ScheduledFuture<?> future = futureMap.get(key);
|
||||
if (future != null) {
|
||||
if (future.isCancelled()) {
|
||||
|
|
|
@ -156,29 +156,5 @@ public class DeferredResultHolder {
|
|||
}
|
||||
}
|
||||
|
||||
/*============================设备主子码流逻辑START========================*/
|
||||
public static String getPlayKey(String deviceId,String channelId,boolean deviceSwitchSubStream,boolean isSubStream){
|
||||
String key = null;
|
||||
if(deviceSwitchSubStream){
|
||||
key = CALLBACK_CMD_PLAY + isSubStream + deviceId + channelId;
|
||||
}else {
|
||||
key = CALLBACK_CMD_PLAY +deviceId + channelId;
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
public static String getSnapKey(String deviceId,String channelId,boolean deviceSwitchSubStream,boolean isSubStream){
|
||||
String key = null;
|
||||
if(deviceSwitchSubStream){
|
||||
key = CALLBACK_CMD_SNAP + isSubStream + deviceId + channelId;
|
||||
}else {
|
||||
key = CALLBACK_CMD_SNAP +deviceId + channelId;
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
|
||||
/*============================设备主子码流逻辑END========================*/
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -98,7 +98,7 @@ public interface ISIPCommander {
|
|||
* @param device 视频设备
|
||||
* @param channelId 预览通道
|
||||
*/
|
||||
void playStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId,boolean isSubStream, ZlmHttpHookSubscribe.Event event, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException;
|
||||
void playStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId, ZlmHttpHookSubscribe.Event event, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException;
|
||||
|
||||
/**
|
||||
* 请求回放视频流
|
||||
|
|
|
@ -268,7 +268,7 @@ public class SIPCommander implements ISIPCommander {
|
|||
* @param errorEvent sip错误订阅
|
||||
*/
|
||||
@Override
|
||||
public void playStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId,boolean isSubStream,
|
||||
public void playStreamCmd(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId,
|
||||
ZlmHttpHookSubscribe.Event event, SipSubscribe.Event okEvent, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException {
|
||||
String stream = ssrcInfo.getStream();
|
||||
|
||||
|
@ -345,13 +345,13 @@ public class SIPCommander implements ISIPCommander {
|
|||
|
||||
if( device.isSwitchPrimarySubStream() ){
|
||||
if("TP-LINK".equals(device.getManufacturer())){
|
||||
if (isSubStream){
|
||||
if (device.isSwitchPrimarySubStream()){
|
||||
content.append("a=streamMode:sub\r\n");
|
||||
}else {
|
||||
content.append("a=streamMode:main\r\n");
|
||||
}
|
||||
}else {
|
||||
if (isSubStream){
|
||||
if (device.isSwitchPrimarySubStream()){
|
||||
content.append("a=streamprofile:1\r\n");
|
||||
}else {
|
||||
content.append("a=streamprofile:0\r\n");
|
||||
|
@ -374,11 +374,8 @@ public class SIPCommander implements ISIPCommander {
|
|||
// 这里为例避免一个通道的点播只有一个callID这个参数使用一个固定值
|
||||
ResponseEvent responseEvent = (ResponseEvent) e.event;
|
||||
SIPResponse response = (SIPResponse) responseEvent.getResponse();
|
||||
if(device.isSwitchPrimarySubStream()){
|
||||
streamSession.put(device.getDeviceId(), channelId, "switch-play", stream, ssrcInfo.getSsrc(), mediaServerItem.getId(), response, InviteSessionType.PLAY);
|
||||
}else {
|
||||
streamSession.put(device.getDeviceId(), channelId, "play", stream, ssrcInfo.getSsrc(), mediaServerItem.getId(), response, InviteSessionType.PLAY);
|
||||
}
|
||||
streamSession.put(device.getDeviceId(), channelId, "play", stream, ssrcInfo.getSsrc(), mediaServerItem.getId(), response,
|
||||
InviteSessionType.PLAY);
|
||||
okEvent.response(e);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -142,13 +142,8 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In
|
|||
// 可能是设备主动停止
|
||||
Device device = storager.queryVideoDeviceByChannelId(platformGbId);
|
||||
if (device != null) {
|
||||
SsrcTransaction ssrcTransactionForPlay = null;
|
||||
if (device.isSwitchPrimarySubStream() ) {
|
||||
ssrcTransactionForPlay = streamSession.getSsrcTransaction(device.getDeviceId(), channelId, "switch-play", null);
|
||||
} else {
|
||||
storager.stopPlay(device.getDeviceId(), channelId);
|
||||
ssrcTransactionForPlay = streamSession.getSsrcTransaction(device.getDeviceId(), channelId, "play", null);
|
||||
}
|
||||
storager.stopPlay(device.getDeviceId(), channelId);
|
||||
SsrcTransaction ssrcTransactionForPlay = streamSession.getSsrcTransaction(device.getDeviceId(), channelId, "play", null);
|
||||
if (ssrcTransactionForPlay != null){
|
||||
if (ssrcTransactionForPlay.getCallId().equals(callIdHeader.getCallId())){
|
||||
// 释放ssrc
|
||||
|
@ -158,16 +153,8 @@ public class ByeRequestProcessor extends SIPRequestProcessorParent implements In
|
|||
}
|
||||
streamSession.remove(device.getDeviceId(), channelId, ssrcTransactionForPlay.getStream());
|
||||
}
|
||||
InviteInfo inviteInfo = null;
|
||||
if (device.isSwitchPrimarySubStream() ) {
|
||||
String streamType = ssrcTransactionForPlay.getStream().split("_")[0];
|
||||
boolean isSubStream = "sub".equals(streamType);
|
||||
inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId,isSubStream);
|
||||
inviteStreamService.removeInviteInfo(inviteInfo.getType(),inviteInfo.getDeviceId(),inviteInfo.getChannelId(),isSubStream,inviteInfo.getStream());
|
||||
}else {
|
||||
inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId);
|
||||
inviteStreamService.removeInviteInfo(inviteInfo);
|
||||
}
|
||||
InviteInfo inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId);
|
||||
inviteStreamService.removeInviteInfo(inviteInfo);
|
||||
if (inviteInfo != null) {
|
||||
if (inviteInfo.getStreamInfo() != null) {
|
||||
mediaServerService.closeRTPServer(inviteInfo.getStreamInfo().getMediaServerId(), inviteInfo.getStream());
|
||||
|
|
|
@ -490,7 +490,7 @@ public class InviteRequestProcessor extends SIPRequestProcessorParent implements
|
|||
}
|
||||
sendRtpItem.setStreamId(streamId);
|
||||
redisCatchStorage.updateSendRTPSever(sendRtpItem);
|
||||
playService.play(mediaServerItem, device.getDeviceId(), channelId,false, ((code, msg, data) -> {
|
||||
playService.play(mediaServerItem, device.getDeviceId(), channelId, ((code, msg, data) -> {
|
||||
if (code == InviteErrorCode.SUCCESS.getCode()){
|
||||
hookEvent.run(code, msg, data);
|
||||
}else if (code == InviteErrorCode.ERROR_FOR_SIGNALLING_TIMEOUT.getCode() || code == InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getCode()){
|
||||
|
|
|
@ -252,7 +252,6 @@ public class NotifyRequestForCatalogProcessor extends SIPRequestProcessorParent
|
|||
}
|
||||
|
||||
private void executeSave(){
|
||||
System.out.println("定时存储数据");
|
||||
executeSaveForUpdate();
|
||||
executeSaveForDelete();
|
||||
executeSaveForOnline();
|
||||
|
|
|
@ -250,7 +250,6 @@ public class SipUtils {
|
|||
if (ObjectUtils.isEmpty(timeStr)){
|
||||
return null;
|
||||
}
|
||||
System.out.println(timeStr);
|
||||
LocalDateTime localDateTime;
|
||||
try {
|
||||
localDateTime = LocalDateTime.parse(timeStr);
|
||||
|
|
|
@ -343,19 +343,10 @@ public class ZLMHttpHookListener {
|
|||
}
|
||||
|
||||
if ("rtp".equals(param.getApp()) && !param.isRegist()) {
|
||||
if(param.getStream().split("_").length == 3){
|
||||
boolean isSubStream = "sub".equals(param.getStream().split("_")[0]);
|
||||
InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(null, param.getStream(), isSubStream);
|
||||
if(inviteInfo != null && (inviteInfo.getType() == InviteSessionType.PLAY )){
|
||||
inviteStreamService.removeInviteInfo(inviteInfo.getType(),inviteInfo.getDeviceId(),
|
||||
inviteInfo.getChannelId(),inviteInfo.isSubStream(),inviteInfo.getStream());
|
||||
}
|
||||
}else {
|
||||
InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(null, param.getStream());
|
||||
if (inviteInfo != null && (inviteInfo.getType() == InviteSessionType.PLAY || inviteInfo.getType() == InviteSessionType.PLAYBACK)) {
|
||||
inviteStreamService.removeInviteInfo(inviteInfo);
|
||||
storager.stopPlay(inviteInfo.getDeviceId(), inviteInfo.getChannelId());
|
||||
}
|
||||
InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(null, param.getStream());
|
||||
if (inviteInfo != null && (inviteInfo.getType() == InviteSessionType.PLAY || inviteInfo.getType() == InviteSessionType.PLAYBACK)) {
|
||||
inviteStreamService.removeInviteInfo(inviteInfo);
|
||||
storager.stopPlay(inviteInfo.getDeviceId(), inviteInfo.getChannelId());
|
||||
}
|
||||
} else {
|
||||
if (!"rtp".equals(param.getApp())) {
|
||||
|
@ -483,15 +474,8 @@ public class ZLMHttpHookListener {
|
|||
Device device = deviceService.getDevice(inviteInfo.getDeviceId());
|
||||
if (device != null) {
|
||||
try {
|
||||
InviteInfo info = null;
|
||||
if(device.isSwitchPrimarySubStream()){
|
||||
boolean isSubStream = "sub".equals(param.getStream().split("_")[0]);
|
||||
info = inviteStreamService.getInviteInfo(inviteInfo.getType(), inviteInfo.getDeviceId(), inviteInfo.getChannelId(),isSubStream, inviteInfo.getStream());
|
||||
}else {
|
||||
info = inviteStreamService.getInviteInfo(inviteInfo.getType(), inviteInfo.getDeviceId(), inviteInfo.getChannelId(), inviteInfo.getStream());
|
||||
|
||||
}
|
||||
|
||||
InviteInfo info = inviteStreamService.getInviteInfo(inviteInfo.getType(),
|
||||
inviteInfo.getDeviceId(), inviteInfo.getChannelId(), inviteInfo.getStream());
|
||||
if (info != null) {
|
||||
cmder.streamByeCmd(device, inviteInfo.getChannelId(),
|
||||
inviteInfo.getStream(), null);
|
||||
|
@ -502,15 +486,9 @@ public class ZLMHttpHookListener {
|
|||
}
|
||||
}
|
||||
|
||||
if(device.isSwitchPrimarySubStream()){
|
||||
boolean isSubStream = "sub".equals(param.getStream().split("_")[0]);
|
||||
inviteStreamService.removeInviteInfo(inviteInfo.getType(), inviteInfo.getDeviceId(),
|
||||
inviteInfo.getChannelId(),isSubStream, inviteInfo.getStream());
|
||||
}else {
|
||||
inviteStreamService.removeInviteInfo(inviteInfo.getType(), inviteInfo.getDeviceId(),
|
||||
inviteInfo.getChannelId(), inviteInfo.getStream());
|
||||
storager.stopPlay(inviteInfo.getDeviceId(), inviteInfo.getChannelId());
|
||||
}
|
||||
inviteStreamService.removeInviteInfo(inviteInfo.getType(), inviteInfo.getDeviceId(),
|
||||
inviteInfo.getChannelId(), inviteInfo.getStream());
|
||||
storager.stopPlay(inviteInfo.getDeviceId(), inviteInfo.getChannelId());
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
|
@ -563,26 +541,12 @@ public class ZLMHttpHookListener {
|
|||
|
||||
if ("rtp".equals(param.getApp())) {
|
||||
String[] s = param.getStream().split("_");
|
||||
if (!mediaInfo.isRtpEnable() ) {
|
||||
defaultResult.setResult(HookResult.SUCCESS());
|
||||
return defaultResult;
|
||||
}else if(s.length != 2 && s.length != 3 ){
|
||||
if (!mediaInfo.isRtpEnable() || s.length != 2) {
|
||||
defaultResult.setResult(HookResult.SUCCESS());
|
||||
return defaultResult;
|
||||
}
|
||||
String deviceId = null;
|
||||
String channelId = null;
|
||||
boolean isSubStream = false;
|
||||
if (s[0].length() < 20) {
|
||||
if ("sub".equals(s[0])) {
|
||||
isSubStream = true;
|
||||
}
|
||||
deviceId = s[1];
|
||||
channelId = s[2];
|
||||
} else {
|
||||
deviceId = s[0];
|
||||
channelId = s[1];
|
||||
}
|
||||
String deviceId = s[0];
|
||||
String channelId = s[1];
|
||||
Device device = redisCatchStorage.getDevice(deviceId);
|
||||
if (device == null) {
|
||||
defaultResult.setResult(new HookResult(ErrorCode.ERROR404.getCode(), ErrorCode.ERROR404.getMsg()));
|
||||
|
@ -596,7 +560,7 @@ public class ZLMHttpHookListener {
|
|||
logger.info("[ZLM HOOK] 流未找到, 发起自动点播:{}->{}->{}/{}", param.getMediaServerId(), param.getSchema(), param.getApp(), param.getStream());
|
||||
|
||||
RequestMessage msg = new RequestMessage();
|
||||
String key = DeferredResultHolder.getPlayKey(deviceId, channelId, device.isSwitchPrimarySubStream(), isSubStream);
|
||||
String key = DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId;
|
||||
boolean exist = resultHolder.exist(key, null);
|
||||
msg.setKey(key);
|
||||
String uuid = UUID.randomUUID().toString();
|
||||
|
@ -614,7 +578,7 @@ public class ZLMHttpHookListener {
|
|||
resultHolder.put(key, uuid, result);
|
||||
|
||||
if (!exist) {
|
||||
playService.play(mediaInfo, deviceId, channelId,isSubStream, (code, message, data) -> {
|
||||
playService.play(mediaInfo, deviceId, channelId, (code, message, data) -> {
|
||||
msg.setData(new HookResult(code, message));
|
||||
resultHolder.invokeResult(msg);
|
||||
});
|
||||
|
|
|
@ -270,11 +270,6 @@ public class ZLMRESTfulUtils {
|
|||
}
|
||||
|
||||
public JSONObject openRtpServer(MediaServerItem mediaServerItem, Map<String, Object> param){
|
||||
System.out.println("==============openRtpServer=================");
|
||||
for (String s : param.keySet()) {
|
||||
System.out.println(s + "-->" + param.get(s));
|
||||
}
|
||||
System.out.println("===============================");
|
||||
return sendPost(mediaServerItem, "openRtpServer",param, null);
|
||||
}
|
||||
|
||||
|
|
|
@ -227,7 +227,6 @@ public class ZLMRTPServerFactory {
|
|||
int localPort = 0;
|
||||
if (userSetting.getGbSendStreamStrict()) {
|
||||
if (userSetting.getGbSendStreamStrict()) {
|
||||
System.out.println("createSendRtpItem1");
|
||||
localPort = keepPort(serverItem, ssrc, localPort);
|
||||
if (localPort == 0) {
|
||||
return null;
|
||||
|
@ -264,7 +263,6 @@ public class ZLMRTPServerFactory {
|
|||
// 默认为随机端口
|
||||
int localPort = 0;
|
||||
if (userSetting.getGbSendStreamStrict()) {
|
||||
System.out.println("createSendRtpItem2");
|
||||
localPort = keepPort(serverItem, ssrc, localPort);
|
||||
if (localPort == 0) {
|
||||
return null;
|
||||
|
@ -294,9 +292,7 @@ public class ZLMRTPServerFactory {
|
|||
param.put("port", localPort);
|
||||
param.put("enable_tcp", 1);
|
||||
param.put("stream_id", ssrc);
|
||||
System.out.println("用于收流");
|
||||
JSONObject jsonObject = zlmresTfulUtils.openRtpServer(serverItem, param);
|
||||
System.out.println(jsonObject);
|
||||
if (jsonObject.getInteger("code") == 0) {
|
||||
localPort = jsonObject.getInteger("port");
|
||||
HookSubscribeForRtpServerTimeout hookSubscribeForRtpServerTimeout = HookSubscribeFactory.on_rtp_server_timeout(ssrc, null, serverItem.getId());
|
||||
|
|
|
@ -4,8 +4,6 @@ import com.genersoft.iot.vmp.common.InviteInfo;
|
|||
import com.genersoft.iot.vmp.common.InviteSessionType;
|
||||
import com.genersoft.iot.vmp.service.bean.ErrorCallback;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 记录国标点播的状态,包括实时预览,下载,录像回放
|
||||
*/
|
||||
|
@ -16,6 +14,8 @@ public interface IInviteStreamService {
|
|||
*/
|
||||
void updateInviteInfo(InviteInfo inviteInfo);
|
||||
|
||||
InviteInfo updateInviteInfoForStream(InviteInfo inviteInfo, String stream);
|
||||
|
||||
/**
|
||||
* 获取点播的状态信息
|
||||
*/
|
||||
|
@ -74,48 +74,5 @@ public interface IInviteStreamService {
|
|||
int getStreamInfoCount(String mediaServerId);
|
||||
|
||||
|
||||
/*======================设备主子码流逻辑START=========================*/
|
||||
/**
|
||||
* 获取点播的状态信息
|
||||
*/
|
||||
InviteInfo getInviteInfoByDeviceAndChannel(InviteSessionType type,
|
||||
String deviceId,
|
||||
String channelId,boolean isSubStream);
|
||||
|
||||
void removeInviteInfoByDeviceAndChannel(InviteSessionType inviteSessionType, String deviceId, String channelId,boolean isSubStream);
|
||||
|
||||
InviteInfo getInviteInfo(InviteSessionType type,
|
||||
String deviceId,
|
||||
String channelId,
|
||||
boolean isSubStream,
|
||||
String stream);
|
||||
|
||||
void removeInviteInfo(InviteSessionType type,
|
||||
String deviceId,
|
||||
String channelId,
|
||||
boolean isSubStream,
|
||||
String stream);
|
||||
|
||||
void once(InviteSessionType type, String deviceId, String channelId,boolean isSubStream, String stream, ErrorCallback<Object> callback);
|
||||
|
||||
void call(InviteSessionType type, String deviceId, String channelId,boolean isSubStream, String stream, int code, String msg, Object data);
|
||||
|
||||
void updateInviteInfoSub(InviteInfo inviteInfo);
|
||||
|
||||
/**
|
||||
* 获取点播的状态信息
|
||||
*/
|
||||
InviteInfo getInviteInfoByStream(InviteSessionType type, String stream,boolean isSubStream);
|
||||
|
||||
/**
|
||||
* 获取点播的状态信息
|
||||
*/
|
||||
List<Object> getInviteInfos(InviteSessionType type,
|
||||
String deviceId,
|
||||
String channelId,
|
||||
String stream);
|
||||
/*======================设备主子码流逻辑END=========================*/
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -16,9 +16,9 @@ import java.text.ParseException;
|
|||
*/
|
||||
public interface IPlayService {
|
||||
|
||||
void play(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId,boolean isSubStream,
|
||||
void play(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId,
|
||||
ErrorCallback<Object> callback);
|
||||
SSRCInfo play(MediaServerItem mediaServerItem, String deviceId, String channelId,boolean isSubStream, ErrorCallback<Object> callback);
|
||||
SSRCInfo play(MediaServerItem mediaServerItem, String deviceId, String channelId, ErrorCallback<Object> callback);
|
||||
|
||||
MediaServerItem getNewMediaServerItem(Device device);
|
||||
|
||||
|
@ -43,5 +43,5 @@ public interface IPlayService {
|
|||
|
||||
void resumeRtp(String streamId) throws ServiceException, InvalidArgumentException, ParseException, SipException;
|
||||
|
||||
void getSnap(String deviceId, String channelId, String fileName,boolean isSubStream, ErrorCallback errorCallback);
|
||||
void getSnap(String deviceId, String channelId, String fileName, ErrorCallback errorCallback);
|
||||
}
|
||||
|
|
|
@ -84,6 +84,24 @@ public class InviteStreamServiceImpl implements IInviteStreamService {
|
|||
redisTemplate.opsForValue().set(key, inviteInfoForUpdate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InviteInfo updateInviteInfoForStream(InviteInfo inviteInfo, String stream) {
|
||||
|
||||
InviteInfo inviteInfoInDb = getInviteInfo(inviteInfo.getType(), inviteInfo.getDeviceId(), inviteInfo.getChannelId(), inviteInfo.getStream());
|
||||
if (inviteInfoInDb == null) {
|
||||
return null;
|
||||
}
|
||||
removeInviteInfo(inviteInfoInDb);
|
||||
String key = VideoManagerConstants.INVITE_PREFIX +
|
||||
"_" + inviteInfo.getType() +
|
||||
"_" + inviteInfo.getDeviceId() +
|
||||
"_" + inviteInfo.getChannelId() +
|
||||
"_" + stream;
|
||||
inviteInfoInDb.setStream(stream);
|
||||
redisTemplate.opsForValue().set(key, inviteInfoInDb);
|
||||
return inviteInfoInDb;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InviteInfo getInviteInfo(InviteSessionType type, String deviceId, String channelId, String stream) {
|
||||
String key = VideoManagerConstants.INVITE_PREFIX +
|
||||
|
@ -152,19 +170,6 @@ public class InviteStreamServiceImpl implements IInviteStreamService {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void call(InviteSessionType type, String deviceId, String channelId, String stream, int code, String msg, Object data) {
|
||||
String key = buildKey(type, deviceId, channelId, stream);
|
||||
List<ErrorCallback<Object>> callbacks = inviteErrorCallbackMap.get(key);
|
||||
if (callbacks == null) {
|
||||
return;
|
||||
}
|
||||
for (ErrorCallback<Object> callback : callbacks) {
|
||||
callback.run(code, msg, data);
|
||||
}
|
||||
inviteErrorCallbackMap.remove(key);
|
||||
}
|
||||
|
||||
private String buildKey(InviteSessionType type, String deviceId, String channelId, String stream) {
|
||||
String key = type + "_" + deviceId + "_" + channelId;
|
||||
// 如果ssrc未null那么可以实现一个通道只能一次操作,ssrc不为null则可以支持一个通道多次invite
|
||||
|
@ -199,69 +204,9 @@ public class InviteStreamServiceImpl implements IInviteStreamService {
|
|||
return count;
|
||||
}
|
||||
|
||||
/*======================设备主子码流逻辑START=========================*/
|
||||
|
||||
@Override
|
||||
public InviteInfo getInviteInfoByDeviceAndChannel(InviteSessionType type, String deviceId, String channelId, boolean isSubStream) {
|
||||
return getInviteInfo(type, deviceId, channelId,isSubStream, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeInviteInfoByDeviceAndChannel(InviteSessionType inviteSessionType, String deviceId, String channelId, boolean isSubStream) {
|
||||
removeInviteInfo(inviteSessionType, deviceId, channelId,isSubStream, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InviteInfo getInviteInfo(InviteSessionType type, String deviceId, String channelId,boolean isSubStream, String stream) {
|
||||
String key = VideoManagerConstants.INVITE_PREFIX +
|
||||
"_" + (type != null ? type : "*") +
|
||||
"_" + (isSubStream ? "sub" : "main") +
|
||||
"_" + (deviceId != null ? deviceId : "*") +
|
||||
"_" + (channelId != null ? channelId : "*") +
|
||||
"_" + (stream != null ? stream : "*");
|
||||
List<Object> scanResult = RedisUtil.scan(redisTemplate, key);
|
||||
if (scanResult.size() != 1) {
|
||||
return null;
|
||||
}
|
||||
return (InviteInfo) redisTemplate.opsForValue().get(scanResult.get(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeInviteInfo(InviteSessionType type, String deviceId, String channelId, boolean isSubStream, String stream) {
|
||||
String scanKey = VideoManagerConstants.INVITE_PREFIX +
|
||||
"_" + (type != null ? type : "*") +
|
||||
"_" + (isSubStream ? "sub" : "main") +
|
||||
"_" + (deviceId != null ? deviceId : "*") +
|
||||
"_" + (channelId != null ? channelId : "*") +
|
||||
"_" + (stream != null ? stream : "*");
|
||||
List<Object> scanResult = RedisUtil.scan(redisTemplate, scanKey);
|
||||
if (scanResult.size() > 0) {
|
||||
for (Object keyObj : scanResult) {
|
||||
String key = (String) keyObj;
|
||||
InviteInfo inviteInfo = (InviteInfo) redisTemplate.opsForValue().get(key);
|
||||
if (inviteInfo == null) {
|
||||
continue;
|
||||
}
|
||||
redisTemplate.delete(key);
|
||||
inviteErrorCallbackMap.remove(buildKey(type, deviceId, channelId, inviteInfo.getStream()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void once(InviteSessionType type, String deviceId, String channelId, boolean isSubStream, String stream, ErrorCallback<Object> callback) {
|
||||
String key = buildSubStreamKey(type, deviceId, channelId,isSubStream, stream);
|
||||
List<ErrorCallback<Object>> callbacks = inviteErrorCallbackMap.get(key);
|
||||
if (callbacks == null) {
|
||||
callbacks = new CopyOnWriteArrayList<>();
|
||||
inviteErrorCallbackMap.put(key, callbacks);
|
||||
}
|
||||
callbacks.add(callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void call(InviteSessionType type, String deviceId, String channelId, boolean isSubStream, String stream, int code, String msg, Object data) {
|
||||
String key = buildSubStreamKey(type, deviceId, channelId,isSubStream, stream);
|
||||
public void call(InviteSessionType type, String deviceId, String channelId, String stream, int code, String msg, Object data) {
|
||||
String key = buildSubStreamKey(type, deviceId, channelId, stream);
|
||||
List<ErrorCallback<Object>> callbacks = inviteErrorCallbackMap.get(key);
|
||||
if (callbacks == null) {
|
||||
return;
|
||||
|
@ -273,89 +218,12 @@ public class InviteStreamServiceImpl implements IInviteStreamService {
|
|||
}
|
||||
|
||||
|
||||
private String buildSubStreamKey(InviteSessionType type, String deviceId, String channelId, boolean isSubStream, String stream) {
|
||||
String key = type + "_" + (isSubStream ? "sub":"main") + "_" + deviceId + "_" + channelId;
|
||||
private String buildSubStreamKey(InviteSessionType type, String deviceId, String channelId, String stream) {
|
||||
String key = type + "_" + "_" + deviceId + "_" + channelId;
|
||||
// 如果ssrc为null那么可以实现一个通道只能一次操作,ssrc不为null则可以支持一个通道多次invite
|
||||
if (stream != null) {
|
||||
key += ("_" + stream);
|
||||
}
|
||||
return key;
|
||||
}
|
||||
@Override
|
||||
public void updateInviteInfoSub(InviteInfo inviteInfo) {
|
||||
if (inviteInfo == null || (inviteInfo.getDeviceId() == null || inviteInfo.getChannelId() == null)) {
|
||||
logger.warn("[更新Invite信息],参数不全: {}", JSON.toJSON(inviteInfo));
|
||||
return;
|
||||
}
|
||||
InviteInfo inviteInfoForUpdate = null;
|
||||
|
||||
if (InviteSessionStatus.ready == inviteInfo.getStatus()) {
|
||||
if (inviteInfo.getDeviceId() == null
|
||||
|| inviteInfo.getChannelId() == null
|
||||
|| inviteInfo.getType() == null
|
||||
|| inviteInfo.getStream() == null
|
||||
) {
|
||||
return;
|
||||
}
|
||||
inviteInfoForUpdate = inviteInfo;
|
||||
} else {
|
||||
InviteInfo inviteInfoInRedis = getInviteInfo(inviteInfo.getType(), inviteInfo.getDeviceId(),
|
||||
inviteInfo.getChannelId(),inviteInfo.isSubStream(), inviteInfo.getStream());
|
||||
if (inviteInfoInRedis == null) {
|
||||
logger.warn("[更新Invite信息],未从缓存中读取到Invite信息: deviceId: {}, channel: {}, stream: {}",
|
||||
inviteInfo.getDeviceId(), inviteInfo.getChannelId(), inviteInfo.getStream());
|
||||
return;
|
||||
}
|
||||
if (inviteInfo.getStreamInfo() != null) {
|
||||
inviteInfoInRedis.setStreamInfo(inviteInfo.getStreamInfo());
|
||||
}
|
||||
if (inviteInfo.getSsrcInfo() != null) {
|
||||
inviteInfoInRedis.setSsrcInfo(inviteInfo.getSsrcInfo());
|
||||
}
|
||||
if (inviteInfo.getStreamMode() != null) {
|
||||
inviteInfoInRedis.setStreamMode(inviteInfo.getStreamMode());
|
||||
}
|
||||
if (inviteInfo.getReceiveIp() != null) {
|
||||
inviteInfoInRedis.setReceiveIp(inviteInfo.getReceiveIp());
|
||||
}
|
||||
if (inviteInfo.getReceivePort() != null) {
|
||||
inviteInfoInRedis.setReceivePort(inviteInfo.getReceivePort());
|
||||
}
|
||||
if (inviteInfo.getStatus() != null) {
|
||||
inviteInfoInRedis.setStatus(inviteInfo.getStatus());
|
||||
}
|
||||
|
||||
inviteInfoForUpdate = inviteInfoInRedis;
|
||||
|
||||
}
|
||||
String key = VideoManagerConstants.INVITE_PREFIX +
|
||||
"_" + inviteInfoForUpdate.getType() +
|
||||
"_" + (inviteInfoForUpdate.isSubStream() ? "sub":"main") +
|
||||
"_" + inviteInfoForUpdate.getDeviceId() +
|
||||
"_" + inviteInfoForUpdate.getChannelId() +
|
||||
"_" + inviteInfoForUpdate.getStream();
|
||||
redisTemplate.opsForValue().set(key, inviteInfoForUpdate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InviteInfo getInviteInfoByStream(InviteSessionType type, String stream, boolean isSubStream) {
|
||||
return getInviteInfo(type, null, null,isSubStream, stream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Object> getInviteInfos(InviteSessionType type, String deviceId, String channelId, String stream) {
|
||||
String key = VideoManagerConstants.INVITE_PREFIX +
|
||||
"_" + (type != null ? type : "*") +
|
||||
"_" + (deviceId != null ? deviceId : "*") +
|
||||
"_" + (channelId != null ? channelId : "*") +
|
||||
"_" + (stream != null ? stream : "*");
|
||||
List<Object> scanResult = RedisUtil.scan(redisTemplate, key);
|
||||
return scanResult;
|
||||
}
|
||||
|
||||
/*======================设备主子码流逻辑END=========================*/
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -116,43 +116,27 @@ public class PlayServiceImpl implements IPlayService {
|
|||
|
||||
|
||||
@Override
|
||||
public SSRCInfo play(MediaServerItem mediaServerItem, String deviceId, String channelId,boolean isSubStream, ErrorCallback<Object> callback) {
|
||||
public SSRCInfo play(MediaServerItem mediaServerItem, String deviceId, String channelId, ErrorCallback<Object> callback) {
|
||||
if (mediaServerItem == null) {
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "未找到可用的zlm");
|
||||
}
|
||||
|
||||
Device device = redisCatchStorage.getDevice(deviceId);
|
||||
InviteInfo inviteInfo;
|
||||
if(device.isSwitchPrimarySubStream()){
|
||||
inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId,isSubStream);
|
||||
}else {
|
||||
inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId);
|
||||
}
|
||||
InviteInfo inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId);
|
||||
if (inviteInfo != null ) {
|
||||
if (inviteInfo.getStreamInfo() == null) {
|
||||
// 点播发起了但是尚未成功, 仅注册回调等待结果即可
|
||||
if(device.isSwitchPrimarySubStream()){
|
||||
inviteStreamService.once(InviteSessionType.PLAY, deviceId, channelId,isSubStream, null, callback);
|
||||
}else {
|
||||
inviteStreamService.once(InviteSessionType.PLAY, deviceId, channelId, null, callback);
|
||||
}
|
||||
inviteStreamService.once(InviteSessionType.PLAY, deviceId, channelId, null, callback);
|
||||
return inviteInfo.getSsrcInfo();
|
||||
}else {
|
||||
StreamInfo streamInfo = inviteInfo.getStreamInfo();
|
||||
String streamId = streamInfo.getStream();
|
||||
if (streamId == null) {
|
||||
callback.run(InviteErrorCode.ERROR_FOR_CATCH_DATA.getCode(), "点播失败, redis缓存streamId等于null", null);
|
||||
if(device.isSwitchPrimarySubStream()){
|
||||
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId,isSubStream, null,
|
||||
InviteErrorCode.ERROR_FOR_CATCH_DATA.getCode(),
|
||||
"点播失败, redis缓存streamId等于null",
|
||||
null);
|
||||
}else {
|
||||
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
||||
InviteErrorCode.ERROR_FOR_CATCH_DATA.getCode(),
|
||||
"点播失败, redis缓存streamId等于null",
|
||||
null);
|
||||
}
|
||||
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
||||
InviteErrorCode.ERROR_FOR_CATCH_DATA.getCode(),
|
||||
"点播失败, redis缓存streamId等于null",
|
||||
null);
|
||||
return inviteInfo.getSsrcInfo();
|
||||
}
|
||||
String mediaServerId = streamInfo.getMediaServerId();
|
||||
|
@ -161,64 +145,38 @@ public class PlayServiceImpl implements IPlayService {
|
|||
Boolean ready = zlmrtpServerFactory.isStreamReady(mediaInfo, "rtp", streamId);
|
||||
if (ready != null && ready) {
|
||||
callback.run(InviteErrorCode.SUCCESS.getCode(), InviteErrorCode.SUCCESS.getMsg(), streamInfo);
|
||||
if(device.isSwitchPrimarySubStream()){
|
||||
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId,isSubStream, null,
|
||||
InviteErrorCode.SUCCESS.getCode(),
|
||||
InviteErrorCode.SUCCESS.getMsg(),
|
||||
streamInfo);
|
||||
}else {
|
||||
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
||||
InviteErrorCode.SUCCESS.getCode(),
|
||||
InviteErrorCode.SUCCESS.getMsg(),
|
||||
streamInfo);
|
||||
}
|
||||
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
||||
InviteErrorCode.SUCCESS.getCode(),
|
||||
InviteErrorCode.SUCCESS.getMsg(),
|
||||
streamInfo);
|
||||
return inviteInfo.getSsrcInfo();
|
||||
}else {
|
||||
// 点播发起了但是尚未成功, 仅注册回调等待结果即可
|
||||
if(device.isSwitchPrimarySubStream()) {
|
||||
inviteStreamService.once(InviteSessionType.PLAY, deviceId, channelId, null, callback);
|
||||
storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId());
|
||||
inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId);
|
||||
}else {
|
||||
inviteStreamService.once(InviteSessionType.PLAY, deviceId, channelId,isSubStream, null, callback);
|
||||
inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId,isSubStream);
|
||||
}
|
||||
inviteStreamService.once(InviteSessionType.PLAY, deviceId, channelId, null, callback);
|
||||
storager.stopPlay(streamInfo.getDeviceID(), streamInfo.getChannelId());
|
||||
inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String streamId = null;
|
||||
if (mediaServerItem.isRtpEnable()) {
|
||||
if(device.isSwitchPrimarySubStream()){
|
||||
streamId = StreamInfo.getPlayStream(deviceId, channelId, isSubStream);
|
||||
}else {
|
||||
streamId = String.format("%s_%s", device.getDeviceId(), channelId);
|
||||
}
|
||||
}
|
||||
String streamId = String.format("%s_%s", device.getDeviceId(), channelId);
|
||||
SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaServerItem, streamId, null, device.isSsrcCheck(), false, 0, false, device.getStreamModeForParam());
|
||||
if (ssrcInfo == null) {
|
||||
callback.run(InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(), InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getMsg(), null);
|
||||
if(device.isSwitchPrimarySubStream()){
|
||||
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId,isSubStream, null,
|
||||
InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(),
|
||||
InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getMsg(),
|
||||
null);
|
||||
}else {
|
||||
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
||||
InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(),
|
||||
InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getMsg(),
|
||||
null);
|
||||
}
|
||||
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
||||
InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(),
|
||||
InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getMsg(),
|
||||
null);
|
||||
return null;
|
||||
}
|
||||
// TODO 记录点播的状态
|
||||
play(mediaServerItem, ssrcInfo, device, channelId,isSubStream, callback);
|
||||
play(mediaServerItem, ssrcInfo, device, channelId, callback);
|
||||
return ssrcInfo;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void play(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId,boolean isSubStream,
|
||||
public void play(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, Device device, String channelId,
|
||||
ErrorCallback<Object> callback) {
|
||||
|
||||
if (mediaServerItem == null || ssrcInfo == null) {
|
||||
|
@ -227,11 +185,9 @@ public class PlayServiceImpl implements IPlayService {
|
|||
null);
|
||||
return;
|
||||
}
|
||||
if( device.isSwitchPrimarySubStream() ){
|
||||
logger.info("[点播开始] deviceId: {}, channelId: {},码流类型:{},收流端口: {}, 收流模式:{}, SSRC: {}, SSRC校验:{}", device.getDeviceId(), channelId,isSubStream ? "辅码流" : "主码流", ssrcInfo.getPort(), device.getStreamMode(), ssrcInfo.getSsrc(), device.isSsrcCheck());
|
||||
}else {
|
||||
logger.info("[点播开始] deviceId: {}, channelId: {},收流端口: {}, 收流模式:{}, SSRC: {}, SSRC校验:{}", device.getDeviceId(), channelId, ssrcInfo.getPort(), device.getStreamMode(), ssrcInfo.getSsrc(), device.isSsrcCheck());
|
||||
}
|
||||
logger.info("[点播开始] deviceId: {}, channelId: {},码流类型:{},收流端口: {}, 收流模式:{}, SSRC: {}, SSRC校验:{}",
|
||||
device.getDeviceId(), channelId, device.isSwitchPrimarySubStream() ? "辅码流" : "主码流", ssrcInfo.getPort(),
|
||||
device.getStreamMode(), ssrcInfo.getSsrc(), device.isSsrcCheck());
|
||||
//端口获取失败的ssrcInfo 没有必要发送点播指令
|
||||
if (ssrcInfo.getPort() <= 0) {
|
||||
logger.info("[点播端口分配异常],deviceId={},channelId={},ssrcInfo={}", device.getDeviceId(), channelId, ssrcInfo);
|
||||
|
@ -240,50 +196,27 @@ public class PlayServiceImpl implements IPlayService {
|
|||
streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream());
|
||||
|
||||
callback.run(InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(), "点播端口分配异常", null);
|
||||
if(device.isSwitchPrimarySubStream()){
|
||||
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId,isSubStream, null,
|
||||
InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(), "点播端口分配异常", null);
|
||||
}else {
|
||||
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
||||
InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(), "点播端口分配异常", null);
|
||||
}
|
||||
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
||||
InviteErrorCode.ERROR_FOR_RESOURCE_EXHAUSTION.getCode(), "点播端口分配异常", null);
|
||||
return;
|
||||
}
|
||||
|
||||
// 初始化redis中的invite消息状态
|
||||
InviteInfo inviteInfo;
|
||||
|
||||
if(device.isSwitchPrimarySubStream()){
|
||||
// 初始化redis中的invite消息状态
|
||||
inviteInfo = InviteInfo.getInviteInfo(device.getDeviceId(), channelId,isSubStream, ssrcInfo.getStream(), ssrcInfo,
|
||||
mediaServerItem.getSdpIp(), ssrcInfo.getPort(), device.getStreamMode(), InviteSessionType.PLAY,
|
||||
InviteSessionStatus.ready);
|
||||
inviteStreamService.updateInviteInfoSub(inviteInfo);
|
||||
}else {
|
||||
// 初始化redis中的invite消息状态
|
||||
inviteInfo = InviteInfo.getinviteInfo(device.getDeviceId(), channelId, ssrcInfo.getStream(), ssrcInfo,
|
||||
mediaServerItem.getSdpIp(), ssrcInfo.getPort(), device.getStreamMode(), InviteSessionType.PLAY,
|
||||
InviteSessionStatus.ready);
|
||||
inviteStreamService.updateInviteInfo(inviteInfo);
|
||||
}
|
||||
InviteInfo inviteInfo = InviteInfo.getInviteInfo(device.getDeviceId(), channelId, ssrcInfo.getStream(), ssrcInfo,
|
||||
mediaServerItem.getSdpIp(), ssrcInfo.getPort(), device.getStreamMode(), InviteSessionType.PLAY,
|
||||
InviteSessionStatus.ready);
|
||||
inviteInfo.setSubStream(device.isSwitchPrimarySubStream());
|
||||
inviteStreamService.updateInviteInfo(inviteInfo);
|
||||
// 超时处理
|
||||
String timeOutTaskKey = UUID.randomUUID().toString();
|
||||
dynamicTask.startDelay(timeOutTaskKey, () -> {
|
||||
// 执行超时任务时查询是否已经成功,成功了则不执行超时任务,防止超时任务取消失败的情况
|
||||
InviteInfo inviteInfoForTimeOut;
|
||||
if(device.isSwitchPrimarySubStream()){
|
||||
// 初始化redis中的invite消息状态
|
||||
inviteInfoForTimeOut = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId,isSubStream);
|
||||
}else {
|
||||
// 初始化redis中的invite消息状态
|
||||
inviteInfoForTimeOut = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId);
|
||||
}
|
||||
InviteInfo inviteInfoForTimeOut = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId);
|
||||
if (inviteInfoForTimeOut == null || inviteInfoForTimeOut.getStreamInfo() == null) {
|
||||
if( device.isSwitchPrimarySubStream()){
|
||||
logger.info("[点播超时] 收流超时 deviceId: {}, channelId: {},码流类型:{},端口:{}, SSRC: {}", device.getDeviceId(), channelId,isSubStream ? "辅码流" : "主码流", ssrcInfo.getPort(), ssrcInfo.getSsrc());
|
||||
}else {
|
||||
logger.info("[点播超时] 收流超时 deviceId: {}, channelId: {},端口:{}, SSRC: {}", device.getDeviceId(), channelId, ssrcInfo.getPort(), ssrcInfo.getSsrc());
|
||||
}
|
||||
logger.info("[点播超时] 收流超时 deviceId: {}, channelId: {},码流类型:{},端口:{}, SSRC: {}",
|
||||
device.getDeviceId(), channelId, device.isSwitchPrimarySubStream() ? "辅码流" : "主码流",
|
||||
ssrcInfo.getPort(), ssrcInfo.getSsrc());
|
||||
|
||||
// 点播超时回复BYE 同时释放ssrc以及此次点播的资源
|
||||
// InviteInfo inviteInfoForTimeout = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.play, device.getDeviceId(), channelId);
|
||||
// if (inviteInfoForTimeout == null) {
|
||||
|
@ -295,16 +228,10 @@ public class PlayServiceImpl implements IPlayService {
|
|||
// // TODO 发送cancel
|
||||
// }
|
||||
callback.run(InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getCode(), InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getMsg(), null);
|
||||
if( device.isSwitchPrimarySubStream()){
|
||||
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId,isSubStream, null,
|
||||
InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getCode(), InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getMsg(), null);
|
||||
inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId,isSubStream);
|
||||
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
||||
InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getCode(), InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getMsg(), null);
|
||||
inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId);
|
||||
|
||||
}else {
|
||||
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
||||
InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getCode(), InviteErrorCode.ERROR_FOR_STREAM_TIMEOUT.getMsg(), null);
|
||||
inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId);
|
||||
}
|
||||
try {
|
||||
cmder.streamByeCmd(device, channelId, ssrcInfo.getStream(), null);
|
||||
} catch (InvalidArgumentException | ParseException | SipException | SsrcTransactionNotFoundException e) {
|
||||
|
@ -322,42 +249,26 @@ public class PlayServiceImpl implements IPlayService {
|
|||
}, userSetting.getPlayTimeout());
|
||||
|
||||
try {
|
||||
cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId,isSubStream, (mediaServerItemInuse, hookParam ) -> {
|
||||
cmder.playStreamCmd(mediaServerItem, ssrcInfo, device, channelId, (mediaServerItemInuse, hookParam ) -> {
|
||||
logger.info("收到订阅消息: " + hookParam);
|
||||
dynamicTask.stop(timeOutTaskKey);
|
||||
// hook响应
|
||||
StreamInfo streamInfo = onPublishHandlerForPlay(mediaServerItemInuse, hookParam, device.getDeviceId(), channelId,isSubStream);
|
||||
StreamInfo streamInfo = onPublishHandlerForPlay(mediaServerItemInuse, hookParam, device.getDeviceId(), channelId);
|
||||
if (streamInfo == null){
|
||||
callback.run(InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getCode(),
|
||||
InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getMsg(), null);
|
||||
if( device.isSwitchPrimarySubStream()){
|
||||
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId,isSubStream, null,
|
||||
InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getCode(),
|
||||
InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getMsg(), null);
|
||||
}else {
|
||||
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
||||
InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getCode(),
|
||||
InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getMsg(), null);
|
||||
}
|
||||
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
||||
InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getCode(),
|
||||
InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getMsg(), null);
|
||||
return;
|
||||
}
|
||||
callback.run(InviteErrorCode.SUCCESS.getCode(), InviteErrorCode.SUCCESS.getMsg(), streamInfo);
|
||||
if( device.isSwitchPrimarySubStream()){
|
||||
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId,isSubStream, null,
|
||||
InviteErrorCode.SUCCESS.getCode(),
|
||||
InviteErrorCode.SUCCESS.getMsg(),
|
||||
streamInfo);
|
||||
}else {
|
||||
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
||||
InviteErrorCode.SUCCESS.getCode(),
|
||||
InviteErrorCode.SUCCESS.getMsg(),
|
||||
streamInfo);
|
||||
}
|
||||
if( device.isSwitchPrimarySubStream() ){
|
||||
logger.info("[点播成功] deviceId: {}, channelId: {},码流类型:{}", device.getDeviceId(), channelId,isSubStream ? "辅码流" : "主码流");
|
||||
}else {
|
||||
logger.info("[点播成功] deviceId: {}, channelId: {}", device.getDeviceId(), channelId);
|
||||
}
|
||||
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
||||
InviteErrorCode.SUCCESS.getCode(),
|
||||
InviteErrorCode.SUCCESS.getMsg(),
|
||||
streamInfo);
|
||||
logger.info("[点播成功] deviceId: {}, channelId: {},码流类型:{}", device.getDeviceId(),
|
||||
device.isSwitchPrimarySubStream() ? "辅码流" : "主码流");
|
||||
String streamUrl;
|
||||
if (mediaServerItemInuse.getRtspPort() != 0) {
|
||||
streamUrl = String.format("rtsp://127.0.0.1:%s/%s/%s", mediaServerItemInuse.getRtspPort(), "rtp", ssrcInfo.getStream());
|
||||
|
@ -413,15 +324,9 @@ public class PlayServiceImpl implements IPlayService {
|
|||
|
||||
callback.run(InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getCode(),
|
||||
InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getMsg(), null);
|
||||
if(device.isSwitchPrimarySubStream()){
|
||||
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId,isSubStream, null,
|
||||
InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getCode(),
|
||||
InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getMsg(), null);
|
||||
}else {
|
||||
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
||||
InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getCode(),
|
||||
InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getMsg(), null);
|
||||
}
|
||||
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
||||
InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getCode(),
|
||||
InviteErrorCode.ERROR_FOR_SDP_PARSING_EXCEPTIONS.getMsg(), null);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
@ -438,39 +343,26 @@ public class PlayServiceImpl implements IPlayService {
|
|||
subscribe.removeSubscribe(hookSubscribe);
|
||||
String stream = String.format("%08x", Integer.parseInt(ssrcInResponse)).toUpperCase();
|
||||
hookSubscribe.getContent().put("stream", stream);
|
||||
inviteInfo.setStream(stream);
|
||||
inviteStreamService.updateInviteInfoForStream(inviteInfo, stream);
|
||||
subscribe.addSubscribe(hookSubscribe, (mediaServerItemInUse, hookParam) -> {
|
||||
logger.info("[ZLM HOOK] ssrc修正后收到订阅消息: " + hookParam);
|
||||
dynamicTask.stop(timeOutTaskKey);
|
||||
// hook响应
|
||||
StreamInfo streamInfo = onPublishHandlerForPlay(mediaServerItemInUse, hookParam, device.getDeviceId(), channelId,isSubStream);
|
||||
StreamInfo streamInfo = onPublishHandlerForPlay(mediaServerItemInUse, hookParam, device.getDeviceId(), channelId);
|
||||
if (streamInfo == null){
|
||||
callback.run(InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getCode(),
|
||||
InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getMsg(), null);
|
||||
if( device.isSwitchPrimarySubStream()){
|
||||
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId,isSubStream, null,
|
||||
InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getCode(),
|
||||
InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getMsg(), null);
|
||||
}else {
|
||||
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
||||
InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getCode(),
|
||||
InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getMsg(), null);
|
||||
}
|
||||
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
||||
InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getCode(),
|
||||
InviteErrorCode.ERROR_FOR_STREAM_PARSING_EXCEPTIONS.getMsg(), null);
|
||||
return;
|
||||
}
|
||||
callback.run(InviteErrorCode.SUCCESS.getCode(),
|
||||
InviteErrorCode.SUCCESS.getMsg(), streamInfo);
|
||||
if( device.isSwitchPrimarySubStream()){
|
||||
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId,isSubStream, null,
|
||||
InviteErrorCode.SUCCESS.getCode(),
|
||||
InviteErrorCode.SUCCESS.getMsg(),
|
||||
streamInfo);
|
||||
}else {
|
||||
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
||||
InviteErrorCode.SUCCESS.getCode(),
|
||||
InviteErrorCode.SUCCESS.getMsg(),
|
||||
streamInfo);
|
||||
}
|
||||
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
||||
InviteErrorCode.SUCCESS.getCode(),
|
||||
InviteErrorCode.SUCCESS.getMsg(),
|
||||
streamInfo);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
@ -493,17 +385,14 @@ public class PlayServiceImpl implements IPlayService {
|
|||
|
||||
callback.run(InviteErrorCode.ERROR_FOR_RESET_SSRC.getCode(),
|
||||
"下级自定义了ssrc,重新设置收流信息失败", null);
|
||||
if( device.isSwitchPrimarySubStream()){
|
||||
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId,isSubStream, null,
|
||||
InviteErrorCode.ERROR_FOR_RESET_SSRC.getCode(),
|
||||
"下级自定义了ssrc,重新设置收流信息失败", null);
|
||||
}else {
|
||||
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
||||
InviteErrorCode.ERROR_FOR_RESET_SSRC.getCode(),
|
||||
"下级自定义了ssrc,重新设置收流信息失败", null);
|
||||
}
|
||||
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
||||
InviteErrorCode.ERROR_FOR_RESET_SSRC.getCode(),
|
||||
"下级自定义了ssrc,重新设置收流信息失败", null);
|
||||
|
||||
}else {
|
||||
if (ssrcInfo.getStream()!= null && !ssrcInfo.getStream().equals(inviteInfo.getStream())) {
|
||||
inviteStreamService.removeInviteInfo(inviteInfo);
|
||||
}
|
||||
ssrcInfo.setSsrc(ssrcInResponse);
|
||||
inviteInfo.setSsrcInfo(ssrcInfo);
|
||||
inviteInfo.setStream(ssrcInfo.getStream());
|
||||
|
@ -512,11 +401,7 @@ public class PlayServiceImpl implements IPlayService {
|
|||
logger.info("[点播消息] 收到invite 200, 下级自定义了ssrc, 但是当前模式无需修正");
|
||||
}
|
||||
}
|
||||
if(device.isSwitchPrimarySubStream()){
|
||||
inviteStreamService.updateInviteInfoSub(inviteInfo);
|
||||
}else {
|
||||
inviteStreamService.updateInviteInfo(inviteInfo);
|
||||
}
|
||||
inviteStreamService.updateInviteInfo(inviteInfo);
|
||||
}, (event) -> {
|
||||
dynamicTask.stop(timeOutTaskKey);
|
||||
mediaServerService.closeRTPServer(mediaServerItem, ssrcInfo.getStream());
|
||||
|
@ -527,19 +412,11 @@ public class PlayServiceImpl implements IPlayService {
|
|||
|
||||
callback.run(InviteErrorCode.ERROR_FOR_SIGNALLING_ERROR.getCode(),
|
||||
String.format("点播失败, 错误码: %s, %s", event.statusCode, event.msg), null);
|
||||
if( device.isSwitchPrimarySubStream()){
|
||||
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId,isSubStream, null,
|
||||
InviteErrorCode.ERROR_FOR_RESET_SSRC.getCode(),
|
||||
String.format("点播失败, 错误码: %s, %s", event.statusCode, event.msg), null);
|
||||
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
||||
InviteErrorCode.ERROR_FOR_RESET_SSRC.getCode(),
|
||||
String.format("点播失败, 错误码: %s, %s", event.statusCode, event.msg), null);
|
||||
|
||||
inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId,isSubStream);
|
||||
}else {
|
||||
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
||||
InviteErrorCode.ERROR_FOR_RESET_SSRC.getCode(),
|
||||
String.format("点播失败, 错误码: %s, %s", event.statusCode, event.msg), null);
|
||||
|
||||
inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId);
|
||||
}
|
||||
inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId);
|
||||
});
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
|
||||
|
@ -553,52 +430,30 @@ public class PlayServiceImpl implements IPlayService {
|
|||
|
||||
callback.run(InviteErrorCode.ERROR_FOR_SIP_SENDING_FAILED.getCode(),
|
||||
InviteErrorCode.ERROR_FOR_SIP_SENDING_FAILED.getMsg(), null);
|
||||
if( device.isSwitchPrimarySubStream()){
|
||||
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId,isSubStream, null,
|
||||
InviteErrorCode.ERROR_FOR_SIP_SENDING_FAILED.getCode(),
|
||||
InviteErrorCode.ERROR_FOR_SIP_SENDING_FAILED.getMsg(), null);
|
||||
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
||||
InviteErrorCode.ERROR_FOR_SIP_SENDING_FAILED.getCode(),
|
||||
InviteErrorCode.ERROR_FOR_SIP_SENDING_FAILED.getMsg(), null);
|
||||
|
||||
inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId,isSubStream);
|
||||
}else {
|
||||
inviteStreamService.call(InviteSessionType.PLAY, device.getDeviceId(), channelId, null,
|
||||
InviteErrorCode.ERROR_FOR_SIP_SENDING_FAILED.getCode(),
|
||||
InviteErrorCode.ERROR_FOR_SIP_SENDING_FAILED.getMsg(), null);
|
||||
|
||||
inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId);
|
||||
}
|
||||
inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, device.getDeviceId(), channelId);
|
||||
}
|
||||
}
|
||||
|
||||
private StreamInfo onPublishHandlerForPlay(MediaServerItem mediaServerItem, HookParam hookParam, String deviceId, String channelId, boolean isSubStream) {
|
||||
private StreamInfo onPublishHandlerForPlay(MediaServerItem mediaServerItem, HookParam hookParam, String deviceId, String channelId) {
|
||||
StreamInfo streamInfo = null;
|
||||
Device device = redisCatchStorage.getDevice(deviceId);
|
||||
OnStreamChangedHookParam streamChangedHookParam = (OnStreamChangedHookParam)hookParam;
|
||||
if( device.isSwitchPrimarySubStream() ){
|
||||
streamInfo = onPublishHandler(mediaServerItem, streamChangedHookParam, deviceId, channelId,isSubStream);
|
||||
}else {
|
||||
streamInfo = onPublishHandler(mediaServerItem, streamChangedHookParam, deviceId, channelId);
|
||||
}
|
||||
streamInfo = onPublishHandler(mediaServerItem, streamChangedHookParam, deviceId, channelId);
|
||||
if (streamInfo != null) {
|
||||
InviteInfo inviteInfo;
|
||||
if(device.isSwitchPrimarySubStream()){
|
||||
inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId,isSubStream);
|
||||
}else {
|
||||
DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId);
|
||||
if (deviceChannel != null) {
|
||||
deviceChannel.setStreamId(streamInfo.getStream());
|
||||
storager.startPlay(deviceId, channelId, streamInfo.getStream());
|
||||
}
|
||||
inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId);
|
||||
DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId);
|
||||
if (deviceChannel != null) {
|
||||
deviceChannel.setStreamId(streamInfo.getStream());
|
||||
storager.startPlay(deviceId, channelId, streamInfo.getStream());
|
||||
}
|
||||
InviteInfo inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId);
|
||||
if (inviteInfo != null) {
|
||||
inviteInfo.setStatus(InviteSessionStatus.ok);
|
||||
inviteInfo.setStreamInfo(streamInfo);
|
||||
if(device.isSwitchPrimarySubStream()){
|
||||
inviteStreamService.updateInviteInfoSub(inviteInfo);
|
||||
}else {
|
||||
inviteStreamService.updateInviteInfo(inviteInfo);
|
||||
}
|
||||
|
||||
inviteStreamService.updateInviteInfo(inviteInfo);
|
||||
}
|
||||
}
|
||||
return streamInfo;
|
||||
|
@ -693,7 +548,7 @@ public class PlayServiceImpl implements IPlayService {
|
|||
device.getDeviceId(), channelId, startTime, endTime, ssrcInfo.getPort(), device.getStreamMode(),
|
||||
ssrcInfo.getSsrc(), device.isSsrcCheck());
|
||||
// 初始化redis中的invite消息状态
|
||||
InviteInfo inviteInfo = InviteInfo.getinviteInfo(device.getDeviceId(), channelId, ssrcInfo.getStream(), ssrcInfo,
|
||||
InviteInfo inviteInfo = InviteInfo.getInviteInfo(device.getDeviceId(), channelId, ssrcInfo.getStream(), ssrcInfo,
|
||||
mediaServerItem.getSdpIp(), ssrcInfo.getPort(), device.getStreamMode(), InviteSessionType.PLAYBACK,
|
||||
InviteSessionStatus.ready);
|
||||
inviteStreamService.updateInviteInfo(inviteInfo);
|
||||
|
@ -805,7 +660,7 @@ public class PlayServiceImpl implements IPlayService {
|
|||
subscribe.removeSubscribe(hookSubscribe);
|
||||
String stream = String.format("%08x", Integer.parseInt(ssrcInResponse)).toUpperCase();
|
||||
hookSubscribe.getContent().put("stream", stream);
|
||||
inviteInfo.setStream(stream);
|
||||
inviteStreamService.updateInviteInfoForStream(inviteInfo, stream);
|
||||
subscribe.addSubscribe(hookSubscribe, (mediaServerItemInUse, hookParam) -> {
|
||||
logger.info("[ZLM HOOK] ssrc修正后收到订阅消息: " + hookParam);
|
||||
dynamicTask.stop(playBackTimeOutTaskKey);
|
||||
|
@ -834,6 +689,10 @@ public class PlayServiceImpl implements IPlayService {
|
|||
"下级自定义了ssrc,重新设置收流信息失败", null);
|
||||
|
||||
}else {
|
||||
if (ssrcInfo.getStream()!= null && !ssrcInfo.getStream().equals(inviteInfo.getStream())) {
|
||||
inviteStreamService.removeInviteInfo(inviteInfo);
|
||||
}
|
||||
|
||||
ssrcInfo.setSsrc(ssrcInResponse);
|
||||
inviteInfo.setSsrcInfo(ssrcInfo);
|
||||
inviteInfo.setStream(ssrcInfo.getStream());
|
||||
|
@ -892,7 +751,7 @@ public class PlayServiceImpl implements IPlayService {
|
|||
}
|
||||
logger.info("[录像下载] deviceId: {}, channelId: {}, 下载速度:{}, 收流端口:{}, 收流模式:{}, SSRC: {}, SSRC校验:{}", device.getDeviceId(), channelId, downloadSpeed, ssrcInfo.getPort(), device.getStreamMode(), ssrcInfo.getSsrc(), device.isSsrcCheck());
|
||||
// 初始化redis中的invite消息状态
|
||||
InviteInfo inviteInfo = InviteInfo.getinviteInfo(device.getDeviceId(), channelId, ssrcInfo.getStream(), ssrcInfo,
|
||||
InviteInfo inviteInfo = InviteInfo.getInviteInfo(device.getDeviceId(), channelId, ssrcInfo.getStream(), ssrcInfo,
|
||||
mediaServerItem.getSdpIp(), ssrcInfo.getPort(), device.getStreamMode(), InviteSessionType.DOWNLOAD,
|
||||
InviteSessionStatus.ready);
|
||||
inviteStreamService.updateInviteInfo(inviteInfo);
|
||||
|
@ -998,7 +857,9 @@ public class PlayServiceImpl implements IPlayService {
|
|||
// 添加订阅
|
||||
HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", ssrcInfo.getStream(), true, "rtsp", mediaServerItem.getId());
|
||||
subscribe.removeSubscribe(hookSubscribe);
|
||||
hookSubscribe.getContent().put("stream", String.format("%08x", Integer.parseInt(ssrcInResponse)).toUpperCase());
|
||||
String stream = String.format("%08x", Integer.parseInt(ssrcInResponse)).toUpperCase();
|
||||
hookSubscribe.getContent().put("stream", stream);
|
||||
inviteStreamService.updateInviteInfoForStream(inviteInfo, stream);
|
||||
subscribe.addSubscribe(hookSubscribe, (mediaServerItemInUse, hookParam) -> {
|
||||
logger.info("[ZLM HOOK] ssrc修正后收到订阅消息: " + hookParam);
|
||||
dynamicTask.stop(downLoadTimeOutTaskKey);
|
||||
|
@ -1026,6 +887,9 @@ public class PlayServiceImpl implements IPlayService {
|
|||
"下级自定义了ssrc,重新设置收流信息失败", null);
|
||||
|
||||
}else {
|
||||
if (ssrcInfo.getStream()!= null && !ssrcInfo.getStream().equals(inviteInfo.getStream())) {
|
||||
inviteStreamService.removeInviteInfo(inviteInfo);
|
||||
}
|
||||
ssrcInfo.setSsrc(ssrcInResponse);
|
||||
inviteInfo.setSsrcInfo(ssrcInfo);
|
||||
inviteInfo.setStream(ssrcInfo.getStream());
|
||||
|
@ -1034,6 +898,7 @@ public class PlayServiceImpl implements IPlayService {
|
|||
logger.info("[录像下载] 收到invite 200, 下级自定义了ssrc, 但是当前模式无需修正");
|
||||
}
|
||||
}
|
||||
inviteStreamService.updateInviteInfo(inviteInfo);
|
||||
});
|
||||
} catch (InvalidArgumentException | SipException | ParseException e) {
|
||||
logger.error("[命令发送失败] 录像下载: {}", e.getMessage());
|
||||
|
@ -1255,18 +1120,13 @@ public class PlayServiceImpl implements IPlayService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void getSnap(String deviceId, String channelId, String fileName,boolean isSubStream, ErrorCallback errorCallback) {
|
||||
public void getSnap(String deviceId, String channelId, String fileName, ErrorCallback errorCallback) {
|
||||
Device device = deviceService.getDevice(deviceId);
|
||||
if (device == null) {
|
||||
errorCallback.run(InviteErrorCode.ERROR_FOR_PARAMETER_ERROR.getCode(), InviteErrorCode.ERROR_FOR_PARAMETER_ERROR.getMsg(), null);
|
||||
return;
|
||||
}
|
||||
InviteInfo inviteInfo;
|
||||
if(device.isSwitchPrimarySubStream()){
|
||||
inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId,isSubStream);
|
||||
}else {
|
||||
inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId);
|
||||
}
|
||||
InviteInfo inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId);
|
||||
if (inviteInfo != null) {
|
||||
if (inviteInfo.getStreamInfo() != null) {
|
||||
// 已存在线直接截图
|
||||
|
@ -1292,11 +1152,11 @@ public class PlayServiceImpl implements IPlayService {
|
|||
}
|
||||
|
||||
MediaServerItem newMediaServerItem = getNewMediaServerItem(device);
|
||||
play(newMediaServerItem, deviceId, channelId,isSubStream, (code, msg, data)->{
|
||||
play(newMediaServerItem, deviceId, channelId, (code, msg, data)->{
|
||||
if (code == InviteErrorCode.SUCCESS.getCode()) {
|
||||
InviteInfo inviteInfoForPlay = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId);
|
||||
if (inviteInfoForPlay != null && inviteInfoForPlay.getStreamInfo() != null) {
|
||||
getSnap(deviceId, channelId, fileName,isSubStream, errorCallback);
|
||||
getSnap(deviceId, channelId, fileName, errorCallback);
|
||||
}else {
|
||||
errorCallback.run(InviteErrorCode.FAIL.getCode(), InviteErrorCode.FAIL.getMsg(), null);
|
||||
}
|
||||
|
@ -1306,17 +1166,4 @@ public class PlayServiceImpl implements IPlayService {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
/*======================设备主子码流逻辑START=========================*/
|
||||
public StreamInfo onPublishHandler(MediaServerItem mediaServerItem, OnStreamChangedHookParam hookParam, String deviceId, String channelId,boolean isSubStream) {
|
||||
String streamId = hookParam.getStream();
|
||||
List<OnStreamChangedHookParam.MediaTrack> tracks = hookParam.getTracks();
|
||||
StreamInfo streamInfo = mediaService.getStreamInfoByAppAndStream(mediaServerItem, "rtp", streamId, tracks, null);
|
||||
streamInfo.setDeviceID(deviceId);
|
||||
streamInfo.setChannelId(channelId);
|
||||
streamInfo.setSubStream(isSubStream);
|
||||
return streamInfo;
|
||||
}
|
||||
/*======================设备主子码流逻辑END=========================*/
|
||||
|
||||
}
|
||||
|
|
|
@ -70,7 +70,6 @@ public class UserServiceImpl implements IUserService {
|
|||
continue;
|
||||
}
|
||||
String checkStr = callId == null? user.getPushKey():(callId + "_" + user.getPushKey()) ;
|
||||
System.out.println(checkStr);
|
||||
String checkSign = DigestUtils.md5DigestAsHex(checkStr.getBytes());
|
||||
if (checkSign.equals(sign)) {
|
||||
return true;
|
||||
|
|
|
@ -88,17 +88,16 @@ public class PlayController {
|
|||
@Operation(summary = "开始点播")
|
||||
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
||||
@Parameter(name = "channelId", description = "通道国标编号", required = true)
|
||||
@Parameter(name = "isSubStream", description = "是否子码流(true-子码流,false-主码流),默认为false", required = true)
|
||||
@GetMapping("/start/{deviceId}/{channelId}")
|
||||
public DeferredResult<WVPResult<StreamContent>> play(HttpServletRequest request, @PathVariable String deviceId,
|
||||
@PathVariable String channelId,boolean isSubStream) {
|
||||
@PathVariable String channelId) {
|
||||
|
||||
// 获取可用的zlm
|
||||
Device device = storager.queryVideoDevice(deviceId);
|
||||
MediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device);
|
||||
|
||||
RequestMessage requestMessage = new RequestMessage();
|
||||
String key = DeferredResultHolder.getPlayKey(deviceId,channelId,device.isSwitchPrimarySubStream(),isSubStream);
|
||||
String key = DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId;
|
||||
requestMessage.setKey(key);
|
||||
String uuid = UUID.randomUUID().toString();
|
||||
requestMessage.setId(uuid);
|
||||
|
@ -117,7 +116,7 @@ public class PlayController {
|
|||
// 录像查询以channelId作为deviceId查询
|
||||
resultHolder.put(key, uuid, result);
|
||||
|
||||
playService.play(newMediaServerItem, deviceId, channelId,isSubStream, (code, msg, data) -> {
|
||||
playService.play(newMediaServerItem, deviceId, channelId, (code, msg, data) -> {
|
||||
WVPResult<StreamContent> wvpResult = new WVPResult<>();
|
||||
if (code == InviteErrorCode.SUCCESS.getCode()) {
|
||||
wvpResult.setCode(ErrorCode.SUCCESS.getCode());
|
||||
|
@ -158,12 +157,7 @@ public class PlayController {
|
|||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "设备[" + deviceId + "]不存在");
|
||||
}
|
||||
|
||||
InviteInfo inviteInfo =null;
|
||||
if(device.isSwitchPrimarySubStream()){
|
||||
inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId,isSubStream);
|
||||
}else {
|
||||
inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId);
|
||||
}
|
||||
InviteInfo inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId);
|
||||
if (inviteInfo == null) {
|
||||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "点播未找到");
|
||||
}
|
||||
|
@ -176,12 +170,8 @@ public class PlayController {
|
|||
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
if(device.isSwitchPrimarySubStream()){
|
||||
inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId,isSubStream);
|
||||
}else {
|
||||
inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId);
|
||||
storager.stopPlay(deviceId, channelId);
|
||||
}
|
||||
inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId);
|
||||
storager.stopPlay(deviceId, channelId);
|
||||
|
||||
JSONObject json = new JSONObject();
|
||||
json.put("deviceId", deviceId);
|
||||
|
@ -360,9 +350,8 @@ public class PlayController {
|
|||
logger.debug("获取截图: {}/{}", deviceId, channelId);
|
||||
}
|
||||
|
||||
Device device = storager.queryVideoDevice(deviceId);
|
||||
DeferredResult<String> result = new DeferredResult<>(3 * 1000L);
|
||||
String key = DeferredResultHolder.getSnapKey(deviceId,channelId,device.isSwitchPrimarySubStream(),isSubStream);
|
||||
String key = DeferredResultHolder.CALLBACK_CMD_SNAP + deviceId;
|
||||
String uuid = UUID.randomUUID().toString();
|
||||
resultHolder.put(key, uuid, result);
|
||||
|
||||
|
@ -371,7 +360,7 @@ public class PlayController {
|
|||
message.setId(uuid);
|
||||
|
||||
String fileName = deviceId + "_" + channelId + "_" + DateUtil.getNowForUrl() + "jpg";
|
||||
playService.getSnap(deviceId, channelId, fileName,isSubStream, (code, msg, data) -> {
|
||||
playService.getSnap(deviceId, channelId, fileName, (code, msg, data) -> {
|
||||
if (code == InviteErrorCode.SUCCESS.getCode()) {
|
||||
message.setData(data);
|
||||
}else {
|
||||
|
|
|
@ -122,7 +122,7 @@ public class ApiStreamController {
|
|||
MediaServerItem newMediaServerItem = playService.getNewMediaServerItem(device);
|
||||
|
||||
|
||||
playService.play(newMediaServerItem, serial, code,false, (errorCode, msg, data) -> {
|
||||
playService.play(newMediaServerItem, serial, code, (errorCode, msg, data) -> {
|
||||
if (errorCode == InviteErrorCode.SUCCESS.getCode()) {
|
||||
InviteInfo inviteInfo = inviteStreamService.getInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, serial, code);
|
||||
if (inviteInfo != null && inviteInfo.getStreamInfo() != null) {
|
||||
|
|
Loading…
Reference in New Issue