648540858
2024-01-10 c25a99d60bef3d3bbd59fee895bd658928fd00db
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
@@ -111,6 +111,9 @@
    private IUserService userService;
    @Autowired
    private ICloudRecordService cloudRecordService;
    @Autowired
    private VideoStreamSessionManager sessionManager;
    @Autowired
@@ -199,6 +202,13 @@
        }
        // 推流鉴权的处理
        if (!"rtp".equals(param.getApp())) {
            StreamProxyItem stream = streamProxyService.getStreamProxyByAppAndStream(param.getApp(), param.getStream());
            if (stream != null) {
                HookResultForOnPublish result = HookResultForOnPublish.SUCCESS();
                result.setEnable_audio(stream.isEnableAudio());
                result.setEnable_mp4(stream.isEnableMp4());
                return result;
            }
            if (userSetting.getPushAuthority()) {
                // 推流鉴权
                if (param.getParams() == null) {
@@ -224,12 +234,6 @@
                streamAuthorityInfo.setSign(sign);
                // 鉴权通过
                redisCatchStorage.updateStreamAuthorityInfo(param.getApp(), param.getStream(), streamAuthorityInfo);
                // 通知assist新的callId
                if (mediaInfo != null && mediaInfo.getRecordAssistPort() > 0) {
                    taskExecutor.execute(() -> {
                        assistRESTfulUtils.addStreamCallInfo(mediaInfo, param.getApp(), param.getStream(), callId, null);
                    });
                }
            }
        } else {
            zlmMediaListManager.sendStreamEvent(param.getApp(), param.getStream(), param.getMediaServerId());
@@ -257,15 +261,28 @@
        }
        // 替换流地址
        if ("rtp".equals(param.getApp()) && !mediaInfo.isRtpEnable()) {
            String ssrc = String.format("%010d", Long.parseLong(param.getStream(), 16));;
            InviteInfo inviteInfo = inviteStreamService.getInviteInfoBySSRC(ssrc);
            if (inviteInfo != null) {
                result.setStream_replace(inviteInfo.getStream());
                logger.info("[ZLM HOOK]推流鉴权 stream: {} 替换为 {}", param.getStream(), inviteInfo.getStream());
            if (!mediaInfo.isRtpEnable()) {
                String ssrc = String.format("%010d", Long.parseLong(param.getStream(), 16));;
                InviteInfo inviteInfo = inviteStreamService.getInviteInfoBySSRC(ssrc);
                if (inviteInfo != null) {
                    result.setStream_replace(inviteInfo.getStream());
                    logger.info("[ZLM HOOK]推流鉴权 stream: {} 替换为 {}", param.getStream(), inviteInfo.getStream());
                }
            }
        }
        List<SsrcTransaction> ssrcTransactionForAll = sessionManager.getSsrcTransactionForAll(null, null, null, param.getStream());
        if (ssrcTransactionForAll != null && ssrcTransactionForAll.size() == 1) {
            // 为录制国标模拟一个鉴权信息
            StreamAuthorityInfo streamAuthorityInfo = StreamAuthorityInfo.getInstanceByHook(param);
            streamAuthorityInfo.setApp(param.getApp());
            streamAuthorityInfo.setStream(ssrcTransactionForAll.get(0).getStream());
            streamAuthorityInfo.setCallId(ssrcTransactionForAll.get(0).getSipTransactionInfo().getCallId());
            redisCatchStorage.updateStreamAuthorityInfo(param.getApp(), ssrcTransactionForAll.get(0).getStream(), streamAuthorityInfo);
            String deviceId = ssrcTransactionForAll.get(0).getDeviceId();
            String channelId = ssrcTransactionForAll.get(0).getChannelId();
            DeviceChannel deviceChannel = storager.queryChannel(deviceId, channelId);
@@ -274,26 +291,8 @@
            }
            // 如果是录像下载就设置视频间隔十秒
            if (ssrcTransactionForAll.get(0).getType() == InviteSessionType.DOWNLOAD) {
                result.setMp4_max_second(10);
                result.setMp4_max_second(30);
                result.setEnable_mp4(true);
            }
        }
        if (mediaInfo.getRecordAssistPort() > 0 && userSetting.getRecordPath() == null) {
            logger.info("推流时发现尚未设置录像路径,从assist服务中读取");
            JSONObject info = assistRESTfulUtils.getInfo(mediaInfo, null);
            if (info != null && info.getInteger("code") != null && info.getInteger("code") == 0 ) {
                JSONObject dataJson = info.getJSONObject("data");
                if (dataJson != null) {
                    String recordPath = dataJson.getString("record");
                    userSetting.setRecordPath(recordPath);
                    result.setMp4_save_path(recordPath);
                    // 修改zlm中的录像路径
                    if (mediaInfo.isAutoConfig()) {
                        taskExecutor.execute(() -> {
                            mediaServerService.setZLMConfig(mediaInfo, false);
                        });
                    }
                }
            }
        }
        if (param.getApp().equalsIgnoreCase("rtp")) {
@@ -339,13 +338,11 @@
            List<OnStreamChangedHookParam.MediaTrack> tracks = param.getTracks();
            // TODO 重构此处逻辑
            boolean isPush = false;
            if (param.isRegist()) {
                // 处理流注册的鉴权信息
                // 处理流注册的鉴权信息, 流注销这里不再删除鉴权信息,下次来了新的鉴权信息会对就的进行覆盖
                if (param.getOriginType() == OriginType.RTMP_PUSH.ordinal()
                        || param.getOriginType() == OriginType.RTSP_PUSH.ordinal()
                        || param.getOriginType() == OriginType.RTC_PUSH.ordinal()) {
                    isPush = true;
                    StreamAuthorityInfo streamAuthorityInfo = redisCatchStorage.getStreamAuthorityInfo(param.getApp(), param.getStream());
                    if (streamAuthorityInfo == null) {
                        streamAuthorityInfo = StreamAuthorityInfo.getInstanceByHook(param);
@@ -355,8 +352,6 @@
                    }
                    redisCatchStorage.updateStreamAuthorityInfo(param.getApp(), param.getStream(), streamAuthorityInfo);
                }
            } else {
                redisCatchStorage.removeStreamAuthorityInfo(param.getApp(), param.getStream());
            }
            if ("rtsp".equals(param.getSchema())) {
@@ -397,6 +392,9 @@
                                    || param.getOriginType() == OriginType.RTC_PUSH.ordinal()) {
                                param.setSeverId(userSetting.getServerId());
                                zlmMediaListManager.addPush(param);
                                // 冗余数据,自己系统中自用
                                redisCatchStorage.addPushListItem(param.getApp(), param.getStream(), param);
                            }
                        } else {
                            // 兼容流注销时类型从redis记录获取
@@ -405,6 +403,10 @@
                            if (onStreamChangedHookParam != null) {
                                type = OriginType.values()[onStreamChangedHookParam.getOriginType()].getType();
                                redisCatchStorage.removeStream(mediaInfo.getId(), type, param.getApp(), param.getStream());
                                if ("PUSH".equalsIgnoreCase(type)) {
                                    // 冗余数据,自己系统中自用
                                    redisCatchStorage.removePushListItem(param.getApp(), param.getStream(), param.getMediaServerId());
                                }
                            }
                            GbStream gbStream = storager.getGbStream(param.getApp(), param.getStream());
                            if (gbStream != null) {
@@ -609,7 +611,9 @@
                result.onTimeout(() -> {
                    logger.info("[ZLM HOOK] 预览流自动点播, 等待超时");
                    msg.setData(new HookResult(ErrorCode.ERROR100.getCode(), "点播超时"));
                    resultHolder.invokeResult(msg);
                    resultHolder.invokeAllResult(msg);
                    inviteStreamService.removeInviteInfoByDeviceAndChannel(InviteSessionType.PLAY, deviceId, channelId);
                    storager.stopPlay(deviceId, channelId);
                });
                resultHolder.put(key, uuid, result);
@@ -757,6 +761,21 @@
        return HookResult.SUCCESS();
    }
    /**
     * 录像完成事件
     */
    @ResponseBody
    @PostMapping(value = "/on_record_mp4", produces = "application/json;charset=UTF-8")
    public HookResult onRecordMp4(HttpServletRequest request, @RequestBody OnRecordMp4HookParam param) {
        logger.info("[ZLM HOOK] 录像完成事件:{}->{}", param.getMediaServerId(), param.getFile_path());
        taskExecutor.execute(() -> {
            cloudRecordService.addRecord(param);
        });
        return HookResult.SUCCESS();
    }
    private Map<String, String> urlParamToMap(String params) {
        HashMap<String, String> map = new HashMap<>();
        if (ObjectUtils.isEmpty(params)) {