一、为什么浏览器不能直接播 RTSP
海康 / 大华等安防摄像头默认协议是 RTSP(Real Time Streaming Protocol),浏览器原生不支持 RTSP——Chrome / Edge / Firefox 都不行。
两条主流路径让浏览器能播摄像头:
- RTSP → RTMP → Flash / HLS(老方案)—— 需
nginx-rtmp-module+video.js / videojs-flash - RTSP → WebRTC / HLS(新方案)—— 用 ZLMediaKit / MediaMTX / go2rtc 媒体网关,浏览器原生 video 标签
本文讲第一种老方案——因为很多 2018-2020 年的项目(GB28181 视频监控平台)仍依赖此架构,且控制粒度细(按需推流 = 节省服务器资源)。
二、整体流程
| |
关键点:
- 按需推流 = 不点就不推,ffmpeg 进程按需启动 / 关闭
- FFmpeg = RTSP → RTMP 转协议 + 转封装
- Nginx-rtmp-module = RTMP 服务端,支持 HLS / DASH 切片
- vue-video-player = 浏览器播放器,带 RTMP 播放能力(需 videojs-flash 插件)
三、服务端部署
3.1 安装 Nginx + nginx-rtmp-module
Windows 编译 nginx-rtmp-module 较麻烦,推荐用现成的 Windows 集成版:
- 项目:nginx-rtmp-win32(GitHub 搜
nginx-rtmp-win32或nginx-rtmp-module-win32) - 下载后解压到
D:\nginx-ffmpeg\
3.2 nginx.conf 配置
| |
启动 nginx:
| |
测试 RTMP 端口:
| |
3.3 安装 FFmpeg
- 官方:https://ffmpeg.org/download.html#build-windows
- 推荐:gyan.dev 出品的 ffmpeg-release-essentials.zip
- 解压到
D:\nginx-ffmpeg\ffmpeg\bin\
把 D:\nginx-ffmpeg\ffmpeg\bin\ 加到 PATH。
四、FFmpeg 推流命令
| |
参数说明:
-i—— 输入 RTSP URL-b 4096k—— 视频比特率 4 Mbps-f flv—— 输出格式 FLV(RTMP 走 FLV 封装)-r 25—— 帧率 25 fps-s 1920x1080—— 分辨率-an—— 去掉音频(RTMP 推摄像头画面不需要音轨)- 最后是 RTMP URL,
<自定义名称>是 stream key
4.1 海康 RTSP URL 格式
| |
101 = 通道 1 主码流,102 = 通道 1 子码流。
五、Java 后端:调 FFmpeg 推流
5.1 项目结构
| |
5.2 ProcessBuilder 启动 FFmpeg
| |
5.3 获取 FFmpeg 进程 PID
| |
编码必须是 GBK——
tasklist.exe在中文 Windows 上输出是 GBK 编码,UTF-8 会乱码。
5.4 关流流程
| |
六、前端:Vue + vue-video-player
6.1 安装
| |
6.2 组件
| |
techOrder: ['flash', 'html5']—— 优先 Flash(RTMP),回退 HTML5(HLS)。但 Chrome 88+ 已经彻底禁用 Flash,所以生产请直接用 HLS。
七、按需推流:点击播放事件
| |
八、生产级方案升级
8.1 RTMP → HLS 切片
nginx-rtmp-module 自动把 RTMP 切成 HLS 切片:
- 浏览器用
http://server:8080/hls/cam001.m3u8播放 - 支持原生 video 标签,不用 Flash
- 延迟 5-10 秒(HLS 切片固定延迟)
8.2 用 ZLMediaKit 替代 nginx-rtmp
- 项目:https://github.com/ZLMediaKit/ZLMediaKit
- 支持 RTSP/RTMP/HLS/HTTP-FLV/WebRTC 全协议
- 延迟可调到 1 秒级
- 2018-2023 持续维护,生产首选
8.3 用 go2rtc 做"轻量转协议"
- 项目:https://github.com/alexxit/go2rtc
- 几乎零配置,Docker 一行起
- 支持 RTSP / RTMP / WebRTC / MSE / HLS 多协议转发
8.4 浏览器兼容性
| 协议 | Chrome | Edge | Firefox | Safari |
|---|---|---|---|---|
| RTMP | ❌(Flash 88+ 已删) | ❌ | ❌ | ❌ |
| HLS | ❌ | ❌ | ❌ | ✅ |
| HTTP-FLV | ✅(via MSE) | ✅ | ✅ | ❌ |
| WebRTC | ✅ | ✅ | ✅ | ✅ |
结论:生产请走 HLS(兼容 Safari)或 WebRTC(低延迟)。RTMP 已经是 2010 年代技术。
九、常见 5 个坑
- RTSP URL 认证失败——海康 RTSP 默认需要先在摄像头后台开启 RTSP 服务(路径:网络 → 平台接入 → RTSP)
- ffmpeg 推流卡顿——
-b 4096k太高,降到 2048k 或 1024k;或者-c:v copy不转码(前提是摄像头 H.264) - nginx-rtmp hls 切片生成失败——
hls_path目录nginx 没写权限 - videojs-flash 加载失败——Chrome 88+ 不再支持 Flash,改用 videojs-http-streaming (VHS) 播 HLS
- ffmpeg 进程关不掉——
taskkill /F /PID仍关不掉时,用wmic process where "name='ffmpeg.exe'" call terminate
十、总结
- 老方案 = FFmpeg + nginx-rtmp + video.js / vue-video-player(2018-2020 经典)
- 新方案 = ZLMediaKit / MediaMTX / go2rtc 直接做 RTSP → HLS/WebRTC(2021+ 推荐)
- 按需推流 = 不点就不开 ffmpeg,省 CPU 省带宽
- Java 调 FFmpeg 用
ProcessBuilder+tasklist /fi "imagename eq ffmpeg.exe"查 PID +taskkill /F /PID - 浏览器兼容:RTMP 已死(Flash 88+ 被删),走 HLS / WebRTC / HTTP-FLV
- 延迟排序:WebRTC (~500ms) < HTTP-FLV (~1s) < HLS (~5-10s) < RTMP (~1-2s)
