| | |
| | | import com.genersoft.iot.vmp.media.bean.MediaInfo; |
| | | import com.genersoft.iot.vmp.media.event.MediaArrivalEvent; |
| | | import com.genersoft.iot.vmp.media.event.MediaDepartureEvent; |
| | | import com.genersoft.iot.vmp.media.event.MediaNotFoundEvent; |
| | | import com.genersoft.iot.vmp.media.service.IMediaServerService; |
| | | import com.genersoft.iot.vmp.media.zlm.SendRtpPortManager; |
| | | import com.genersoft.iot.vmp.media.zlm.ZLMServerFactory; |
| | | import com.genersoft.iot.vmp.media.zlm.ZlmHttpHookSubscribe; |
| | | import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeFactory; |
| | | import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForRecordMp4; |
| | | import com.genersoft.iot.vmp.media.zlm.dto.HookSubscribeForStreamChange; |
| | | import com.genersoft.iot.vmp.media.event.hook.HookSubscribe; |
| | | import com.genersoft.iot.vmp.media.event.hook.HookSubscribeFactory; |
| | | import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForRecordMp4; |
| | | import com.genersoft.iot.vmp.media.event.hook.HookSubscribeForStreamChange; |
| | | import com.genersoft.iot.vmp.media.zlm.dto.MediaServer; |
| | | import com.genersoft.iot.vmp.media.zlm.dto.hook.HookParam; |
| | | import com.genersoft.iot.vmp.media.zlm.dto.hook.OnRecordMp4HookParam; |
| | |
| | | private IInviteStreamService inviteStreamService; |
| | | |
| | | @Autowired |
| | | private ZlmHttpHookSubscribe subscribe; |
| | | private HookSubscribe subscribe; |
| | | |
| | | @Autowired |
| | | private SendRtpPortManager sendRtpPortManager; |
| | |
| | | @Async("taskExecutor") |
| | | @EventListener |
| | | public void onApplicationEvent(MediaDepartureEvent event) { |
| | | List<SendRtpItem> sendRtpItems = redisCatchStorage.querySendRTPServerByStream(event.getStream()); |
| | | if (!sendRtpItems.isEmpty()) { |
| | | for (SendRtpItem sendRtpItem : sendRtpItems) { |
| | | if (sendRtpItem != null && sendRtpItem.getApp().equals(event.getApp())) { |
| | | String platformId = sendRtpItem.getPlatformId(); |
| | | Device device = deviceService.getDevice(platformId); |
| | | try { |
| | | if (device != null) { |
| | | cmder.streamByeCmd(device, sendRtpItem.getChannelId(), event.getStream(), sendRtpItem.getCallId()); |
| | | if (sendRtpItem.getPlayType().equals(InviteStreamType.BROADCAST) |
| | | || sendRtpItem.getPlayType().equals(InviteStreamType.TALK)) { |
| | | AudioBroadcastCatch audioBroadcastCatch = audioBroadcastManager.get(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); |
| | | if (audioBroadcastCatch != null) { |
| | | // 来自上级平台的停止对讲 |
| | | logger.info("[停止对讲] 来自上级,平台:{}, 通道:{}", sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); |
| | | audioBroadcastManager.del(sendRtpItem.getDeviceId(), sendRtpItem.getChannelId()); |
| | | } |
| | | } |
| | | } |
| | | } catch (SipException | InvalidArgumentException | ParseException | |
| | | SsrcTransactionNotFoundException e) { |
| | | logger.error("[命令发送失败] 发送BYE: {}", e.getMessage()); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | if ("broadcast".equals(event.getApp()) || "talk".equals(event.getApp())) { |
| | | if (event.getStream().indexOf("_") > 0) { |
| | | String[] streamArray = event.getStream().split("_"); |
| | |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 流未找到的处理 |
| | | */ |
| | | @Async("taskExecutor") |
| | | @EventListener |
| | | public void onApplicationEvent(MediaNotFoundEvent event) { |
| | | if (!"rtp".equals(event.getApp())) { |
| | | return; |
| | | } |
| | | String[] s = event.getStream().split("_"); |
| | | if ((s.length != 2 && s.length != 4)) { |
| | | return; |
| | | } |
| | | String deviceId = s[0]; |
| | | String channelId = s[1]; |
| | | Device device = redisCatchStorage.getDevice(deviceId); |
| | | if (device == null || !device.isOnLine()) { |
| | | return; |
| | | } |
| | | DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId); |
| | | if (deviceChannel == null) { |
| | | return; |
| | | } |
| | | if (s.length == 2) { |
| | | logger.info("[ZLM HOOK] 预览流未找到, 发起自动点播:{}->{}->{}/{}", event.getMediaServer().getId(), event.getSchema(), event.getApp(), event.getStream()); |
| | | play(event.getMediaServer(), deviceId, channelId, null, null); |
| | | } else if (s.length == 4) { |
| | | // 此时为录像回放, 录像回放格式为> 设备ID_通道ID_开始时间_结束时间 |
| | | String startTimeStr = s[2]; |
| | | String endTimeStr = s[3]; |
| | | if (startTimeStr == null || endTimeStr == null || startTimeStr.length() != 14 || endTimeStr.length() != 14) { |
| | | return; |
| | | } |
| | | String startTime = DateUtil.urlToyyyy_MM_dd_HH_mm_ss(startTimeStr); |
| | | String endTime = DateUtil.urlToyyyy_MM_dd_HH_mm_ss(endTimeStr); |
| | | logger.info("[ZLM HOOK] 回放流未找到, 发起自动点播:{}->{}->{}/{}-{}-{}", |
| | | event.getMediaServer().getId(), event.getSchema(), |
| | | event.getApp(), event.getStream(), |
| | | startTime, endTime |
| | | ); |
| | | |
| | | SSRCInfo ssrcInfo = mediaServerService.openRTPServer(event.getMediaServer(), event.getStream(), null, |
| | | device.isSsrcCheck(), true, 0, false, false, device.getStreamModeForParam()); |
| | | playBack(event.getMediaServer(), ssrcInfo, deviceId, channelId, startTime, endTime, null); |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | private void talk(MediaServer mediaServerItem, Device device, String channelId, String stream, |
| | | ZlmHttpHookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent, |
| | | HookSubscribe.Event hookEvent, SipSubscribe.Event errorEvent, |
| | | Runnable timeoutCallback, AudioBroadcastEvent audioEvent) { |
| | | |
| | | String playSsrc = ssrcFactory.getPlaySsrc(mediaServerItem.getId()); |
| | |
| | | inviteStreamService.removeInviteInfo(inviteInfo); |
| | | }; |
| | | |
| | | ZlmHttpHookSubscribe.Event hookEvent = (mediaServerItemInuse, hookParam) -> { |
| | | HookSubscribe.Event hookEvent = (mediaServerItemInuse, hookParam) -> { |
| | | logger.info("收到回放订阅消息: " + hookParam); |
| | | dynamicTask.stop(playBackTimeOutTaskKey); |
| | | StreamInfo streamInfo = onPublishHandlerForPlayback(mediaServerItemInuse, hookParam, deviceId, channelId, startTime, endTime); |
| | |
| | | streamSession.remove(device.getDeviceId(), channelId, ssrcInfo.getStream()); |
| | | inviteStreamService.removeInviteInfo(inviteInfo); |
| | | }; |
| | | ZlmHttpHookSubscribe.Event hookEvent = (mediaServerItemInuse, hookParam) -> { |
| | | HookSubscribe.Event hookEvent = (mediaServerItemInuse, hookParam) -> { |
| | | logger.info("[录像下载]收到订阅消息: " + hookParam); |
| | | dynamicTask.stop(downLoadTimeOutTaskKey); |
| | | StreamInfo streamInfo = onPublishHandlerForDownload(mediaServerItemInuse, hookParam, deviceId, channelId, startTime, endTime); |
| | |
| | | downLoadTimeOutTaskKey, callback, inviteInfo, InviteSessionType.DOWNLOAD); |
| | | |
| | | // 注册录像回调事件,录像下载结束后写入下载地址 |
| | | ZlmHttpHookSubscribe.Event hookEventForRecord = (mediaServerItemInuse, hookParam) -> { |
| | | HookSubscribe.Event hookEventForRecord = (mediaServerItemInuse, hookParam) -> { |
| | | logger.info("[录像下载] 收到录像写入磁盘消息: , {}/{}-{}", |
| | | inviteInfo.getDeviceId(), inviteInfo.getChannelId(), ssrcInfo.getStream()); |
| | | logger.info("[录像下载] 收到录像写入磁盘消息内容: " + hookParam); |