# h265 **Repository Path**: kdisi_admin/h265 ## Basic Information - **Project Name**: h265 - **Description**: 接入海康nvr,摄像头。定时截图,转发成hls - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-03-09 - **Last Updated**: 2026-03-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # H.265 摄像头截图与播放管理平台(Go + React) > 本文档基于当前代码实现重写,覆盖后端架构、前端页面、接口、配置与部署方式。 ## 1. 项目概述 这是一个面向海康 RTSP 场景的“截图调度 + 实时播放 + 固定推流转发 + 用户管理”平台,主要能力: - 周期截图:按摄像头独立周期抓取最新截图。 - 实时播放:前端预览墙支持 `1/4/9/16` 分屏和全屏。 - 固定推流:将任意摄像头绑定到固定 8 路 URL,供第三方 Web 调用。 - 用户管理:登录、用户新增、密码重置、删除(保护默认管理员)。 - 高并发稳定性:任务队列、并发限制、调度错峰、丢弃计数、超时控制。 --- ## 2. 当前功能总览 ### 2.1 后端能力 - 鉴权与会话:`auth_users` 表 + 内存 token 会话。 - 摄像头配置:增删改查、启停、立即截图。 - NVR 配置:列表与新增(自动从 RTSP 回填关联)。 - 调度器: - worker 池并发抓图 - 有界队列 + 丢弃计数 - 全局出队最小间隔(削峰) - 每路稳定相位(避免同秒扎堆) - 抓图引擎: - 首选 `CaptureHook`(如 ZLM 快照) - 失败后自动回退 ffmpeg 兜底 - 支持 `cpu/gpu` 模式、`FFMPEG_THREADS` 限制 - 固定推流 8 路: - 绑定关系持久化 - 公共转发 URL:`/forward/live/{1..8}.live.ts` ### 2.2 前端能力 - `视频管理` 下拉菜单包含: - `截图查看` - `配置界面` - `视频播放` - `推流选择` - `用户管理` 独立入口。 - 关键页面: - 截图查看:卡片化看图、懒加载、分页、手动截图。 - 视频播放:左侧摄像头扁平列表筛选,右侧预览墙分屏。 - 推流选择:固定 8 路槽位绑定摄像头,展示固定 URL。 - 用户管理:新增用户与重置密码改为弹窗操作。 - 首屏性能优化:非主页面按需懒加载(代码分包)。 --- ## 3. 代码结构分析(全仓) ## 3.1 后端目录分析(`backend/internal`) | 模块 | 主要职责 | |---|---| | `api/` | HTTP 路由、鉴权中间件、业务接口、静态托管、固定推流转发 | | `snapshot/` | 截图调度器(队列、分发、worker、ffmpeg/Hook 抓图) | | `store/` | 摄像头/NVR 存储抽象(内存 + JSON + SQLite 同步) | | `configdb/` | 通用配置项存储(`config_items`) | | `auth/` | 用户认证服务(`auth_users` + token session) | | `zlm/` | ZLMediaKit 对接(代理流注册/释放、快照调用) | | `model/` | 核心数据结构(Camera/NVR) | | `clock/` | 时间函数封装,方便测试和统一时间格式 | ### 3.1.1 启动主链路(`backend/main.go`) 1. 读取环境变量构建 `appConfig`。 2. 初始化 `store/configdb/auth/scheduler/zlm`。 3. 将运行参数写入 `config_items`。 4. 将摄像头列表同步给调度器。 5. 启动 HTTP 服务(可托管前端静态资源)。 ### 3.1.2 调度器核心策略(`snapshot/`) - `dispatch` 与 `tasks` 双通道模型: - `dispatch`:有界队列(承压) - `tasks`:worker 消费队列 - `DispatchMinGap`:全局任务最小出队间隔,降低瞬时峰值。 - `stablePhaseDelay`:同周期摄像头按 ID 哈希错峰启动。 - `runMux`:同一摄像头同时只允许一个抓图任务。 - `TriggerNow`:支持手动截图,未启用任务也可即时入队。 ### 3.1.3 抓图执行顺序(`snapshot/scheduler_capture.go`) 1. 先尝试 `CaptureHook`(例如 ZLM 快照)。 2. Hook 失败则回退 ffmpeg。 3. 成功后原子替换临时文件并更新运行态字段。 ### 3.1.4 API 分层(`api/`) - `server.go`:路由注册、公开/鉴权接口分组。 - `server_auth.go`:登录、鉴权、登出。 - `server_camera.go`:摄像头/NVR/统计。 - `server_user.go`:用户管理。 - `server_stream_forward.go`:8 路固定推流绑定与转发。 - `server_static.go`:前端静态资源与 SPA fallback。 ## 3.2 前端目录分析(`frontend/src`) | 模块 | 主要职责 | |---|---| | `App.jsx` | 页面路由切换、登录态守卫、全局数据流接线 | | `components/` | 页面组件与业务视图 | | `components/videoWall/` | 播放墙侧边筛选、分屏舞台、播放器逻辑 | | `hooks/useCameraConsole.js` | 摄像头主业务状态与操作封装 | | `hooks/useAPIClient.js` | 统一 API 请求封装(鉴权/错误处理) | | `hooks/useAuthSession.js` | 登录态、token 管理 | | `hooks/useUserAdmin.js` | 用户管理请求逻辑 | | `hooks/useStreamForward.js` | 固定推流槽位请求逻辑 | | `utils/` | HTTP 解析与摄像头业务工具函数 | --- ## 4. 数据存储设计 ### 4.1 SQLite(`CONFIG_DB_FILE`) - `camera_configs`:摄像头配置 - `nvr_configs`:NVR 配置 - `auth_users`:用户与密码哈希 - `config_items`:运行参数及通用配置项(含固定推流槽位) ### 4.2 JSON(`DATA_FILE`) - `backend/data/cameras.json` - 用于摄像头配置落盘快照与兼容迁移。 ### 4.3 截图目录(`SNAPSHOT_DIR`) 按时间层级落盘: `snapshots/YYYY/MM/DD/HH/mm/<摄像头名>.jpg` 接口返回 `latest_image` 字段用于前端展示。 --- ## 5. 页面说明(最新) ### 5.1 视频管理(下拉菜单) - `截图查看` - 左侧 NVR 选择,右侧卡片网格查看最新截图。 - 支持刷新、搜索、分页、手动截图。 - 图片懒加载,减少长列表渲染压力。 - `配置界面` - 摄像头配置管理(新增、编辑、删除、启停)。 - NVR 配置新增。 - `视频播放` - 左侧是**扁平摄像头列表**(按 NVR/关键字/启停筛选)。 - 右侧预览墙支持 `1/4/9/16` 分屏、全屏最大化。 - `推流选择` - 固定 8 路槽位绑定摄像头。 - 每个槽位显示固定 URL,可复制/打开验证。 ### 5.2 用户管理(独立入口) - 用户列表展示。 - 新增用户:弹窗。 - 重置密码:弹窗。 - 删除用户:禁止删除当前登录用户;默认 admin 受保护。 --- ## 6. 快速启动 ## 6.1 后端 ```bash cd backend go mod tidy go run . ``` 默认地址:`http://localhost:8080` ## 6.2 前端开发模式 ```bash cd frontend npm install npm run dev ``` 默认地址:`http://localhost:5173` 如后端不在本机: ```bash cd frontend VITE_API_BASE=http://your-host:8080 npm run dev ``` 如播放 TS 流地址不是 `http://:8081`: ```bash cd frontend VITE_ZLM_HTTP_BASE=http://your-host:8081 npm run dev ``` ## 6.3 单端口部署(推荐) ```bash cd frontend npm install npm run build cd ../backend go run . ``` 后端会托管 `frontend/dist`,统一端口访问。 --- ## 7. 环境变量(后端) | 变量 | 默认值 | 说明 | |---|---|---| | `LISTEN_ADDR` | `:8080` | 服务监听地址 | | `DATA_FILE` | `data/cameras.json` | 摄像头 JSON 落盘 | | `CONFIG_DB_FILE` | `data/config.db` | SQLite 文件 | | `SNAPSHOT_DIR` | `snapshots` | 截图目录 | | `FRONTEND_DIST` | `../frontend/dist` | 前端静态资源目录 | | `MAX_CONCURRENT_GRABS` | `8` | 抓图 worker 并发 | | `TASK_QUEUE_SIZE` | `MAX_CONCURRENT_GRABS*4` | 调度队列长度 | | `SNAPSHOT_DISPATCH_GAP_MS` | `80` | 全局出队最小间隔(毫秒) | | `COMMAND_TIMEOUT_SEC` | `12` | 单次抓图超时(秒) | | `FFMPEG_PATH` | `ffmpeg` | ffmpeg 路径 | | `FFMPEG_THREADS` | `1` | 单次抓图 ffmpeg 线程数 | | `CAPTURE_MODE` | `cpu` | `cpu/gpu` | | `CAPTURE_KEYFRAME_ONLY` | `false` | 是否仅关键帧抓图 | | `AUTH_DEFAULT_USER` | `admin` | 默认管理员用户名 | | `AUTH_DEFAULT_PASSWORD` | `admin123456` | 默认管理员密码(建议修改) | | `AUTH_TOKEN_TTL_HOURS` | `24` | token 有效期(小时) | | `ENABLE_ZLM_PROXY` | `false` | 是否启用 ZLM 代理 | | `ZLM_AUTO_REGISTER` | `false` | 是否自动注册代理流 | | `ZLM_STRICT` | `false` | 严格模式(代理失败是否回退) | | `ZLM_SNAP_ENABLED` | `false` | 是否启用 ZLM 快照 Hook | | `ZLM_SNAP_EXPIRE_SEC` | `1` | ZLM 快照过期秒数 | | `ZLM_SNAP_MAX_CONCURRENT` | `4` | ZLM 快照并发上限(0=不限制) | | `ZLM_SNAP_FAIL_COOLDOWN_MS` | `1500` | ZLM 快照失败熔断窗口 | | `ZLM_API_BASE` | `http://127.0.0.1:80` | ZLM API 地址 | | `ZLM_SECRET` | `` | ZLM API 密钥 | | `ZLM_APP` | `live` | 流应用名 | | `ZLM_VHOST` | `__defaultVhost__` | vhost | | `ZLM_PROXY_RTSP_TEMPLATE` | `rtsp://127.0.0.1:554/live/%s` | 代理 RTSP 模板 | | `ZLM_HTTP_TIMEOUT_SEC` | `5` | ZLM HTTP 超时 | --- ## 8. API 说明(按当前代码) ### 8.1 公开接口(无需鉴权) - `GET /api/health` - `POST /api/auth/login` - `GET /forward/live/{slot}.live.ts`(固定推流槽位转发,`slot=1..8`) - `GET /snapshots/*`(截图静态文件) ### 8.2 鉴权接口(Bearer Token) - 认证 - `GET /api/auth/me` - `POST /api/auth/logout` - 用户管理 - `GET /api/users` - `POST /api/users` - `PUT /api/users/{username}/password` - `DELETE /api/users/{username}` - 固定推流配置 - `GET /api/stream-forwards` - `PUT /api/stream-forwards/{slot}` - 摄像头/NVR/统计 - `GET /api/cameras` - `POST /api/cameras` - `PUT /api/cameras/{id}` - `DELETE /api/cameras/{id}` - `POST /api/cameras/{id}/enable` - `POST /api/cameras/{id}/disable` - `POST /api/cameras/{id}/snapshot` - `GET /api/stats` - `GET /api/configs` - `GET /api/nvrs` - `POST /api/nvrs` 鉴权头格式: ```text Authorization: Bearer ``` --- ## 9. 固定推流(8 路)使用说明 1. 进入前端 `推流选择` 页面。 2. 在槽位 1~8 中选择摄像头并保存。 3. 第三方前端可直接访问固定地址: ```text /forward/live/1.live.ts /forward/live/2.live.ts ... /forward/live/8.live.ts ``` 说明: - 槽位为空时访问会返回 `slot not configured`。 - 槽位绑定关系持久化到 `config_items`。 --- ## 10. 性能与稳定性建议 - `MAX_CONCURRENT_GRABS`:按 CPU 与码流复杂度调优(建议从 8~16 起步)。 - `SNAPSHOT_DISPATCH_GAP_MS`:CPU 突发高时增大(例如 120~300)。 - `FFMPEG_THREADS`:建议保持 `1`,优先抑制瞬时多核冲高。 - `ZLM_SNAP_MAX_CONCURRENT`:MediaServer 压力大时调小。 - 截图周期建议 `>= 5s`,常见 `8~15s`。 前端侧已做: - 页面懒加载(降低首包体积)。 - 截图页图片懒加载。 - 同摄像头重复“立即截图”短时间抑制。 --- ## 11. 脚本与运维 ### 11.1 批量导入脚本 - `backend/scripts/bulk_add_hik_nvr.sh` - `backend/scripts/pressure_test_queue.sh` - `backend/scripts/apply_nvr_credentials.py` ### 11.2 systemd 用户服务(示例) ```bash # 重启 systemctl --user restart h265-backend.service # 状态 systemctl --user status h265-backend.service --no-pager # 日志 journalctl --user -u h265-backend.service -n 100 --no-pager ``` --- ## 12. 默认账号与安全建议 默认账号: - 用户名:`admin` - 密码:`admin123456` 建议: - 首次部署后立即修改默认密码。 - 在可信内网环境部署,或在网关侧增加访问控制。 - 若对外暴露,请加反向代理 TLS 与鉴权策略。