Merge branch 'wvp-28181-2.0' into main-dev
# Conflicts: # src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java # src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/AckRequestProcessor.java # src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/InviteRequestProcessor.java # src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMServerFactory.java # src/main/java/com/genersoft/iot/vmp/service/impl/MediaServerServiceImpl.java # src/main/java/com/genersoft/iot/vmp/service/impl/PlatformServiceImpl.java # src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java # src/main/java/com/genersoft/iot/vmp/service/redisMsg/RedisPushStreamCloseResponseListener.java # src/main/java/com/genersoft/iot/vmp/vmanager/rtp/RtpController.java
This commit is contained in:
@@ -1,13 +1,20 @@
|
||||
package com.genersoft.iot.vmp.media.zlm;
|
||||
|
||||
import com.genersoft.iot.vmp.common.VideoManagerConstants;
|
||||
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
|
||||
import com.genersoft.iot.vmp.media.zlm.dto.MediaSendRtpPortInfo;
|
||||
import com.genersoft.iot.vmp.utils.redis.RedisUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
public class SendRtpPortManager {
|
||||
|
||||
@@ -29,27 +36,55 @@ public class SendRtpPortManager {
|
||||
}
|
||||
|
||||
public int getNextPort(String mediaServerId) {
|
||||
String key = KEY + userSetting.getServerId() + "_" + mediaServerId;
|
||||
MediaSendRtpPortInfo mediaSendRtpPortInfo = (MediaSendRtpPortInfo)redisTemplate.opsForValue().get(key);
|
||||
String sendIndexKey = KEY + userSetting.getServerId() + "_" + mediaServerId;
|
||||
MediaSendRtpPortInfo mediaSendRtpPortInfo = (MediaSendRtpPortInfo)redisTemplate.opsForValue().get(sendIndexKey);
|
||||
if (mediaSendRtpPortInfo == null) {
|
||||
logger.warn("[发送端口管理] 获取{}的发送端口时未找到端口信息", mediaSendRtpPortInfo);
|
||||
logger.warn("[发送端口管理] 获取{}的发送端口时未找到端口信息", mediaServerId);
|
||||
return 0;
|
||||
}
|
||||
int port;
|
||||
if (mediaSendRtpPortInfo.getCurrent() %2 != 0) {
|
||||
port = mediaSendRtpPortInfo.getCurrent() + 1;
|
||||
}else {
|
||||
port = mediaSendRtpPortInfo.getCurrent() + 2;
|
||||
}
|
||||
if (port > mediaSendRtpPortInfo.getEnd()) {
|
||||
if (mediaSendRtpPortInfo.getStart() %2 != 0) {
|
||||
port = mediaSendRtpPortInfo.getStart() + 1;
|
||||
}else {
|
||||
port = mediaSendRtpPortInfo.getStart();
|
||||
|
||||
String key = VideoManagerConstants.PLATFORM_SEND_RTP_INFO_PREFIX
|
||||
+ userSetting.getServerId() + "_*";
|
||||
List<Object> queryResult = RedisUtil.scan(redisTemplate, key);
|
||||
Map<Integer, SendRtpItem> sendRtpItemMap = new HashMap<>();
|
||||
|
||||
for (Object o : queryResult) {
|
||||
SendRtpItem sendRtpItem = (SendRtpItem) redisTemplate.opsForValue().get(o);
|
||||
if (sendRtpItem != null) {
|
||||
sendRtpItemMap.put(sendRtpItem.getLocalPort(), sendRtpItem);
|
||||
}
|
||||
}
|
||||
|
||||
int port = getPort(mediaSendRtpPortInfo.getCurrent(),
|
||||
mediaSendRtpPortInfo.getStart(),
|
||||
mediaSendRtpPortInfo.getEnd(), checkPort -> sendRtpItemMap.get(checkPort) == null);
|
||||
|
||||
mediaSendRtpPortInfo.setCurrent(port);
|
||||
redisTemplate.opsForValue().set(key, mediaSendRtpPortInfo);
|
||||
redisTemplate.opsForValue().set(sendIndexKey, mediaSendRtpPortInfo);
|
||||
return port;
|
||||
}
|
||||
|
||||
interface CheckPortCallback{
|
||||
boolean check(int port);
|
||||
}
|
||||
|
||||
private int getPort(int current, int start, int end, CheckPortCallback checkPortCallback) {
|
||||
int port;
|
||||
if (current %2 != 0) {
|
||||
port = current + 1;
|
||||
}else {
|
||||
port = current + 2;
|
||||
}
|
||||
if (port > end) {
|
||||
if (start %2 != 0) {
|
||||
port = start + 1;
|
||||
}else {
|
||||
port = start;
|
||||
}
|
||||
}
|
||||
if (!checkPortCallback.check(port)) {
|
||||
return getPort(port, start, end, checkPortCallback);
|
||||
}
|
||||
return port;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.alibaba.fastjson2.JSONObject;
|
||||
import com.genersoft.iot.vmp.common.InviteInfo;
|
||||
import com.genersoft.iot.vmp.common.InviteSessionType;
|
||||
import com.genersoft.iot.vmp.common.StreamInfo;
|
||||
import com.genersoft.iot.vmp.common.VideoManagerConstants;
|
||||
import com.genersoft.iot.vmp.conf.UserSetting;
|
||||
import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.*;
|
||||
@@ -27,11 +28,13 @@ import com.genersoft.iot.vmp.service.bean.MessageForPushChannel;
|
||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.OtherRtpSendInfo;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.StreamContent;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@@ -124,6 +127,9 @@ public class ZLMHttpHookListener {
|
||||
@Autowired
|
||||
private ThreadPoolTaskExecutor taskExecutor;
|
||||
|
||||
@Autowired
|
||||
private RedisTemplate<Object, Object> redisTemplate;
|
||||
|
||||
/**
|
||||
* 服务器定时上报时间,上报间隔可配置,默认10s上报一次
|
||||
*/
|
||||
@@ -232,10 +238,7 @@ public class ZLMHttpHookListener {
|
||||
|
||||
|
||||
HookResultForOnPublish result = HookResultForOnPublish.SUCCESS();
|
||||
if (!"rtp".equals(param.getApp())) {
|
||||
result.setEnable_audio(true);
|
||||
}
|
||||
|
||||
result.setEnable_audio(true);
|
||||
taskExecutor.execute(() -> {
|
||||
ZlmHttpHookSubscribe.Event subscribe = this.subscribe.sendNotify(HookType.on_publish, json);
|
||||
if (subscribe != null) {
|
||||
@@ -264,7 +267,6 @@ public class ZLMHttpHookListener {
|
||||
// 如果是录像下载就设置视频间隔十秒
|
||||
if (ssrcTransactionForAll.get(0).getType() == InviteSessionType.DOWNLOAD) {
|
||||
result.setMp4_max_second(10);
|
||||
result.setEnable_audio(true);
|
||||
result.setEnable_mp4(true);
|
||||
}
|
||||
// 如果是talk对讲,则默认获取声音
|
||||
@@ -291,6 +293,14 @@ public class ZLMHttpHookListener {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (param.getApp().equalsIgnoreCase("rtp")) {
|
||||
String receiveKey = VideoManagerConstants.WVP_OTHER_RECEIVE_RTP_INFO + userSetting.getServerId() + "_" + param.getStream();
|
||||
OtherRtpSendInfo otherRtpSendInfo = (OtherRtpSendInfo)redisTemplate.opsForValue().get(receiveKey);
|
||||
if (otherRtpSendInfo != null) {
|
||||
result.setEnable_mp4(true);
|
||||
}
|
||||
}
|
||||
logger.info("[ZLM HOOK]推流鉴权 响应:{}->{}->>>>{}", param.getMediaServerId(), param, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -522,8 +532,6 @@ public class ZLMHttpHookListener {
|
||||
if ("rtp".equals(param.getApp())) {
|
||||
ret.put("close", userSetting.getStreamOnDemand());
|
||||
// 国标流, 点播/录像回放/录像下载
|
||||
// StreamInfo streamInfoForPlayCatch = redisCatchStorage.queryPlayByStreamId(param.getStream());
|
||||
|
||||
InviteInfo inviteInfo = inviteStreamService.getInviteInfoByStream(null, param.getStream());
|
||||
// 点播
|
||||
if (inviteInfo != null) {
|
||||
@@ -588,7 +596,7 @@ public class ZLMHttpHookListener {
|
||||
// 拉流代理
|
||||
StreamProxyItem streamProxyItem = streamProxyService.getStreamProxyByAppAndStream(param.getApp(), param.getStream());
|
||||
if (streamProxyItem != null) {
|
||||
if (streamProxyItem.isEnableDisableNoneReader()) {
|
||||
if (streamProxyItem.isEnableRemoveNoneReader()) {
|
||||
// 无人观看自动移除
|
||||
ret.put("close", true);
|
||||
streamProxyService.del(param.getApp(), param.getStream());
|
||||
@@ -670,7 +678,7 @@ public class ZLMHttpHookListener {
|
||||
resultHolder.put(key, uuid, result);
|
||||
|
||||
if (!exist) {
|
||||
playService.play(mediaInfo, deviceId, channelId, (code, message, data) -> {
|
||||
playService.play(mediaInfo, deviceId, channelId, null, (code, message, data) -> {
|
||||
msg.setData(new HookResult(code, message));
|
||||
resultHolder.invokeResult(msg);
|
||||
});
|
||||
|
||||
@@ -61,7 +61,7 @@ public class ZLMMediaListManager {
|
||||
private UserSetting userSetting;
|
||||
|
||||
@Autowired
|
||||
private ZLMServerFactory ZLMServerFactory;
|
||||
private ZLMServerFactory zlmServerFactory;
|
||||
|
||||
@Autowired
|
||||
private IMediaServerService mediaServerService;
|
||||
@@ -97,7 +97,7 @@ public class ZLMMediaListManager {
|
||||
public void sendStreamEvent(String app, String stream, String mediaServerId) {
|
||||
MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId);
|
||||
// 查看推流状态
|
||||
Boolean streamReady = ZLMServerFactory.isStreamReady(mediaServerItem, app, stream);
|
||||
Boolean streamReady = zlmServerFactory.isStreamReady(mediaServerItem, app, stream);
|
||||
if (streamReady != null && streamReady) {
|
||||
ChannelOnlineEvent channelOnlineEventLister = getChannelOnlineEventLister(app, stream);
|
||||
if (channelOnlineEventLister != null) {
|
||||
|
||||
@@ -86,10 +86,13 @@ public class ZLMServerFactory {
|
||||
}else {
|
||||
param.put("port", port);
|
||||
}
|
||||
param.put("ssrc", ssrc);
|
||||
if (onlyAuto != null) {
|
||||
param.put("only_audio", onlyAuto?"1":"0");
|
||||
}
|
||||
if (ssrc != 0) {
|
||||
param.put("ssrc", ssrc);
|
||||
}
|
||||
|
||||
JSONObject openRtpServerResultJson = zlmresTfulUtils.openRtpServer(mediaServerItem, param);
|
||||
logger.info(JSONObject.toJSONString(openRtpServerResultJson));
|
||||
if (openRtpServerResultJson != null) {
|
||||
|
||||
@@ -21,5 +21,6 @@ public enum HookType {
|
||||
on_server_started,
|
||||
|
||||
on_rtp_server_timeout,
|
||||
on_server_keepalive
|
||||
on_server_keepalive,
|
||||
on_send_rtp_stopped
|
||||
}
|
||||
|
||||
@@ -51,5 +51,13 @@ public class HookResultForOnPublish extends HookResult{
|
||||
this.mp4_save_path = mp4_save_path;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "HookResultForOnPublish{" +
|
||||
"enable_audio=" + enable_audio +
|
||||
", enable_mp4=" + enable_mp4 +
|
||||
", mp4_max_second=" + mp4_max_second +
|
||||
", mp4_save_path='" + mp4_save_path + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user