|
@@ -11,6 +11,7 @@ import com.genersoft.iot.vmp.conf.security.dto.LoginUser;
|
|
|
import com.genersoft.iot.vmp.gb28181.GBEventSubscribe;
|
|
|
import com.genersoft.iot.vmp.gb28181.GBHookSubscribeFactory;
|
|
|
import com.genersoft.iot.vmp.gb28181.HookSubscribeForKey;
|
|
|
+import com.genersoft.iot.vmp.gb28181.bean.BroadcastItem;
|
|
|
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
|
|
import com.genersoft.iot.vmp.gb28181.bean.SsrcTransaction;
|
|
|
import com.genersoft.iot.vmp.gb28181.session.VideoStreamSessionManager;
|
|
@@ -45,10 +46,7 @@ import javax.servlet.http.HttpServletRequest;
|
|
|
import javax.sip.InvalidArgumentException;
|
|
|
import javax.sip.SipException;
|
|
|
import java.text.ParseException;
|
|
|
-import java.util.HashMap;
|
|
|
-import java.util.List;
|
|
|
-import java.util.Map;
|
|
|
-import java.util.UUID;
|
|
|
+import java.util.*;
|
|
|
|
|
|
@Tag(name = "国标设备点播")
|
|
|
@CrossOrigin
|
|
@@ -268,7 +266,7 @@ public class PlayController {
|
|
|
@Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
|
|
@Parameter(name = "app", description = "推流app", required = true)
|
|
|
@Parameter(name = "stream", description = "音频推流编号", required = true)
|
|
|
- @GetMapping("/broadcast")
|
|
|
+ @GetMapping("/broadcastOld")
|
|
|
// @PostMapping("/broadcast/{deviceId}")
|
|
|
public DeferredResult<WVPResult<String>> broadcastApi(
|
|
|
HttpServletRequest request,
|
|
@@ -364,7 +362,7 @@ public class PlayController {
|
|
|
@Parameter(name = "channelId", description = "设备国标编号", required = true)
|
|
|
@Parameter(name = "waitTime", description = "设备国标编号", required = false)
|
|
|
@GetMapping("/startBroadcast")
|
|
|
- public DeferredResult<WVPResult<String>> getWebRtcAddr(@RequestParam String deviceId,
|
|
|
+ public DeferredResult<WVPResult<String>> startBroadcast(@RequestParam String deviceId,
|
|
|
@RequestParam("channelId") String channelId,
|
|
|
@RequestParam(value = "waitTime",
|
|
|
required = false,
|
|
@@ -431,7 +429,17 @@ public class PlayController {
|
|
|
wvpResult.setMsg((String) json.get("msg"));
|
|
|
} else if (code == 0) {
|
|
|
logger.info("收到设备invite信息: {}",json);
|
|
|
- // todo 存储invite信息和request信息至redis中
|
|
|
+
|
|
|
+ BroadcastItem broadcastItem = new BroadcastItem();
|
|
|
+ broadcastItem.setMediaId(mediaServerItem.getId());
|
|
|
+ broadcastItem.setDeviceId(deviceId);
|
|
|
+ broadcastItem.setApp(app);
|
|
|
+ broadcastItem.setStream(stream);
|
|
|
+ broadcastItem.setIpcIp((String) json.get("addr"));
|
|
|
+ broadcastItem.setIpcAudioPort((Integer) json.get("port"));
|
|
|
+ broadcastItem.setSsrc((String) json.get("ssrc"));
|
|
|
+ broadcastItem.setRequest(request);
|
|
|
+ broadcastItem.setAudioFormats((Vector) json.get("audioFormats"));
|
|
|
// 获取id
|
|
|
resultData.put("mediaId",mediaServerItem.getId());
|
|
|
resultData.put("app",app);
|
|
@@ -439,21 +447,94 @@ public class PlayController {
|
|
|
resultData.put("type",type);
|
|
|
resultData.put("sign",sign);
|
|
|
resultData.put("webRtcPushUrl", webRtcPushUrl);
|
|
|
+ resultData.put("audioFormats",json.get("audioFormats"));
|
|
|
logger.info("获取webrtc推流地址:{}",webRtcPushUrl);
|
|
|
+ //存储invite信息和request信息至redis中
|
|
|
+ if(redisCatchStorage.addBroadcastItem(
|
|
|
+ deviceId,
|
|
|
+ broadcastItem
|
|
|
+ )){
|
|
|
+ logger.info("语音对讲信息存储成功");
|
|
|
+ }else{
|
|
|
+ logger.warn("无法存储数据至zlm");
|
|
|
+ }
|
|
|
+ //设置过期时间
|
|
|
wvpResult.setCode(ErrorCode.SUCCESS.getCode());
|
|
|
wvpResult.setMsg(ErrorCode.SUCCESS.getMsg());
|
|
|
wvpResult.setData(resultData);
|
|
|
}
|
|
|
- logger.warn("结束");
|
|
|
msg.setData(wvpResult);
|
|
|
resultHolder.invokeAllResult(msg);
|
|
|
- logger.warn("结束2");
|
|
|
// return result;
|
|
|
}
|
|
|
);
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
+ @Operation(summary = "开始建立语音广播连接")
|
|
|
+ @Parameter(name = "deviceId", description = "设备国标编号", required = true)
|
|
|
+ @Parameter(name = "audioCoded", description = "音频编码信息", required = false)
|
|
|
+ @GetMapping("/broadcast")
|
|
|
+ public DeferredResult<WVPResult<String>> broadcast(
|
|
|
+ @RequestParam("deviceId") String deviceId,
|
|
|
+ @RequestParam(value = "audioCoded",required = false) String audioCoded
|
|
|
+ ){
|
|
|
+ RequestMessage msg = new RequestMessage();
|
|
|
+ // 返回invite信息给设备
|
|
|
+ String key = DeferredResultHolder.CALLBACK_CMD_BROADCAST_INVITE + deviceId;
|
|
|
+ msg.setKey(key);
|
|
|
+ String uuid = UUID.randomUUID().toString();
|
|
|
+ msg.setId(uuid);
|
|
|
+ DeferredResult<WVPResult<String>> result = new DeferredResult<>(10*1000l);
|
|
|
+ WVPResult wvpResult = new WVPResult();
|
|
|
+ resultHolder.put(key, uuid, result);
|
|
|
+
|
|
|
+
|
|
|
+ // 从redis中拉取语音对讲数据
|
|
|
+ BroadcastItem broadcastItem = redisCatchStorage.queryBroadcastItem(deviceId);
|
|
|
+ if(broadcastItem == null){
|
|
|
+ logger.info("[语音对讲 invite] invite交互超时");
|
|
|
+ wvpResult.setCode(ErrorCode.ERROR404.getCode());
|
|
|
+ wvpResult.setMsg("无法找到设备invite信息,可能是交互超时");
|
|
|
+ msg.setData(wvpResult);
|
|
|
+ resultHolder.invokeAllResult(msg);
|
|
|
+ }
|
|
|
+ // 检查设备是否存在
|
|
|
+ Device device = storager.queryVideoDevice(deviceId);
|
|
|
+ if (device == null){
|
|
|
+ // 无法找到设备
|
|
|
+ wvpResult.setCode(ErrorCode.ERROR404.getCode());
|
|
|
+ wvpResult.setMsg("无法找到设备");
|
|
|
+ msg.setData(wvpResult);
|
|
|
+ resultHolder.invokeAllResult(msg);
|
|
|
+ }
|
|
|
+ // 获取对应的媒体服务
|
|
|
+ MediaServerItem mediaServerItem = playService.getNewMediaServerItem(device);
|
|
|
+ logger.info("[语言广播] 分配的流媒体服务器为 {}",mediaServerItem.getId());
|
|
|
+ if (mediaServerItem == null) {
|
|
|
+ logger.warn("[语音广播] 无法连接至ZLM服务器");
|
|
|
+ wvpResult.setCode(ErrorCode.ERR_NOTFOUND_STREAM.getCode());
|
|
|
+ wvpResult.setMsg("无法连接至流媒体服务器");
|
|
|
+ msg.setData(wvpResult);
|
|
|
+ resultHolder.invokeAllResult(msg);
|
|
|
+ }else{
|
|
|
+ playService.broadcast(
|
|
|
+ mediaServerItem,
|
|
|
+ device,
|
|
|
+ broadcastItem,
|
|
|
+ 5000,
|
|
|
+ (int code, JSONObject json, SIPRequest request)->{
|
|
|
+ // todo 处理并返回语音广播请求,应该有一个ack
|
|
|
+ }
|
|
|
+ );
|
|
|
+ }
|
|
|
+ // 获取zlm推流端口
|
|
|
+ // todo 回复 invite 200 给设备
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
@Operation(summary = "获取所有的ssrc")
|
|
|
@GetMapping("/ssrc")
|
|
|
public JSONObject getSSRC() {
|