添加语音对讲接口
parent
4ad711f61a
commit
1e67a8dde0
|
@ -411,7 +411,7 @@ public class ZLMHttpHookListener {
|
||||||
}
|
}
|
||||||
// 开启语音对讲通道
|
// 开启语音对讲通道
|
||||||
try {
|
try {
|
||||||
playService.audioBroadcastCmd(device, channelId, mediaInfo, param.getApp(), param.getStream(), 60, false, (msg) -> {
|
playService.audioBroadcastCmd(device, channelId, mediaInfo, param.getApp(), param.getStream(), 60, false, (code, msg) -> {
|
||||||
logger.info("[语音对讲] 通道建立成功, device: {}, channel: {}", deviceId, channelId);
|
logger.info("[语音对讲] 通道建立成功, device: {}, channel: {}", deviceId, channelId);
|
||||||
});
|
});
|
||||||
} catch (InvalidArgumentException | ParseException | SipException e) {
|
} catch (InvalidArgumentException | ParseException | SipException e) {
|
||||||
|
@ -440,8 +440,12 @@ public class ZLMHttpHookListener {
|
||||||
playService.stopAudioBroadcast(deviceId, channelId);
|
playService.stopAudioBroadcast(deviceId, channelId);
|
||||||
}
|
}
|
||||||
// 开启语音对讲通道
|
// 开启语音对讲通道
|
||||||
playService.talkCmd(device, channelId, mediaInfo, param.getStream(), (msg) -> {
|
playService.talkCmd(device, channelId, mediaInfo, param.getStream(), (code, msg) -> {
|
||||||
logger.info("[语音对讲] 通道建立成功, device: {}, channel: {}", deviceId, channelId);
|
if (code == 0) {
|
||||||
|
logger.info("[语音对讲] 通道建立成功, device: {}, channel: {}", deviceId, channelId);
|
||||||
|
}else {
|
||||||
|
logger.info("[语音对讲] 通道建立失败,{}, device: {}, channel: {}", msg, deviceId, channelId);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// 流注销
|
// 流注销
|
||||||
|
|
|
@ -47,7 +47,7 @@ public interface IPlayService {
|
||||||
|
|
||||||
AudioBroadcastResult audioBroadcast(Device device, String channelId, Boolean broadcastMode);
|
AudioBroadcastResult audioBroadcast(Device device, String channelId, Boolean broadcastMode);
|
||||||
|
|
||||||
boolean audioBroadcastCmd(Device device, String channelId, MediaServerItem mediaServerItem, String app, String stream, int timeout, boolean isFromPlatform, AudioBroadcastEvent event) throws InvalidArgumentException, ParseException, SipException;
|
boolean audioBroadcastCmd(Device device, DeviceChannel channel, MediaServerItem mediaServerItem, String app, String stream, int timeout, boolean isFromPlatform, AudioBroadcastEvent event) throws InvalidArgumentException, ParseException, SipException;
|
||||||
|
|
||||||
boolean audioBroadcastInUse(Device device, String channelId);
|
boolean audioBroadcastInUse(Device device, String channelId);
|
||||||
|
|
||||||
|
|
|
@ -220,7 +220,7 @@ public class PlayServiceImpl implements IPlayService {
|
||||||
String playSsrc = ssrcFactory.getPlaySsrc(mediaServerItem.getId());
|
String playSsrc = ssrcFactory.getPlaySsrc(mediaServerItem.getId());
|
||||||
|
|
||||||
if (playSsrc == null) {
|
if (playSsrc == null) {
|
||||||
audioEvent.call("ssrc已经用尽");
|
audioEvent.call(-1,"ssrc已经用尽");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SendRtpItem sendRtpItem = new SendRtpItem();
|
SendRtpItem sendRtpItem = new SendRtpItem();
|
||||||
|
@ -246,7 +246,7 @@ public class PlayServiceImpl implements IPlayService {
|
||||||
//端口获取失败的ssrcInfo 没有必要发送点播指令
|
//端口获取失败的ssrcInfo 没有必要发送点播指令
|
||||||
if (port <= 0) {
|
if (port <= 0) {
|
||||||
logger.info("[语音对讲] 端口分配异常,deviceId={},channelId={}", device.getDeviceId(), channelId);
|
logger.info("[语音对讲] 端口分配异常,deviceId={},channelId={}", device.getDeviceId(), channelId);
|
||||||
audioEvent.call("端口分配异常");
|
audioEvent.call(-1,"端口分配异常");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sendRtpItem.setLocalPort(port);
|
sendRtpItem.setLocalPort(port);
|
||||||
|
@ -287,7 +287,7 @@ public class PlayServiceImpl implements IPlayService {
|
||||||
if (jsonObject == null || jsonObject.getInteger("code") != 0 ) {
|
if (jsonObject == null || jsonObject.getInteger("code") != 0 ) {
|
||||||
mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpItem.getSsrc());
|
mediaServerService.releaseSsrc(mediaServerItem.getId(), sendRtpItem.getSsrc());
|
||||||
logger.info("[语音对讲]失败 deviceId: {}, channelId: {}", device.getDeviceId(), channelId);
|
logger.info("[语音对讲]失败 deviceId: {}, channelId: {}", device.getDeviceId(), channelId);
|
||||||
audioEvent.call("失败, " + jsonObject.getString("msg"));
|
audioEvent.call(-1,"失败, " + jsonObject.getString("msg"));
|
||||||
// 查看是否已经建立了通道,存在则发送bye
|
// 查看是否已经建立了通道,存在则发送bye
|
||||||
stopTalk(device, channelId);
|
stopTalk(device, channelId);
|
||||||
}
|
}
|
||||||
|
@ -349,8 +349,6 @@ public class PlayServiceImpl implements IPlayService {
|
||||||
eventResult.msg = "命令发送失败";
|
eventResult.msg = "命令发送失败";
|
||||||
errorEvent.response(eventResult);
|
errorEvent.response(eventResult);
|
||||||
}
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1123,7 +1121,7 @@ public class PlayServiceImpl implements IPlayService {
|
||||||
DeviceChannel deviceChannel = storager.queryChannel(device.getDeviceId(), channelId);
|
DeviceChannel deviceChannel = storager.queryChannel(device.getDeviceId(), channelId);
|
||||||
if (deviceChannel == null) {
|
if (deviceChannel == null) {
|
||||||
logger.warn("开启语音广播的时候未找到通道: {}", channelId);
|
logger.warn("开启语音广播的时候未找到通道: {}", channelId);
|
||||||
event.call("开启语音广播的时候未找到通道");
|
event.call(-1, "开启语音广播的时候未找到通道");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// 查询通道使用状态
|
// 查询通道使用状态
|
||||||
|
@ -1134,25 +1132,13 @@ public class PlayServiceImpl implements IPlayService {
|
||||||
Boolean streamReady = zlmServerFactory.isStreamReady(mediaServerItem, sendRtpItem.getApp(), sendRtpItem.getStream());
|
Boolean streamReady = zlmServerFactory.isStreamReady(mediaServerItem, sendRtpItem.getApp(), sendRtpItem.getStream());
|
||||||
if (streamReady) {
|
if (streamReady) {
|
||||||
logger.warn("语音广播已经开启: {}", channelId);
|
logger.warn("语音广播已经开启: {}", channelId);
|
||||||
event.call("语音广播已经开启");
|
event.call(-1,"语音广播已经开启");
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
stopAudioBroadcast(device.getDeviceId(), channelId);
|
stopAudioBroadcast(device.getDeviceId(), channelId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// SendRtpItem sendRtpItem = redisCatchStorage.querySendRTPServer(device.getDeviceId(), channelId, null, null);
|
|
||||||
// if (sendRtpItem != null) {
|
|
||||||
// MediaServerItem mediaServer = mediaServerService.getOne(sendRtpItem.getMediaServerId());
|
|
||||||
// Boolean streamReady = zlmServerFactory.isStreamReady(mediaServer, sendRtpItem.getApp(), sendRtpItem.getStream());
|
|
||||||
// if (streamReady) {
|
|
||||||
// logger.warn("[语音对讲] 进行中: {}", channelId);
|
|
||||||
// event.call("语音对讲进行中");
|
|
||||||
// return false;
|
|
||||||
// } else {
|
|
||||||
// stopTalk(device, channelId);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// 发送通知
|
// 发送通知
|
||||||
cmder.audioBroadcastCmd(device, channelId, eventResultForOk -> {
|
cmder.audioBroadcastCmd(device, channelId, eventResultForOk -> {
|
||||||
|
@ -1166,12 +1152,13 @@ public class PlayServiceImpl implements IPlayService {
|
||||||
}
|
}
|
||||||
dynamicTask.startDelay(key, ()->{
|
dynamicTask.startDelay(key, ()->{
|
||||||
logger.info("[语音广播]等待invite消息超时:{}/{}", device.getDeviceId(), channelId);
|
logger.info("[语音广播]等待invite消息超时:{}/{}", device.getDeviceId(), channelId);
|
||||||
|
event.call(-1,"等待invite消息超时");
|
||||||
stopAudioBroadcast(device.getDeviceId(), channelId);
|
stopAudioBroadcast(device.getDeviceId(), channelId);
|
||||||
}, 10*1000);
|
}, 10*1000);
|
||||||
}, eventResultForError -> {
|
}, eventResultForError -> {
|
||||||
// 发送失败
|
// 发送失败
|
||||||
logger.error("语音广播发送失败: {}:{}", channelId, eventResultForError.msg);
|
logger.error("语音广播发送失败: {}:{}", channelId, eventResultForError.msg);
|
||||||
event.call("语音广播发送失败");
|
event.call(-1,"语音广播发送失败");
|
||||||
stopAudioBroadcast(device.getDeviceId(), channelId);
|
stopAudioBroadcast(device.getDeviceId(), channelId);
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
|
@ -1443,7 +1430,7 @@ public class PlayServiceImpl implements IPlayService {
|
||||||
DeviceChannel deviceChannel = storager.queryChannel(device.getDeviceId(), channelId);
|
DeviceChannel deviceChannel = storager.queryChannel(device.getDeviceId(), channelId);
|
||||||
if (deviceChannel == null) {
|
if (deviceChannel == null) {
|
||||||
logger.warn("开启语音对讲的时候未找到通道: {}", channelId);
|
logger.warn("开启语音对讲的时候未找到通道: {}", channelId);
|
||||||
event.call("开启语音对讲的时候未找到通道");
|
event.call(-1,"开启语音对讲的时候未找到通道");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 查询通道使用状态
|
// 查询通道使用状态
|
||||||
|
@ -1455,7 +1442,7 @@ public class PlayServiceImpl implements IPlayService {
|
||||||
Boolean streamReady = zlmServerFactory.isStreamReady(mediaServer, sendRtpItem.getApp(), sendRtpItem.getStream());
|
Boolean streamReady = zlmServerFactory.isStreamReady(mediaServer, sendRtpItem.getApp(), sendRtpItem.getStream());
|
||||||
if (streamReady) {
|
if (streamReady) {
|
||||||
logger.warn("[语音对讲] 正在语音广播,无法开启语音通话: {}", channelId);
|
logger.warn("[语音对讲] 正在语音广播,无法开启语音通话: {}", channelId);
|
||||||
event.call("正在语音广播");
|
event.call(-1, "正在语音广播");
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
stopAudioBroadcast(device.getDeviceId(), channelId);
|
stopAudioBroadcast(device.getDeviceId(), channelId);
|
||||||
|
@ -1469,7 +1456,7 @@ public class PlayServiceImpl implements IPlayService {
|
||||||
Boolean streamReady = zlmServerFactory.isStreamReady(mediaServer, "rtp", sendRtpItem.getReceiveStream());
|
Boolean streamReady = zlmServerFactory.isStreamReady(mediaServer, "rtp", sendRtpItem.getReceiveStream());
|
||||||
if (streamReady) {
|
if (streamReady) {
|
||||||
logger.warn("[语音对讲] 进行中: {}", channelId);
|
logger.warn("[语音对讲] 进行中: {}", channelId);
|
||||||
event.call("语音对讲进行中");
|
event.call(-1,"语音对讲进行中");
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
stopTalk(device, channelId);
|
stopTalk(device, channelId);
|
||||||
|
@ -1480,14 +1467,14 @@ public class PlayServiceImpl implements IPlayService {
|
||||||
logger.info("[语音对讲] 收到设备发来的流");
|
logger.info("[语音对讲] 收到设备发来的流");
|
||||||
}, eventResult -> {
|
}, eventResult -> {
|
||||||
logger.warn("[语音对讲] 失败,{}/{}, 错误码 {} {}", device.getDeviceId(), channelId, eventResult.statusCode, eventResult.msg);
|
logger.warn("[语音对讲] 失败,{}/{}, 错误码 {} {}", device.getDeviceId(), channelId, eventResult.statusCode, eventResult.msg);
|
||||||
event.call("失败,错误码 " + eventResult.statusCode + ", " + eventResult.msg);
|
event.call(-1,"失败,错误码 " + eventResult.statusCode + ", " + eventResult.msg);
|
||||||
}, () -> {
|
}, () -> {
|
||||||
logger.warn("[语音对讲] 失败,{}/{} 超时", device.getDeviceId(), channelId);
|
logger.warn("[语音对讲] 失败,{}/{} 超时", device.getDeviceId(), channelId);
|
||||||
event.call("失败,超时 ");
|
event.call(-1,"失败,超时 ");
|
||||||
stopTalk(device, channelId);
|
stopTalk(device, channelId);
|
||||||
}, errorMsg -> {
|
}, (code, msg) -> {
|
||||||
logger.warn("[语音对讲] 失败,{}/{} {}", device.getDeviceId(), channelId, errorMsg);
|
logger.warn("[语音对讲] 失败,{}/{} {}", device.getDeviceId(), channelId, msg);
|
||||||
event.call(errorMsg);
|
event.call(code, msg);
|
||||||
stopTalk(device, channelId);
|
stopTalk(device, channelId);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import com.genersoft.iot.vmp.conf.exception.ControllerException;
|
||||||
import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException;
|
import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException;
|
||||||
import com.genersoft.iot.vmp.conf.security.JwtUtils;
|
import com.genersoft.iot.vmp.conf.security.JwtUtils;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||||
|
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
|
||||||
import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction;
|
import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction;
|
||||||
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
|
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
|
import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
|
||||||
|
@ -18,10 +19,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.callback.RequestMessage;
|
||||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
||||||
import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
|
import com.genersoft.iot.vmp.media.zlm.ZLMRESTfulUtils;
|
||||||
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
|
import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
|
||||||
import com.genersoft.iot.vmp.service.IInviteStreamService;
|
import com.genersoft.iot.vmp.service.*;
|
||||||
import com.genersoft.iot.vmp.service.IMediaServerService;
|
|
||||||
import com.genersoft.iot.vmp.service.IMediaService;
|
|
||||||
import com.genersoft.iot.vmp.service.IPlayService;
|
|
||||||
import com.genersoft.iot.vmp.service.bean.InviteErrorCode;
|
import com.genersoft.iot.vmp.service.bean.InviteErrorCode;
|
||||||
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
|
||||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
|
||||||
|
@ -95,6 +93,12 @@ public class PlayController {
|
||||||
@Autowired
|
@Autowired
|
||||||
private UserSetting userSetting;
|
private UserSetting userSetting;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IDeviceService deviceService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IDeviceChannelService channelService;
|
||||||
|
|
||||||
@Operation(summary = "开始点播", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
@Operation(summary = "开始点播", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||||
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
||||||
@Parameter(name = "channelId", description = "通道国标编号", required = true)
|
@Parameter(name = "channelId", description = "通道国标编号", required = true)
|
||||||
|
@ -236,25 +240,60 @@ public class PlayController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "语音广播命令", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
@Operation(summary = "开始语音广播", security = @SecurityRequirement(name = JwtUtils.HEADER))
|
||||||
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
||||||
@Parameter(name = "deviceId", description = "通道国标编号", required = true)
|
@Parameter(name = "deviceId", description = "通道国标编号", required = true)
|
||||||
@Parameter(name = "timeout", description = "推流超时时间(秒)", required = true)
|
@Parameter(name = "mediaServerId", description = "流媒体ID", required = false)
|
||||||
@GetMapping("/broadcast/{deviceId}/{channelId}")
|
@Parameter(name = "app", description = "用于广播的应用名", required = true)
|
||||||
@PostMapping("/broadcast/{deviceId}/{channelId}")
|
@Parameter(name = "stream", description = "用于广播的流ID", required = true)
|
||||||
public AudioBroadcastResult broadcastApi(@PathVariable String deviceId, @PathVariable String channelId, Integer timeout, Boolean broadcastMode) {
|
@GetMapping("/broadcast/start")
|
||||||
|
@PostMapping("/broadcast/start")
|
||||||
|
public DeferredResult<WVPResult<Void>> broadcastApi(String deviceId, String channelId, @RequestParam(required = false) String mediaServerId, String app, String stream) {
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("语音广播API调用");
|
logger.debug("语音广播API调用");
|
||||||
}
|
}
|
||||||
Device device = storager.queryVideoDevice(deviceId);
|
Device device = deviceService.getDevice(deviceId);
|
||||||
if (device == null) {
|
if (device == null) {
|
||||||
throw new ControllerException(ErrorCode.ERROR400.getCode(), "未找到设备: " + deviceId);
|
throw new ControllerException(ErrorCode.ERROR400.getCode(), "未找到设备: " + deviceId);
|
||||||
}
|
}
|
||||||
if (channelId == null) {
|
DeviceChannel channel = channelService.getOne(deviceId, channelId);
|
||||||
|
if (channel == null) {
|
||||||
throw new ControllerException(ErrorCode.ERROR400.getCode(), "未找到通道: " + channelId);
|
throw new ControllerException(ErrorCode.ERROR400.getCode(), "未找到通道: " + channelId);
|
||||||
}
|
}
|
||||||
|
MediaServerItem mediaServerItem;
|
||||||
|
if (ObjectUtils.isEmpty(mediaServerId)) {
|
||||||
|
mediaServerItem = mediaServerService.getDefaultMediaServer();
|
||||||
|
}else {
|
||||||
|
mediaServerItem = mediaServerService.getOne(mediaServerId);
|
||||||
|
}
|
||||||
|
JSONObject jsonObject = zlmresTfulUtils.getMediaInfo(mediaServerItem, app, "rtsp", stream);
|
||||||
|
if (jsonObject == null || jsonObject.getInteger("code") != 0) {
|
||||||
|
throw new ControllerException(ErrorCode.ERROR400.getCode(), "推流信息不存在");
|
||||||
|
}
|
||||||
|
|
||||||
return playService.audioBroadcast(device, channelId, broadcastMode);
|
DeferredResult<WVPResult<Void>> result = new DeferredResult<>();
|
||||||
|
|
||||||
|
result.onTimeout(()->{
|
||||||
|
WVPResult<Void> wvpResult = new WVPResult<>();
|
||||||
|
wvpResult.setCode(-1);
|
||||||
|
wvpResult.setMsg("请求超时");
|
||||||
|
result.setResult(wvpResult);
|
||||||
|
playService.stopAudioBroadcast();
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
playService.audioBroadcastCmd(device, channelId, mediaServerItem, app, stream, 60, false, (code, msg) -> {
|
||||||
|
WVPResult<Void> wvpResult = new WVPResult<>();
|
||||||
|
wvpResult.setCode(code);
|
||||||
|
wvpResult.setMsg(msg);
|
||||||
|
result.setResult(wvpResult);
|
||||||
|
});
|
||||||
|
} catch (InvalidArgumentException | ParseException | SipException e) {
|
||||||
|
WVPResult<Void> wvpResult = new WVPResult<>();
|
||||||
|
wvpResult.setCode(-1);
|
||||||
|
wvpResult.setMsg("请求失败:" + e.getMessage());
|
||||||
|
result.setResult(wvpResult);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,5 +5,5 @@ package com.genersoft.iot.vmp.vmanager.gb28181.play.bean;
|
||||||
* @author lin
|
* @author lin
|
||||||
*/
|
*/
|
||||||
public interface AudioBroadcastEvent {
|
public interface AudioBroadcastEvent {
|
||||||
void call(String msg);
|
void call(int code, String msg);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue