package com.inspect.nvr.hik.vo; import lombok.Data; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; /** 海康实时预览所需的 FFmpeg、媒体网关和超时配置。 */ @Data @Component public class HikNvrLiveStreamConfigVo { /** FFmpeg 可执行文件路径。 */ @Value("${hik.playback.hls.ffmpeg-path:C:/tools/ffmpeg/bin/ffmpeg.exe}") private String ffmpegPath = "C:/tools/ffmpeg/bin/ffmpeg.exe"; /** ZLMediaKit RTMP 基础地址。 */ @Value("${hik.playback.hls.rtmp-base-url:rtmp://127.0.0.1:1935}") private String rtmpBaseUrl = "rtmp://127.0.0.1:1935"; /** ZLMediaKit HTTP/HLS 基础地址。 */ @Value("${hik.playback.hls.http-base-url:http://127.0.0.1:18081}") private String httpBaseUrl = "http://127.0.0.1:18081"; /** 服务端访问 ZLMediaKit HTTP API 的基础地址。 */ @Value("${hik.playback.hls.api-base-url:http://127.0.0.1:18081}") private String apiBaseUrl = "http://127.0.0.1:18081"; /** ZLMediaKit API 密钥,仅用于服务端就绪探测。 */ @Value("${hik.playback.hls.api-secret:}") private String apiSecret = ""; /** 实时流启动探测超时时间。现场实测流注册需 2~4 秒,网络闪断后更慢,默认 10 秒。 */ @Value("${hik.playback.live.startup-timeout-millis:10000}") private long startupTimeoutMillis = 10000L; /** 同一 NVR 相邻 RTSP 握手的最小间隔。 */ @Value("${hik.playback.live.start-spacing-millis:600}") private long startSpacingMillis = 600L; /** 每台 NVR 等待起流的最大任务数,不含正在执行的任务。 */ @Value("${hik.playback.live.max-start-queue-size:8}") private int maxStartQueueSize = 8; /** 单次 ZLMediaKit API 连接和读取超时时间。 */ @Value("${hik.playback.live.zlm-api-timeout-millis:300}") private int zlmApiTimeoutMillis = 300; /** * 单路实时流在返回失败前的最大尝试次数。 * *

现场实测:NVR 在 SETUP 阶段返回 500 后,同一 RTSP 地址稍后单独拉取可以成功, * 说明这类拒绝是瞬时可恢复的,因此允许有限次退避重试。

*/ @Value("${hik.playback.live.max-attempts:3}") private int maxAttempts = 3; /** 设备端拒绝后重试前等待设备释放上一次 RTSP 会话的基础时长。 */ @Value("${hik.playback.live.retry-release-wait-millis:1500}") private long retryReleaseWaitMillis = 1500L; /** 重试前等待设备释放会话的时长上限。 */ @Value("${hik.playback.live.retry-release-wait-max-millis:5000}") private long retryReleaseWaitMaxMillis = 5000L; /** 停流时等待 FFmpeg 优雅退出(发送 RTSP TEARDOWN)的最长时间。 */ @Value("${hik.playback.live.stop-grace-millis:2000}") private long stopGraceMillis = 2000L; /** 单台 NVR 允许同时播放的实时流上限,0 表示不限制。 */ @Value("${hik.playback.live.max-sessions-per-nvr:8}") private int maxSessionsPerNvr = 8; /** 是否回收长时间无人观看的实时流。 */ @Value("${hik.playback.live.idle-reap-enabled:true}") private boolean idleReapEnabled = true; /** 无人观看多少毫秒后回收实时流。 */ @Value("${hik.playback.live.idle-reader-timeout-millis:600000}") private long idleReaderTimeoutMillis = 600000L; /** * 实时预览是否优先直连摄像机取流。 * *

CVR(中心存储)等设备的远程转发额度很小,直连摄像机可以避开该瓶颈;直连不可达或 * 鉴权失败时会自动回退到原有的 IVS/NVR 取流路径。

*/ @Value("${hik.playback.live.prefer-camera-direct:true}") private boolean preferCameraDirect = true; /** 直连摄像机使用的 RTSP 端口。 */ @Value("${hik.playback.live.camera-rtsp-port:554}") private int cameraRtspPort = 554; /** 直连摄像机使用的账号;为空时沿用所属 NVR 的数据库账号。 */ @Value("${hik.playback.live.camera-username:}") private String cameraUsername = ""; /** 直连摄像机使用的密码;为空时沿用所属 NVR 的数据库密码。 */ @Value("${hik.playback.live.camera-password:}") private String cameraPassword = ""; /** 直连摄像机 RTSP 端口连通性探测超时时间。 */ @Value("${hik.playback.live.camera-probe-timeout-millis:500}") private int cameraProbeTimeoutMillis = 500; /** * 同一 IP 多通道相机的相机内通道分配顺序。 * *

{@code asc}(默认)按平台通道编码升序分配 1..N,{@code desc} 反向。 * 双光谱相机优先按名称判断镜头(热成像/测温 → 相机通道 1,可见光 → 2), * 名称无法区分时才使用本顺序;现场若发现两个镜头画面互换,改成 {@code desc} 即可。

*/ @Value("${hik.playback.live.camera-channel-order:asc}") private String cameraChannelOrder = "asc"; }