
简介面向需要在Chrome最新版中直接播放大华摄像头RTSP视频流的开发与运维人员这份插件资源集成了浏览器端播放能力与配套运行环境主要解决Chrome因安全策略无法原生播放RTSP流的问题。适用于家庭、商业及工业等安防监控场景包内共有2000个文件以JavaScript、TypeScript、JSON配置及Markdown文档为主并附带Node.js 14安装程序、jQuery示例源码和可直接运行的演示工程。整个压缩包约152.6MB包含完整插件代码、脚本与说明文档目录结构清晰便于按模块查阅。目前已有3144人学习下载借助演示工程与jQuery交互示例可快速掌握在Chrome中接入RTSP流的方法减少对第三方播放软件的依赖并能将此方案复用到自有监控系统中。1. Chrome 放不了 RTSP问题不在插件而在浏览器前阵子朋友公司上了一批大华摄像头运维想在大屏上直接看实时画面顺手双击浏览器里的rtsp://地址结果弹出来的不是画面而是错误提示。查了一圈地址没错、摄像头在线、网络也通问题出在 Chrome 根本不认 RTSP 拉流协议。标题里说的“大华摄像头播放插件”并不是某个官网现成的安装包而是一套“转流服务 Chrome 扩展”的组合方案先把摄像头 RTSP 流转成 Chrome 能播放的 HTTP-FLV 流再用扩展页面里的播放器拉流渲染。这篇文章写给安防项目集成、前端监控页面开发和运维排障的人从原理讲到你本地能跑通的最小命令最后是实际踩过的坑。2. 为什么 Chrome 拉不动 RTSP协议差异与三种可行播放链路2.1 RTSP 是一套会话控制协议不是浏览器媒体格式RTSP全称 Real Time Streaming Protocol它管的是“会话控制”播放、暂停、快进、停止这些操作。真正的音视频数据走的是 RTPReal-time Transport Protocol传输层一般用 UDP也可以切到 TCP。所以一个完整的 RTSP 流程是先通过 SDP 协商出视频编码、分辨率、传输端口再建立 RTP 通道持续传数据。Chrome 的媒体渲染管道只认 HTTP(S) 加载的媒体流包括 MP4、WebM、HLS以及通过扩展支持的 FLV。浏览器内部没有 RTSP 解复用模块更没有 RTP 解包逻辑。这不是大华一家的问题海康、宇视的摄像头流在 Chrome 里直接打开同样是黑屏或错误。安防行业做了这么多年 Web 监控大家默认的做法是把 RTSP 先“翻译”成浏览器认识的格式再交给页面播放器。常见做法是RTSP - 转流服务 - HTTP-FLV / HLS / WebRTC这部分工作由 ffmpeg 或专门的流媒体服务完成浏览器只做最后一步拉流和渲染。2.2 三种播放链路对比WebRTC、HTTP-FLV、HLS实际选型时大家会先定“延迟要求”再定链路。拿大华摄像头现场来说三种方案的差别非常明显方案端到端延迟浏览器兼容性集成成本适用场景RTSP 转 WebRTC0.3 1 秒Chrome 原生支持无需插件需要信令协商、ICE 穿透、媒体网关低延迟对讲、远程操控RTSP 转 HTTP-FLV1 3 秒flv.js 在 Chrome 下成熟稳定ffmpeg 一条命令即可推流监控大屏、实时预览RTSP 转 HLS5 10 秒移动端和电视都能播需要切片器延迟天然偏高回放、移动端查看RTSP 转 WebRTC 延迟最低但要做 SDP 交换和 NAT 穿透局域网还好公网环境够折腾。RTSP 转 HTTP-FLV 是监控场景最常见的做法flv.js 这个库在 Chrome 下跑得非常成熟代码量也最小。RTSP 转 HLS 兼容性最广但延迟高不适合“看着摄像头挪设备”这种实时操作。2.3 选型结论为什么不在插件里直接解码 RTSP有人会想既然写 Chrome 插件能不能在插件里用 WebAssembly 直接解码 RTSP技术上可以但工程上没必要。插件要负责 SDP 协商、RTP 解包、H.264 NAL 拆分、音视频同步等于重写一个播放器内核。而且 Chrome 扩展对媒体处理的限制很多更新迭代也麻烦。成熟项目的普遍做法是“外置转发、内置拉流”——ffmpeg 或 SRS 负责 RTSP 拉流和转封装Chrome 插件只负责拉 HTTP-FLV 并渲染。这样摄像头厂家换了、编码格式换了改动都集中在转流服务一侧插件不用动。3. 用 ffmpeg 把大华 RTSP 转成 flv最小命令与参数说明3.1 先确认大华 RTSP 地址格式大华摄像头的 RTSP 地址和别家不太一样标准格式是rtsp://用户名:密码摄像头IP:554/cam/realmonitor?channel1subtype0其中channel1是通道号多路摄像头从 1 开始递增。subtype0是主码流分辨率大码率高subtype1是子码流分辨率低更流畅。调试阶段优先用子码流等画面能稳定拉通再切主码流。注意一点这个地址里有符号在 bash 命令行里直接粘贴会被当成后台执行符所以 URL 一定要用双引号包起来。常见的翻车现场是写了命令回车后发现 ffmpeg 只输出版本信息因为 URL 被 shell 截断了。3.2 ffmpeg 转流最小命令用 ffmpeg 把大华 RTSP 转为 HTTP-FLV 输出到流媒体服务最小命令如下ffmpeg -rtsp_transport tcp \ -i rtsp://admin:password192.168.1.64:554/cam/realmonitor?channel1subtype1 \ -c copy \ -f flv \ http://127.0.0.1:8080/live/cam1.flv-rtsp_transport tcp指定用 TCP 拉取 RTSP。默认情况下 ffmpeg 用 UDP跨交换机或 WiFi 场景容易丢包画面会出现花屏和马赛克。TCP 更稳代价是占用带宽稍高。-c copy是流复制不重新编码直接把摄像头推来的 H.264 数据原样封装成 FLV。这个参数最省 CPU一台普通服务器转十几路都没问题。前提是摄像头编码是 H.264/H.265如果摄像头输出的是老的 MJPEG-c copy会失败需要改成-c:v libx264转码。-f flv指定输出封装格式。输出地址写的是http://127.0.0.1:8080/live/cam1.flv这是 HTTP-FLV 的拉流地址由流媒体服务SRS、mediamtx 都支持提供。如果本机装的是 SRS输入地址也可以写成rtmp://127.0.0.1/live/cam1SRS 会自动把它转成 HTTP-FLV 给插件拉取。3.3 转流服务常驻与自动重连直接用 ffmpeg 跑有一个问题摄像头断流或网络抖动ffmpeg 进程读到 EOF 就退出没人拉它回来。常见做法是写成 systemd 服务交给系统守护[Unit] DescriptionRTSP to FLV for Dahua Camera 1 Afternetwork-online.target [Service] Typesimple Restartalways RestartSec5 ExecStart/usr/bin/ffmpeg -rtsp_transport tcp -i rtsp://admin:password192.168.1.64:554/cam/realmonitor?channel1subtype1 -c copy -f flv http://127.0.0.1:8080/live/cam1.flv Userffmpeg [Install] WantedBymulti-user.targetRestartalways配合RestartSec5进程退出后 5 秒自动拉起。摄像头因为断电重启通常需要 30 到 60 秒才能重新提供 RTSP 服务RestartSec可以按现场摄像头启动时间调大一点。配置好后执行systemctl daemon-reload systemctl enable --now dahua-cam1即可生效。4. 写一个 Chrome 插件播放 RTSPflv.js 拉流与扩展封装4.1 插件到底在做什么标题说的“大华摄像头播放插件”本质上是一个 Chrome 扩展壳子加一个页面播放器。插件只做三件事读取摄像头地址表单、向转流服务发请求拿 FLV 流地址、调用 flv.js 把画面渲染到video标签。RTSP 的协议处理在 ffmpeg 那端已经完成插件绝不直接接触 RTSP 数据。4.2 manifest.json 最小配置MV3Chrome 最新版要求扩展使用 Manifest V3最小组件如下{ manifest_version: 3, name: Dahua RTSP Player, version: 1.0.0, action: { default_popup: popup.html }, permissions: [storage], host_permissions: [ http://127.0.0.1/*, http://*/* ] }permissions里只申请了storage用来记住上次填的摄像头地址。host_permissions写http://*/*是开发阶段最省事的做法让扩展能访问内网摄像头和转流服务。在chrome://extensions/页面开启“开发者模式”点“加载已解压的扩展程序”选文件夹即可安装。注意 MV3 已经移除了后台页面改用 Service Worker这里没用到后台逻辑就不赘述。4.3 popup 页面播放 flv核心代码在popup.html里放一个输入框和一个视频标签input idrtspUrl placeholderrtsp://user:passip:554/cam/realmonitor?channel1subtype1 / video idvideo controls muted/video script srcflv.min.js/script script srcpopup.js/scriptpopup.js里创建播放器const video document.getElementById(video); const flvPlayer flvjs.createPlayer({ type: flv, isLive: true, url: http://127.0.0.1:8080/live/cam1.flv }); flvPlayer.attachMediaElement(video); flvPlayer.load(); flvPlayer.play();type: flv告诉 flv.js 按 FLV 格式解封装。isLive: true必须设置直播流没有文件末尾flv.js 会按直播模式处理不会等待 seek 完成。url填的一定是转流服务输出的 HTTP-FLV 地址不能是rtsp://开头的原始地址。播放过程要监听错误事件做重连摄像头断线重连时 flv.js 不会自动恢复flvPlayer.on(flvjs.Events.ERROR, function (err) { console.warn(播放错误:, err); setTimeout(() { flvPlayer.unload(); flvPlayer.load(); flvPlayer.play(); }, 2000); });4.4 把地址写活配置页和参数传递不要硬编码url从表单读取后传给转流服务由服务端决定推流路径const rtspUrl document.getElementById(rtspUrl).value; fetch(http://127.0.0.1:8080/control/start?url encodeURIComponent(rtspUrl)) .then(r r.json()) .then(data { const playUrl http://127.0.0.1:8080/live/ data.streamId .flv; createFlvPlayer(playUrl); });这里的/control/start是转流服务暴露的控制接口SRS 有 HTTP APImediamtx 也有类似接口作用是按需启动 ffmpeg 推流。好处是插件输入一个 RTSP 地址后台动态生成对应 FLV 流扩展代码不用为每路摄像头写死配置。配合chrome.storage记住上次填的地址下次点开插件直接恢复播放状态体验接近原生监控软件。5. Chrome 播放 RTSP 避坑与排查从黑屏到花屏的 5 个实际问题5.1 黑屏 控制台报跨域现象页面不报错视频区域一片黑打开控制台看到CORS policy相关报错。原因HTTP-FLV 拉流时浏览器对跨域请求有严格限制转流服务没有返回Access-Control-Allow-Origin响应头。扩展页面的地址是chrome-extension://开头和http://127.0.0.1:8080属于跨域。解决在转流服务前面加一层 nginx 反代统一加响应头location /live/ { add_header Access-Control-Allow-Origin *; proxy_pass http://127.0.0.1:8080; }或者让 mediamtx / SRS 在配置里直接开启 CORS。调试时也可以临时用--disable-web-security启动 Chrome但那只是绕过问题不是上线方案。5.2 清晰度没问题但卡成 PPT现象画面能出但帧率很低移动的物体有严重拖影。原因地址里subtype0是主码流大华 400 万像素摄像头主码流可能到 4K 分辨率、8Mbps 码率局域网内多路同时拉、或者无线网络带宽不足帧率自然上不来。解决调试先用subtype1子码流。如果必须看主码流给 ffmpeg 加转码参数压一下码率ffmpeg -rtsp_transport tcp \ -i rtsp://admin:password192.168.1.64:554/cam/realmonitor?channel1subtype0 \ -c:v libx264 -b:v 2000k -preset ultrafast \ -c:a copy \ -f flv http://127.0.0.1:8080/live/cam1.flv-b:v 2000k把码率压到 2Mbps-preset ultrafast牺牲压缩率换编码速度实时监控场景优先保证低延迟。5.3 画面延迟越拖越大现象刚打开延迟 1 秒播放十分钟后延迟到 5 秒以上。原因flv.js 默认会缓冲数据来对抗网络抖动直播模式下如果一直累积 buffer延迟会逐渐拉大。解决创建播放器时关闭缓冲 stashflvPlayer flvjs.createPlayer({ type: flv, isLive: true, enableStashBuffer: false, autoCleanupSourceBuffer: true });enableStashBuffer: false是直播场景的关键参数关闭后延迟能稳定在 1 到 2 秒。但网络抖动时更容易出现卡顿所以要在实际网络质量基础上调不能盲关。如果现场 WiFi 丢包严重宁可保留一部分缓冲换流畅。5.4 Chrome 116 后内网请求被拦现象插件在本地机器上访问内网摄像头地址Chrome 控制台提示Private Network Access相关错误请求被阻断。原因Chrome 116 起收紧了 Private Network Access 策略公网或扩展页面访问内网资源需要预检预检不通过就拦截。很多内网监控项目第一次在最新版 Chrome 上跑的时候都会遇到。解决最省事是把转流服务、摄像头和 Chrome 扩展运行在同一个内网环境或者让转流服务响应预检请求头Access-Control-Allow-Private-Network: truenginx 里加add_header Access-Control-Allow-Private-Network true;即可。这个坑在 Chrome 更新后批量出现属于“不是代码写错是浏览器策略变了”的典型。5.5 摄像头重启后 ffmpeg 不自动回来现象现场断电摄像头恢复后页面一直转圈转流进程没起来。原因ffmpeg 读到流中断直接退出没有任何守护机制。很多人跑了个nohup ffmpeg ... 就以为完事了进程一退再无人拉起。解决用第三章的 systemd 配置Restartalways能兜底。如果不想上 systemd写个循环脚本也可以while true; do ffmpeg -rtsp_transport tcp \ -i rtsp://admin:password192.168.1.64:554/cam/realmonitor?channel1subtype1 \ -c copy \ -f flv http://127.0.0.1:8080/live/cam1.flv echo 转流进程退出10 秒后重启 sleep 10 done再配合 ffprobe 检查流是否真的恢复了但普通项目一般 systemd 就够了。注意别把RestartSec设太短摄像头启动慢的时候 5 秒拉起一次会一直空转。6. 本地起一个 RTSP 测试源来验证插件跑通环境后再接真实摄像头没有摄像头在手边的时候插件没法验证。常见做法是起一个本地 RTSP 测试源把链路完全打通后再换真实大华摄像头。用 mediamtx原 rtsp-simple-server起服务它默认监听 8554 端口提供 RTSP 拉流同时内置 HTTP-FLV 输出能力./mediamtx然后把一个本地视频文件循环推成 RTSP 测试流ffmpeg -re -stream_loop -1 -i test.mp4 -c copy -f rtsp rtsp://127.0.0.1:8554/test-stream_loop -1让视频文件无限循环-re按原速读取文件模拟实时流。推流成功后用 ffprobe 验证ffprobe -rtsp_transport tcp rtsp://127.0.0.1:8554/test能读到视频流信息说明测试源正常。然后把插件页面的地址填成rtsp://127.0.0.1:8554/test如果画面能出来就说明整个播放链路没有问题剩下的问题都出在摄像头和网络环境。延迟验证有个土办法手机秒表对着摄像头屏幕和手机同时开计时截图比较时间差。这个办法虽然不够精确但能直观判断 1 秒和 5 秒的差距。做这类项目我还有个习惯先文件源后真实摄像头。文件源画面稳定、地址不变出了任何问题都能立刻排除“摄像头编码异常”这个干扰项。等插件和转流服务本地跑透了再接大华摄像头做兼容验证此时剩下的问题大概率就是主码流码率、路由丢包这种现场环境问题。希望帮到你。本文还有配套的精品资源点击获取