648540858
2023-07-25 59d8f2f9152b3c3106abae64bef343cde842f225
支持录像回放使用固定流地址以及自动点播录像回放
6个文件已修改
1个文件已添加
121 ■■■■ 已修改文件
sql/2.6.9更新.sql 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sql/初始化.sql 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java 94 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/service/IPlayService.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/genersoft/iot/vmp/utils/DateUtil.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sql/2.6.9¸üÐÂ.sql
New file
@@ -0,0 +1,2 @@
alter table wvp_device_channel
    change stream_id stream_id varying(255)
sql/³õʼ»¯.sql
@@ -79,7 +79,7 @@
                                    custom_longitude double precision,
                                    latitude double precision,
                                    custom_latitude double precision,
                                    stream_id character varying(50),
                                    stream_id character varying(255),
                                    device_id character varying(50) not null,
                                    parental character varying(50),
                                    has_audio bool default false,
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/notify/cmd/KeepaliveNotifyMessageHandler.java
@@ -59,6 +59,7 @@
            // æœªæ³¨å†Œçš„设备不做处理
            return;
        }
        logger.info("[收到心跳], device: {}", device.getDeviceId());
        SIPRequest request = (SIPRequest) evt.getRequest();
        // å›žå¤200 OK
        try {
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
@@ -24,8 +24,10 @@
import com.genersoft.iot.vmp.media.zlm.dto.hook.*;
import com.genersoft.iot.vmp.service.*;
import com.genersoft.iot.vmp.service.bean.MessageForPushChannel;
import com.genersoft.iot.vmp.service.bean.SSRCInfo;
import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
import com.genersoft.iot.vmp.storager.IVideoManagerStorage;
import com.genersoft.iot.vmp.utils.DateUtil;
import com.genersoft.iot.vmp.vmanager.bean.ErrorCode;
import com.genersoft.iot.vmp.vmanager.bean.OtherRtpSendInfo;
import com.genersoft.iot.vmp.vmanager.bean.StreamContent;
@@ -559,7 +561,7 @@
        if ("rtp".equals(param.getApp())) {
            String[] s = param.getStream().split("_");
            if (!mediaInfo.isRtpEnable() || s.length != 2) {
            if (!mediaInfo.isRtpEnable() || (s.length != 2 && s.length != 4)) {
                defaultResult.setResult(HookResult.SUCCESS());
                return defaultResult;
            }
@@ -575,33 +577,79 @@
                defaultResult.setResult(new HookResult(ErrorCode.ERROR404.getCode(), ErrorCode.ERROR404.getMsg()));
                return defaultResult;
            }
            logger.info("[ZLM HOOK] æµæœªæ‰¾åˆ°, å‘起自动点播:{}->{}->{}/{}", param.getMediaServerId(), param.getSchema(), param.getApp(), param.getStream());
            if (s.length == 2) {
                logger.info("[ZLM HOOK] é¢„览流未找到, å‘起自动点播:{}->{}->{}/{}", param.getMediaServerId(), param.getSchema(), param.getApp(), param.getStream());
            RequestMessage msg = new RequestMessage();
            String key = DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId;
            boolean exist = resultHolder.exist(key, null);
            msg.setKey(key);
            String uuid = UUID.randomUUID().toString();
            msg.setId(uuid);
            DeferredResult<HookResult> result = new DeferredResult<>(userSetting.getPlayTimeout().longValue());
                RequestMessage msg = new RequestMessage();
                String key = DeferredResultHolder.CALLBACK_CMD_PLAY + deviceId + channelId;
                boolean exist = resultHolder.exist(key, null);
                msg.setKey(key);
                String uuid = UUID.randomUUID().toString();
                msg.setId(uuid);
                DeferredResult<HookResult> result = new DeferredResult<>(userSetting.getPlayTimeout().longValue());
            result.onTimeout(() -> {
                logger.info("[ZLM HOOK] è‡ªåŠ¨ç‚¹æ’­, ç­‰å¾…è¶…æ—¶");
                // é‡Šæ”¾rtpserver
                msg.setData(new HookResult(ErrorCode.ERROR100.getCode(), "点播超时"));
                resultHolder.invokeResult(msg);
            });
            // å½•像查询以channelId作为deviceId查询
            resultHolder.put(key, uuid, result);
            if (!exist) {
                playService.play(mediaInfo, deviceId, channelId, null, (code, message, data) -> {
                    msg.setData(new HookResult(code, message));
                result.onTimeout(() -> {
                    logger.info("[ZLM HOOK] é¢„览流自动点播, ç­‰å¾…è¶…æ—¶");
                    // é‡Šæ”¾rtpserver
                    msg.setData(new HookResult(ErrorCode.ERROR100.getCode(), "点播超时"));
                    resultHolder.invokeResult(msg);
                });
                resultHolder.put(key, uuid, result);
                if (!exist) {
                    playService.play(mediaInfo, deviceId, channelId, null, (code, message, data) -> {
                        msg.setData(new HookResult(code, message));
                        resultHolder.invokeResult(msg);
                    });
                }
                return result;
            }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) {
                    defaultResult.setResult(HookResult.SUCCESS());
                    return defaultResult;
                }
                String startTime = DateUtil.urlToyyyy_MM_dd_HH_mm_ss(startTimeStr);
                String endTime = DateUtil.urlToyyyy_MM_dd_HH_mm_ss(endTimeStr);
                logger.info("[ZLM HOOK] å›žæ”¾æµæœªæ‰¾åˆ°, å‘起自动点播:{}->{}->{}/{}-{}-{}",
                        param.getMediaServerId(), param.getSchema(),
                        param.getApp(), param.getStream(),
                        startTime, endTime
                );
                RequestMessage msg = new RequestMessage();
                String key = DeferredResultHolder.CALLBACK_CMD_PLAYBACK + deviceId + channelId;
                boolean exist = resultHolder.exist(key, null);
                msg.setKey(key);
                String uuid = UUID.randomUUID().toString();
                msg.setId(uuid);
                DeferredResult<HookResult> result = new DeferredResult<>(userSetting.getPlayTimeout().longValue());
                result.onTimeout(() -> {
                    logger.info("[ZLM HOOK] å›žæ”¾æµè‡ªåŠ¨ç‚¹æ’­, ç­‰å¾…è¶…æ—¶");
                    // é‡Šæ”¾rtpserver
                    msg.setData(new HookResult(ErrorCode.ERROR100.getCode(), "点播超时"));
                    resultHolder.invokeResult(msg);
                });
                resultHolder.put(key, uuid, result);
                if (!exist) {
                    SSRCInfo ssrcInfo = mediaServerService.openRTPServer(mediaInfo, param.getStream(), null,
                            device.isSsrcCheck(),  true, 0, false, device.getStreamModeForParam());
                    playService.playBack(mediaInfo, ssrcInfo, deviceId, channelId, startTime, endTime, (code, message, data) -> {
                        msg.setData(new HookResult(code, message));
                        resultHolder.invokeResult(msg);
                    });
                }
                return result;
            }else {
                defaultResult.setResult(HookResult.SUCCESS());
                return defaultResult;
            }
            return result;
        } else {
            // æ‹‰æµä»£ç†
            StreamProxyItem streamProxyByAppAndStream = streamProxyService.getStreamProxyByAppAndStream(param.getApp(), param.getStream());
src/main/java/com/genersoft/iot/vmp/service/IPlayService.java
@@ -29,7 +29,6 @@
    void playBack(String deviceId, String channelId, String startTime, String endTime, ErrorCallback<Object> callback);
    void playBack(MediaServerItem mediaServerItem, SSRCInfo ssrcInfo, String deviceId, String channelId, String startTime, String endTime, ErrorCallback<Object> callback);
    void zlmServerOffline(String mediaServerId);
    void download(String deviceId, String channelId, String startTime, String endTime, int downloadSpeed, ErrorCallback<Object> callback);
@@ -44,4 +43,6 @@
    void resumeRtp(String streamId) throws ServiceException, InvalidArgumentException, ParseException, SipException;
    void getSnap(String deviceId, String channelId, String fileName, ErrorCallback errorCallback);
}
src/main/java/com/genersoft/iot/vmp/service/impl/PlayServiceImpl.java
@@ -539,7 +539,19 @@
            return;
        }
        MediaServerItem newMediaServerItem = getNewMediaServerItem(device);
        SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, null, null, device.isSsrcCheck(),  true, 0, false, device.getStreamModeForParam());
        String stream = null;
        if (newMediaServerItem.isRtpEnable()) {
            String startTimeStr = startTime.replace("-", "")
                    .replace(":", "")
                    .replace(" ", "");
            System.out.println(startTimeStr);
            String endTimeTimeStr = endTime.replace("-", "")
                    .replace(":", "")
                    .replace(" ", "");
            System.out.println(endTimeTimeStr);
            stream = deviceId + "_" + channelId + "_" + startTimeStr + "_" + endTimeTimeStr;
        }
        SSRCInfo ssrcInfo = mediaServerService.openRTPServer(newMediaServerItem, stream, null, device.isSsrcCheck(),  true, 0, false, device.getStreamModeForParam());
        playBack(newMediaServerItem, ssrcInfo, deviceId, channelId, startTime, endTime, callback);
    }
src/main/java/com/genersoft/iot/vmp/utils/DateUtil.java
@@ -53,6 +53,10 @@
        return formatter.format(formatterCompatibleISO8601.parse(formatTime));
    }
    public static String urlToyyyy_MM_dd_HH_mm_ss(String formatTime) {
        return formatter.format(urlFormatter.parse(formatTime));
    }
    /**
     * yyyy_MM_dd_HH_mm_ss è½¬æ—¶é—´æˆ³
     * @param formatTime
@@ -82,6 +86,7 @@
        return urlFormatter.format(nowDateTime);
    }
    /**
     * æ ¼å¼æ ¡éªŒ
     * @param timeStr æ—¶é—´å­—符串