添加第二种语音对讲实现
This commit is contained in:
@@ -11,12 +11,16 @@ import com.genersoft.iot.vmp.conf.UserSetting;
|
||||
import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.*;
|
||||
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
||||
import com.genersoft.iot.vmp.gb28181.session.AudioBroadcastManager;
|
||||
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
|
||||
import com.genersoft.iot.vmp.media.zlm.dto.*;
|
||||
import com.genersoft.iot.vmp.service.*;
|
||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.AudioBroadcastResult;
|
||||
import com.genersoft.iot.vmp.vmanager.bean.WVPResult;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -51,7 +55,13 @@ public class ZLMHttpHookListener {
|
||||
private SIPCommander cmder;
|
||||
|
||||
@Autowired
|
||||
private SIPCommanderFroPlatform commanderFroPlatform;
|
||||
private ISIPCommanderForPlatform commanderFroPlatform;
|
||||
|
||||
@Autowired
|
||||
private AudioBroadcastManager audioBroadcastManager;
|
||||
|
||||
@Autowired
|
||||
private ZLMRTPServerFactory zlmrtpServerFactory;
|
||||
|
||||
@Autowired
|
||||
private IPlayService playService;
|
||||
@@ -466,7 +476,127 @@ public class ZLMHttpHookListener {
|
||||
streamInfo.getStream(), null);
|
||||
}
|
||||
}
|
||||
}else {
|
||||
}else if ("broadcast".equals(app)){
|
||||
// 语音对讲推流 stream需要满足格式deviceId_channelId
|
||||
if (regist && stream.indexOf("_") > 0) {
|
||||
String[] streamArray = stream.split("_");
|
||||
if (streamArray.length == 2) {
|
||||
String deviceId = streamArray[0];
|
||||
String channelId = streamArray[1];
|
||||
Device device = deviceService.queryDevice(deviceId);
|
||||
if (device != null) {
|
||||
DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId);
|
||||
if (deviceChannel != null) {
|
||||
if (audioBroadcastManager.exit(deviceId, channelId)) {
|
||||
// 直接推流
|
||||
SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(null, null, stream, null);
|
||||
if (sendRtpItem == null) {
|
||||
// TODO 可能数据错误,重新开启语音通道
|
||||
}else {
|
||||
String is_Udp = sendRtpItem.isTcp() ? "0" : "1";
|
||||
MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
|
||||
logger.info("rtp/{}开始向上级推流, 目标={}:{},SSRC={}", sendRtpItem.getStreamId(), sendRtpItem.getIp(), sendRtpItem.getPort(), sendRtpItem.getSsrc());
|
||||
Map<String, Object> param = new HashMap<>(12);
|
||||
param.put("vhost","__defaultVhost__");
|
||||
param.put("app",sendRtpItem.getApp());
|
||||
param.put("stream",sendRtpItem.getStreamId());
|
||||
param.put("ssrc", sendRtpItem.getSsrc());
|
||||
param.put("src_port", sendRtpItem.getLocalPort());
|
||||
param.put("pt", sendRtpItem.getPt());
|
||||
param.put("use_ps", sendRtpItem.isUsePs() ? "1" : "0");
|
||||
param.put("only_audio", sendRtpItem.isOnlyAudio() ? "1" : "0");
|
||||
|
||||
JSONObject jsonObject;
|
||||
if (sendRtpItem.isTcpActive()) {
|
||||
jsonObject = zlmrtpServerFactory.startSendRtpPassive(mediaInfo, param);
|
||||
} else {
|
||||
param.put("is_udp", is_Udp);
|
||||
param.put("dst_url", sendRtpItem.getIp());
|
||||
param.put("dst_port", sendRtpItem.getPort());
|
||||
jsonObject = zlmrtpServerFactory.startSendRtpStream(mediaInfo, param);
|
||||
}
|
||||
if (jsonObject != null && jsonObject.getInteger("code") == 0) {
|
||||
logger.info("[语音对讲] 自动推流成功, device: {}, channel: {}", deviceId, channelId);
|
||||
}
|
||||
|
||||
}
|
||||
}else {
|
||||
// 开启语音对讲通道
|
||||
try {
|
||||
playService.audioBroadcastCmd(device, channelId, 60, (msg)->{
|
||||
logger.info("[语音对讲] 通道建立成功, device: {}, channel: {}", deviceId, channelId);
|
||||
});
|
||||
} catch (InvalidArgumentException | ParseException | SipException e) {
|
||||
logger.error("[命令发送失败] 语音对讲: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}else if ("talk".equals(app)){
|
||||
// 语音对讲推流 stream需要满足格式deviceId_channelId
|
||||
if (regist && stream.indexOf("_") > 0) {
|
||||
String[] streamArray = stream.split("_");
|
||||
if (streamArray.length == 2) {
|
||||
String deviceId = streamArray[0];
|
||||
String channelId = streamArray[1];
|
||||
Device device = deviceService.queryDevice(deviceId);
|
||||
if (device != null) {
|
||||
DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId);
|
||||
if (deviceChannel != null) {
|
||||
if (audioBroadcastManager.exit(deviceId, channelId)) {
|
||||
// 直接推流
|
||||
SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(null, null, stream, null);
|
||||
if (sendRtpItem == null) {
|
||||
// TODO 可能数据错误,重新开启语音通道
|
||||
}else {
|
||||
String is_Udp = sendRtpItem.isTcp() ? "0" : "1";
|
||||
MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
|
||||
logger.info("rtp/{}开始向上级推流, 目标={}:{},SSRC={}", sendRtpItem.getStreamId(), sendRtpItem.getIp(), sendRtpItem.getPort(), sendRtpItem.getSsrc());
|
||||
Map<String, Object> param = new HashMap<>(12);
|
||||
param.put("vhost","__defaultVhost__");
|
||||
param.put("app",sendRtpItem.getApp());
|
||||
param.put("stream",sendRtpItem.getStreamId());
|
||||
param.put("ssrc", sendRtpItem.getSsrc());
|
||||
param.put("src_port", sendRtpItem.getLocalPort());
|
||||
param.put("pt", sendRtpItem.getPt());
|
||||
param.put("use_ps", sendRtpItem.isUsePs() ? "1" : "0");
|
||||
param.put("only_audio", sendRtpItem.isOnlyAudio() ? "1" : "0");
|
||||
|
||||
JSONObject jsonObject;
|
||||
if (sendRtpItem.isTcpActive()) {
|
||||
jsonObject = zlmrtpServerFactory.startSendRtpPassive(mediaInfo, param);
|
||||
} else {
|
||||
param.put("is_udp", is_Udp);
|
||||
param.put("dst_url", sendRtpItem.getIp());
|
||||
param.put("dst_port", sendRtpItem.getPort());
|
||||
jsonObject = zlmrtpServerFactory.startSendRtpStream(mediaInfo, param);
|
||||
}
|
||||
if (jsonObject != null && jsonObject.getInteger("code") == 0) {
|
||||
logger.info("[语音对讲] 自动推流成功, device: {}, channel: {}", deviceId, channelId);
|
||||
}
|
||||
}
|
||||
}else {
|
||||
// 开启语音对讲通道
|
||||
MediaServerItem mediaServerForMinimumLoad = mediaServerService.getMediaServerForMinimumLoad();
|
||||
playService.talk(mediaServerForMinimumLoad, device, channelId, (mediaServerItem, jsonObject)->{
|
||||
System.out.println("开始推流");
|
||||
}, eventResult -> {
|
||||
System.out.println(eventResult.msg);
|
||||
}, ()->{
|
||||
System.out.println("超时");
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}else{
|
||||
if (!"rtp".equals(app)){
|
||||
String type = OriginType.values()[item.getOriginType()].getType();
|
||||
MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId);
|
||||
@@ -521,10 +651,23 @@ public class ZLMHttpHookListener {
|
||||
if (sendRtpItem.getApp().equals(app)) {
|
||||
String platformId = sendRtpItem.getPlatformId();
|
||||
ParentPlatform platform = storager.queryParentPlatByServerGBId(platformId);
|
||||
Device device = deviceService.queryDevice(platformId);
|
||||
|
||||
try {
|
||||
commanderFroPlatform.streamByeCmd(platform, sendRtpItem);
|
||||
} catch (SipException | InvalidArgumentException | ParseException e) {
|
||||
if (platform != null) {
|
||||
commanderFroPlatform.streamByeCmd(platform, sendRtpItem);
|
||||
}else {
|
||||
if (sendRtpItem.isOnlyAudio()) {
|
||||
AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId());
|
||||
if (device != null && audioBroadcastCatch != null) {
|
||||
// cmder.streamByeCmd(device, sendRtpItem.getChannelId(), audioBroadcastCatch.getSipTransactionInfo(), null);
|
||||
}
|
||||
}else {
|
||||
cmder.streamByeCmd(device, sendRtpItem.getChannelId(), stream, sendRtpItem.getCallId());
|
||||
}
|
||||
|
||||
}
|
||||
} catch (SipException | InvalidArgumentException | ParseException | SsrcTransactionNotFoundException e) {
|
||||
logger.error("[命令发送失败] 国标级联 发送BYE: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,33 +164,6 @@ public class ZLMRTPServerFactory {
|
||||
return result;
|
||||
}
|
||||
|
||||
// private int getPortFromportRange(MediaServerItem mediaServerItem) {
|
||||
// int currentPort = mediaServerItem.getCurrentPort();
|
||||
// if (currentPort == 0) {
|
||||
// String[] portRangeStrArray = mediaServerItem.getSendRtpPortRange().split(",");
|
||||
// if (portRangeStrArray.length != 2) {
|
||||
// portRangeArray[0] = 30000;
|
||||
// portRangeArray[1] = 30500;
|
||||
// }else {
|
||||
// portRangeArray[0] = Integer.parseInt(portRangeStrArray[0]);
|
||||
// portRangeArray[1] = Integer.parseInt(portRangeStrArray[1]);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (currentPort == 0 || currentPort++ > portRangeArray[1]) {
|
||||
// currentPort = portRangeArray[0];
|
||||
// mediaServerItem.setCurrentPort(currentPort);
|
||||
// return portRangeArray[0];
|
||||
// } else {
|
||||
// if (currentPort % 2 == 1) {
|
||||
// currentPort++;
|
||||
// }
|
||||
// currentPort++;
|
||||
// mediaServerItem.setCurrentPort(currentPort);
|
||||
// return currentPort;
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* 创建一个国标推流
|
||||
* @param ip 推流ip
|
||||
|
||||
@@ -38,6 +38,7 @@ public class ZlmHttpHookSubscribe {
|
||||
hookSubscribe.setExpires(expiresInstant);
|
||||
}
|
||||
allSubscribes.computeIfAbsent(hookSubscribe.getHookType(), k -> new ConcurrentHashMap<>()).put(hookSubscribe, event);
|
||||
System.out.println(allSubscribes);
|
||||
}
|
||||
|
||||
public ZlmHttpHookSubscribe.Event sendNotify(HookType type, JSONObject hookResponse) {
|
||||
@@ -48,6 +49,7 @@ public class ZlmHttpHookSubscribe {
|
||||
}
|
||||
for (IHookSubscribe key : eventMap.keySet()) {
|
||||
Boolean result = null;
|
||||
|
||||
for (String s : key.getContent().keySet()) {
|
||||
if (result == null) {
|
||||
result = key.getContent().getString(s).equals(hookResponse.getString(s));
|
||||
|
||||
@@ -24,10 +24,26 @@ public class HookSubscribeFactory {
|
||||
return hookSubscribe;
|
||||
}
|
||||
|
||||
public static HookSubscribeForStreamPush on_publish(String app, String stream, String scheam, String mediaServerId) {
|
||||
HookSubscribeForStreamPush hookSubscribe = new HookSubscribeForStreamPush();
|
||||
JSONObject subscribeKey = new com.alibaba.fastjson.JSONObject();
|
||||
subscribeKey.put("app", app);
|
||||
subscribeKey.put("stream", stream);
|
||||
if (scheam != null) {
|
||||
subscribeKey.put("schema", scheam);
|
||||
}
|
||||
subscribeKey.put("mediaServerId", mediaServerId);
|
||||
hookSubscribe.setContent(subscribeKey);
|
||||
|
||||
return hookSubscribe;
|
||||
}
|
||||
|
||||
|
||||
public static HookSubscribeForServerStarted on_server_started() {
|
||||
HookSubscribeForServerStarted hookSubscribe = new HookSubscribeForServerStarted();
|
||||
hookSubscribe.setContent(new JSONObject());
|
||||
|
||||
return hookSubscribe;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.genersoft.iot.vmp.media.zlm.dto;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
/**
|
||||
* hook订阅-开始推流
|
||||
* @author lin
|
||||
*/
|
||||
public class HookSubscribeForStreamPush implements IHookSubscribe{
|
||||
|
||||
private HookType hookType = HookType.on_publish;
|
||||
|
||||
private JSONObject content;
|
||||
|
||||
private Instant expires;
|
||||
|
||||
@Override
|
||||
public HookType getHookType() {
|
||||
return hookType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONObject getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(JSONObject content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instant getExpires() {
|
||||
return expires;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExpires(Instant expires) {
|
||||
this.expires = expires;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user