Commit e1af52fb5eaf0bcac221ba11cc90da7cd50d2895

Authored by 648540858
1 parent c859fe22

更新文档

src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
... ... @@ -553,7 +553,6 @@ public class ZLMHttpHookListener {
553 553 if (sendRtpItem == null) {
554 554 // TODO 可能数据错误,重新开启语音通道
555 555 }else {
556   - String is_Udp = sendRtpItem.isTcp() ? "0" : "1";
557 556 MediaServerItem mediaInfo = mediaServerService.getOne(sendRtpItem.getMediaServerId());
558 557 logger.info("rtp/{}开始向上级推流, 目标={}:{},SSRC={}", sendRtpItem.getStreamId(), sendRtpItem.getIp(), sendRtpItem.getPort(), sendRtpItem.getSsrc());
559 558 Map<String, Object> param = new HashMap<>(12);
... ... @@ -570,7 +569,7 @@ public class ZLMHttpHookListener {
570 569 if (sendRtpItem.isTcpActive()) {
571 570 jsonObject = zlmrtpServerFactory.startSendRtpPassive(mediaInfo, param);
572 571 } else {
573   - param.put("is_udp", is_Udp);
  572 + param.put("is_udp", sendRtpItem.isTcp() ? "0" : "1");
574 573 param.put("dst_url", sendRtpItem.getIp());
575 574 param.put("dst_port", sendRtpItem.getPort());
576 575 jsonObject = zlmrtpServerFactory.startSendRtpStream(mediaInfo, param);
... ... @@ -581,8 +580,8 @@ public class ZLMHttpHookListener {
581 580 }
582 581 }else {
583 582 // 开启语音对讲通道
584   - MediaServerItem mediaServerForMinimumLoad = mediaServerService.getMediaServerForMinimumLoad();
585   - playService.talk(mediaServerForMinimumLoad, device, channelId, (mediaServerItem, jsonObject)->{
  583 + MediaServerItem mediaServerItem = mediaServerService.getOne(mediaServerId);
  584 + playService.talk(mediaServerItem, device, channelId, (mediaServer, jsonObject)->{
586 585 System.out.println("开始推流");
587 586 }, eventResult -> {
588 587 System.out.println(eventResult.msg);
... ... @@ -644,7 +643,7 @@ public class ZLMHttpHookListener {
644 643 }
645 644 }
646 645 }
647   - if (!regist) {
  646 + if (!regist ) {
648 647 List<SendRtpItem> sendRtpItems = redisCatchStorage.querySendRTPServerByStream(stream);
649 648 if (sendRtpItems.size() > 0) {
650 649 for (SendRtpItem sendRtpItem : sendRtpItems) {
... ... @@ -657,7 +656,7 @@ public class ZLMHttpHookListener {
657 656 if (platform != null) {
658 657 commanderFroPlatform.streamByeCmd(platform, sendRtpItem);
659 658 }else {
660   - if (sendRtpItem.isOnlyAudio()) {
  659 + if ("talk".equals(app) && sendRtpItem.isOnlyAudio()) {
661 660 AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId());
662 661 if (device != null && audioBroadcastCatch != null) {
663 662 // cmder.streamByeCmd(device, sendRtpItem.getChannelId(), audioBroadcastCatch.getSipTransactionInfo(), null);
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMRTPServerFactory.java
... ... @@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSONArray;
4 4 import com.alibaba.fastjson.JSONObject;
5 5 import com.genersoft.iot.vmp.conf.UserSetting;
6 6 import com.genersoft.iot.vmp.gb28181.bean.SendRtpItem;
  7 +import com.genersoft.iot.vmp.media.zlm.dto.MediaItem;
7 8 import com.genersoft.iot.vmp.media.zlm.dto.MediaServerItem;
8 9 import org.slf4j.Logger;
9 10 import org.slf4j.LoggerFactory;
... ... @@ -323,4 +324,20 @@ public class ZLMRTPServerFactory {
323 324 public void closeAllSendRtpStream() {
324 325  
325 326 }
  327 +
  328 + public MediaItem getMediaInfo(MediaServerItem mediaServerItem, String app, String stream) {
  329 + JSONObject json = zlmresTfulUtils.getMediaList(mediaServerItem, app, stream);
  330 + MediaItem mediaItem = null;
  331 + if (json == null || json.getInteger("code") != 0) {
  332 + return null;
  333 + } else {
  334 + JSONArray data = json.getJSONArray("data");
  335 + if (data == null || data.size() == 0) {
  336 + return null;
  337 + }else {
  338 + mediaItem = JSONObject.toJavaObject(data.getJSONObject(0), MediaItem.class);
  339 + }
  340 + }
  341 + return mediaItem;
  342 + }
326 343 }
... ...
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
... ... @@ -14,6 +14,7 @@ import com.genersoft.iot.vmp.conf.exception.ControllerException;
14 14 import com.genersoft.iot.vmp.conf.exception.SsrcTransactionNotFoundException;
15 15 import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommanderForPlatform;
16 16 import com.genersoft.iot.vmp.gb28181.utils.SipUtils;
  17 +import com.genersoft.iot.vmp.media.zlm.dto.MediaItem;
17 18 import com.genersoft.iot.vmp.service.IDeviceService;
18 19 import com.genersoft.iot.vmp.vmanager.bean.AudioBroadcastResult;
19 20 import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
... ... @@ -290,148 +291,154 @@ public class PlayServiceImpl implements IPlayService {
290 291 logger.info("[对讲] 端口分配异常,deviceId={},channelId={},ssrcInfo={}", device.getDeviceId(), channelId, ssrcInfo);
291 292 return;
292 293 }
293   - try {
294   - String callId = SipUtils.getNewCallId();
295   - cmder.talkStreamCmd(mediaServerItem, ssrcInfo, device, channelId, callId, (MediaServerItem mediaServerItemInuse, JSONObject response) -> {
296   - logger.info("[对讲] 流已生成, 开始推流: " + response.toJSONString());
297   - dynamicTask.stop(timeOutTaskKey);
298   - // TODO 暂不做处理
299   - }, (MediaServerItem mediaServerItemInuse, JSONObject json) -> {
300   - logger.info("[对讲] 开始推流: " + json.toJSONString());
301   - dynamicTask.stop(timeOutTaskKey);
302   - // 获取远程IP端口 作为回复语音流的地址
303   - String ip = json.getString("ip");
304   - Integer port = json.getInteger("port");
305   - logger.info("[远端设备开始推流]{}/{}, 来自ip:{}, 端口:{}", device.getDeviceId(), channelId, ip, port);
306   - // 查看平台推流是否就绪
307   - Boolean ready = zlmrtpServerFactory.isStreamReady(mediaServerItemInuse, "talk", stream);
308   - if (!ready) {
309   - try {
310   - cmder.streamByeCmd(device, channelId, finalSsrcInfo.getStream(), null);
311   - } catch (InvalidArgumentException | ParseException | SipException e) {
312   - logger.error("[对讲超时], 发送BYE失败 {}", e.getMessage());
313   - } catch (SsrcTransactionNotFoundException e) {
314   - timeoutCallback.run();
315   - mediaServerService.releaseSsrc(mediaServerItem.getId(), finalSsrcInfo.getSsrc());
316   - mediaServerService.closeRTPServer(mediaServerItem, finalSsrcInfo.getStream());
317   - streamSession.remove(device.getDeviceId(), channelId, finalSsrcInfo.getStream());
318   - }
319   - }else {
320   - SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, ip, port, ssrcInfo.getSsrc(), device.getDeviceId(),
321   - device.getDeviceId(), channelId,
322   - false);
323   -
324   - sendRtpItem.setTcpActive(false);
325   - if (sendRtpItem == null || sendRtpItem.getLocalPort() == 0) {
326   - logger.warn("服务器端口资源不足");
327   - try {
328   - cmder.streamByeCmd(device, channelId, finalSsrcInfo.getStream(), null);
329   - } catch (InvalidArgumentException | ParseException | SipException e) {
330   - logger.error("[对讲超时], 发送BYE失败 {}", e.getMessage());
331   - } catch (SsrcTransactionNotFoundException e) {
332   - timeoutCallback.run();
333   - mediaServerService.releaseSsrc(mediaServerItem.getId(), finalSsrcInfo.getSsrc());
334   - mediaServerService.closeRTPServer(mediaServerItem, finalSsrcInfo.getStream());
335   - streamSession.remove(device.getDeviceId(), channelId, finalSsrcInfo.getStream());
336   - }
337   - return;
338   - }
339   - sendRtpItem.setCallId(callId);
340   - sendRtpItem.setPlayType(InviteStreamType.TALK);
341   - sendRtpItem.setStatus(1);
342   - sendRtpItem.setIp(ip);
343   - sendRtpItem.setPort(port);
344   - sendRtpItem.setTcpActive(false);
345   - sendRtpItem.setStreamId(ssrcInfo.getStream());
346   - sendRtpItem.setApp("talk");
347   - sendRtpItem.setSsrc(ssrc);
348   - redisCatchStorage.updateSendRTPSever(sendRtpItem);
349   -
350   - Map<String, Object> param = new HashMap<>(12);
351   - param.put("vhost","__defaultVhost__");
352   - param.put("app",sendRtpItem.getApp());
353   - param.put("stream",sendRtpItem.getStreamId());
354   - param.put("ssrc", sendRtpItem.getSsrc());
355   - param.put("src_port", sendRtpItem.getLocalPort());
356   - param.put("pt", sendRtpItem.getPt());
357   - param.put("use_ps", sendRtpItem.isUsePs() ? "1" : "0");
358   - param.put("only_audio", sendRtpItem.isOnlyAudio() ? "1" : "0");
359   - JSONObject jsonObject = zlmrtpServerFactory.startSendRtpStream(mediaServerItemInuse, param);
360   - System.out.println(11111);
361   - System.out.println(jsonObject);
362   - }
363 294  
364   - }, (event) -> {
365   -// ResponseEvent responseEvent = (ResponseEvent) event.event;
366   -// String contentString = new String(responseEvent.getResponse().getRawContent());
367   -// // 获取ssrc
368   -// int ssrcIndex = contentString.indexOf("y=");
369   -// // 检查是否有y字段
370   -// if (ssrcIndex >= 0) {
371   -// //ssrc规定长度为10字节,不取余下长度以避免后续还有“f=”字段 TODO 后续对不规范的非10位ssrc兼容
372   -// String ssrcInResponse = contentString.substring(ssrcIndex + 2, ssrcIndex + 12);
373   -// // 查询到ssrc不一致且开启了ssrc校验则需要针对处理
374   -// if (ssrc.equals(ssrcInResponse)) {
375   -// return;
376   -// }
377   -// logger.info("[对讲消息] 收到invite 200, 发现下级自定义了ssrc: {}", ssrcInResponse);
378   -// if (!mediaServerItem.isRtpEnable() || device.isSsrcCheck()) {
379   -// logger.info("[对讲消息] SSRC修正 {}->{}", ssrc, ssrcInResponse);
  295 + String callId = SipUtils.getNewCallId();
  296 + boolean pushing = false;
  297 + // 查看设备是否已经在推流
  298 +// MediaItem mediaItem = zlmrtpServerFactory.getMediaInfo(mediaServerItem, "rtp",ssrcInfo.getStream());
  299 +// if (mediaItem != null) {
  300 +// SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem,
  301 +// mediaItem.getOriginSock().getPeer_ip(), mediaItem.getOriginSock().getPeer_port(), ssrcInfo.getSsrc(), device.getDeviceId(),
  302 +// device.getDeviceId(), channelId,
  303 +// false);
380 304 //
381   -// if (!mediaServerItem.getSsrcConfig().checkSsrc(ssrcInResponse)) {
382   -// // ssrc 不可用
383   -// // 释放ssrc
  305 +// sendRtpItem.setTcpActive(false);
  306 +// sendRtpItem.setCallId(callId);
  307 +// sendRtpItem.setPlayType(InviteStreamType.TALK);
  308 +// sendRtpItem.setStatus(1);
  309 +// sendRtpItem.setIp(mediaItem.getOriginSock().getPeer_ip());
  310 +// sendRtpItem.setPort(mediaItem.getOriginSock().getPeer_port());
  311 +// sendRtpItem.setTcpActive(false);
  312 +// sendRtpItem.setStreamId(ssrcInfo.getStream());
  313 +// sendRtpItem.setApp("1000");
  314 +// sendRtpItem.setStreamId("1000");
  315 +// sendRtpItem.setSsrc(ssrc);
  316 +// sendRtpItem.setOnlyAudio(true);
  317 +// redisCatchStorage.updateSendRTPSever(sendRtpItem);
  318 +//
  319 +// Map<String, Object> param = new HashMap<>(12);
  320 +// param.put("vhost","__defaultVhost__");
  321 +// param.put("app",sendRtpItem.getApp());
  322 +// param.put("stream",sendRtpItem.getStreamId());
  323 +// param.put("ssrc", sendRtpItem.getSsrc());
  324 +// param.put("dst_url", sendRtpItem.getIp());
  325 +// param.put("dst_port", sendRtpItem.getPort());
  326 +// param.put("src_port", sendRtpItem.getLocalPort());
  327 +// param.put("pt", sendRtpItem.getPt());
  328 +// param.put("use_ps", sendRtpItem.isUsePs() ? "1" : "0");
  329 +// param.put("is_udp", sendRtpItem.isTcp() ? "0" : "1");
  330 +// param.put("only_audio", sendRtpItem.isOnlyAudio() ? "1" : "0");
  331 +// JSONObject jsonObject = zlmrtpServerFactory.startSendRtpStream(mediaServerItem, param);
  332 +// System.out.println(2222);
  333 +// System.out.println(jsonObject);
  334 +// }else {
  335 + try {
  336 + cmder.talkStreamCmd(mediaServerItem, ssrcInfo, device, channelId, callId, (MediaServerItem mediaServerItemInuse, JSONObject response) -> {
  337 + logger.info("[对讲] 流已生成, 开始推流: " + response.toJSONString());
  338 + dynamicTask.stop(timeOutTaskKey);
  339 + // TODO 暂不做处理
  340 + }, (MediaServerItem mediaServerItemInuse, JSONObject json) -> {
  341 + logger.info("[对讲] 设备开始推流: " + json.toJSONString());
  342 + dynamicTask.stop(timeOutTaskKey);
  343 + // 获取远程IP端口 作为回复语音流的地址
  344 + String ip = json.getString("ip");
  345 + Integer port = json.getInteger("port");
  346 + logger.info("[设备开始推流]{}/{}, 来自ip:{}, 端口:{}", device.getDeviceId(), channelId, ip, port);
  347 + // 查看平台推流是否就绪
  348 +// Boolean ready = zlmrtpServerFactory.isStreamReady(mediaServerItemInuse, "talk", stream);
  349 +// if (!ready) {
  350 +// try {
  351 +// cmder.streamByeCmd(device, channelId, finalSsrcInfo.getStream(), null);
  352 +// } catch (InvalidArgumentException | ParseException | SipException e) {
  353 +// logger.error("[对讲超时], 发送BYE失败 {}", e.getMessage());
  354 +// } catch (SsrcTransactionNotFoundException e) {
  355 +// timeoutCallback.run();
384 356 // mediaServerService.releaseSsrc(mediaServerItem.getId(), finalSsrcInfo.getSsrc());
  357 +// mediaServerService.closeRTPServer(mediaServerItem, finalSsrcInfo.getStream());
385 358 // streamSession.remove(device.getDeviceId(), channelId, finalSsrcInfo.getStream());
386   -// event.msg = "下级自定义了ssrc,但是此ssrc不可用";
387   -// event.statusCode = 400;
388   -// errorEvent.response(event);
389   -// return;
390 359 // }
391   -//
392   -// // 单端口模式streamId也有变化,需要重新设置监听
393   -// if (!mediaServerItem.isRtpEnable()) {
394   -// // 添加订阅
395   -// HookSubscribeForStreamChange hookSubscribe = HookSubscribeFactory.on_stream_changed("rtp", stream, true, "rtsp", mediaServerItem.getId());
396   -// subscribe.removeSubscribe(hookSubscribe);
397   -// hookSubscribe.getContent().put("stream", String.format("%08x", Integer.parseInt(ssrcInResponse)).toUpperCase());
398   -// subscribe.addSubscribe(hookSubscribe, (MediaServerItem mediaServerItemInUse, JSONObject response) -> {
399   -// logger.info("[ZLM HOOK] ssrc修正后收到订阅消息: " + response.toJSONString());
400   -// dynamicTask.stop(timeOutTaskKey);
401   -// // hook响应
402   -// onPublishHandlerForPlay(mediaServerItemInUse, response, device.getDeviceId(), channelId, uuid);
403   -// hookEvent.response(mediaServerItemInUse, response);
404   -// });
  360 +// }else {
  361 +// try {
  362 +// Thread.sleep(1000);
  363 +// } catch (InterruptedException e) {
  364 +// throw new RuntimeException(e);
405 365 // }
406   -// // 关闭rtp server
407   -// mediaServerService.closeRTPServer(mediaServerItem, finalSsrcInfo.getStream());
408   -// // 重新开启ssrc server
409   -// mediaServerService.openRTPServer(mediaServerItem, finalSsrcInfo.getStream(), ssrcInResponse, device.isSsrcCheck(), false, finalSsrcInfo.getPort());
410   -//
  366 + SendRtpItem sendRtpItem = zlmrtpServerFactory.createSendRtpItem(mediaServerItem, ip, port, ssrcInfo.getSsrc(), device.getDeviceId(),
  367 + device.getDeviceId(), channelId,
  368 + false);
  369 +
  370 +
  371 +// if (sendRtpItem.getLocalPort() == 0) {
  372 +// logger.warn("服务器端口资源不足");
  373 +// try {
  374 +// cmder.streamByeCmd(device, channelId, finalSsrcInfo.getStream(), null);
  375 +// } catch (InvalidArgumentException | ParseException | SipException e) {
  376 +// logger.error("[对讲超时], 发送BYE失败 {}", e.getMessage());
  377 +// } catch (SsrcTransactionNotFoundException e) {
  378 +// timeoutCallback.run();
  379 +// mediaServerService.releaseSsrc(mediaServerItem.getId(), finalSsrcInfo.getSsrc());
  380 +// mediaServerService.closeRTPServer(mediaServerItem, finalSsrcInfo.getStream());
  381 +// streamSession.remove(device.getDeviceId(), channelId, finalSsrcInfo.getStream());
  382 +// }
  383 +// return;
  384 +// }
  385 + sendRtpItem.setTcpActive(false);
  386 + sendRtpItem.setCallId(callId);
  387 + sendRtpItem.setPlayType(InviteStreamType.TALK);
  388 + sendRtpItem.setStatus(1);
  389 + sendRtpItem.setIp(ip);
  390 + sendRtpItem.setPort(port);
  391 + sendRtpItem.setTcpActive(false);
  392 + sendRtpItem.setApp("1000");
  393 + sendRtpItem.setStreamId("1000");
  394 + sendRtpItem.setSsrc(ssrc);
  395 + sendRtpItem.setOnlyAudio(true);
  396 + redisCatchStorage.updateSendRTPSever(sendRtpItem);
  397 +
  398 + Map<String, Object> param = new HashMap<>(12);
  399 + param.put("vhost","__defaultVhost__");
  400 + param.put("app",sendRtpItem.getApp());
  401 + param.put("stream",sendRtpItem.getStreamId());
  402 + param.put("ssrc", sendRtpItem.getSsrc());
  403 + param.put("dst_url", sendRtpItem.getIp());
  404 + param.put("dst_port", sendRtpItem.getPort());
  405 + param.put("src_port", sendRtpItem.getLocalPort());
  406 + param.put("pt", sendRtpItem.getPt());
  407 + param.put("use_ps", sendRtpItem.isUsePs() ? "1" : "0");
  408 + param.put("is_udp", sendRtpItem.isTcp() ? "0" : "1");
  409 + param.put("only_audio", sendRtpItem.isOnlyAudio() ? "1" : "0");
  410 + JSONObject jsonObject = zlmrtpServerFactory.startSendRtpStream(mediaServerItemInuse, param);
  411 + System.out.println(11111);
  412 + System.out.println(sendRtpItem.getIp() + ":" + sendRtpItem.getPort());
  413 +// System.out.println(jsonObject);
411 414 // }
412   -// }
413   - }, (event) -> {
  415 +
  416 + }, (event) -> {
  417 +
  418 + }, (event) -> {
  419 + dynamicTask.stop(timeOutTaskKey);
  420 + mediaServerService.closeRTPServer(mediaServerItem, finalSsrcInfo.getStream());
  421 + // 释放ssrc
  422 + mediaServerService.releaseSsrc(mediaServerItem.getId(), finalSsrcInfo.getSsrc());
  423 +
  424 + streamSession.remove(device.getDeviceId(), channelId, finalSsrcInfo.getStream());
  425 + errorEvent.response(event);
  426 + });
  427 + } catch (InvalidArgumentException | SipException | ParseException e) {
  428 +
  429 + logger.error("[命令发送失败] 对讲消息: {}", e.getMessage());
414 430 dynamicTask.stop(timeOutTaskKey);
415 431 mediaServerService.closeRTPServer(mediaServerItem, finalSsrcInfo.getStream());
416 432 // 释放ssrc
417 433 mediaServerService.releaseSsrc(mediaServerItem.getId(), finalSsrcInfo.getSsrc());
418 434  
419 435 streamSession.remove(device.getDeviceId(), channelId, finalSsrcInfo.getStream());
420   - errorEvent.response(event);
421   - });
422   - } catch (InvalidArgumentException | SipException | ParseException e) {
423   -
424   - logger.error("[命令发送失败] 对讲消息: {}", e.getMessage());
425   - dynamicTask.stop(timeOutTaskKey);
426   - mediaServerService.closeRTPServer(mediaServerItem, finalSsrcInfo.getStream());
427   - // 释放ssrc
428   - mediaServerService.releaseSsrc(mediaServerItem.getId(), finalSsrcInfo.getSsrc());
  436 + SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(new CmdSendFailEvent(null));
  437 + eventResult.msg = "命令发送失败";
  438 + errorEvent.response(eventResult);
  439 + }
  440 +// }
429 441  
430   - streamSession.remove(device.getDeviceId(), channelId, finalSsrcInfo.getStream());
431   - SipSubscribe.EventResult eventResult = new SipSubscribe.EventResult(new CmdSendFailEvent(null));
432   - eventResult.msg = "命令发送失败";
433   - errorEvent.response(eventResult);
434   - }
435 442 }
436 443  
437 444  
... ...
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/play/PlayController.java
... ... @@ -232,6 +232,14 @@ public class PlayController {
232 232  
233 233 }
234 234  
  235 + @GetMapping("/1111")
  236 + public void broadcastApi1() {
  237 + MediaServerItem defaultMediaServer = mediaServerService.getMediaServerForMinimumLoad();
  238 + Device device = storager.queryVideoDevice("34020000001320090001");
  239 + playService.talk(defaultMediaServer, device, "34020000001370000001", null, null, null);
  240 +
  241 + }
  242 +
235 243  
236 244 @Operation(summary = "停止语音广播")
237 245 @Parameter(name = "deviceId", description = "设备Id", required = true)
... ...