☰
WebGL下AVProVideo播放海康RTSP实时流:转码与低延迟实践
2026/10/18 22:20:35 网站建设 项目流程

简介:这份资源面向需要在Unity WebGL平台播放海康威视监控实时画面的开发者,核心是重写Http请求模块并接入无水印版AVProVideo,解决WebGL环境下视频流播放与发布配置的难题。包内共701个文件,以cs脚本、meta、asset、so配置、dll、shader、aar与mat等为主,涵盖Unity工程资源、Android依赖库、着色器与配置文件,压缩包约80.17MB。作者提供了发布WebGL所需的设置指导配置文件,只需手动修改Http请求配表字段中的值,即可正常发布运行,本地部署服务采用nginx,有需要也可联系作者获取。目前已有1213人学习下载,适合具备一定Unity与C#基础、正在做安防监控或流媒体播放项目的开发者参考,可借此快速打通海康设备取流、AVProVideo播放与WebGL发布链路,减少环境配置与请求模块调试的试错成本。

1. 从一次监控画面接入翻车说起:WebGL 里播海康实时流到底难在哪

去年帮某实验室做一个设备监控看板,需求很明确:在浏览器里直接看海康摄像头的实时画面,还要叠加设备状态标签。第一版方案想当然地用了 Video 标签直接怼 RTSP 地址,结果浏览器根本不认这个协议,页面一片黑。后来换成转码推流,延迟又高得离谱,操作员点一下按钮,画面要等三四秒才动。最后落到 Unity WebGL + AVProVideo 这套组合上,才算把延迟压到可接受范围。这个 Demo 要解决的核心问题就一个:在 WebGL 平台下,用 AVProVideo 播放海康设备的实时画面,适合正在做安防监控类毕设、课设,或者需要快速验证浏览器端视频接入方案的开发者。它不是一个完整的监控系统,而是一个能跑通的最小闭环,把最难的协议转换和渲染链路先趟平。

2. 需求拆解与技术选型:为什么是 WebGL + AVProVideo + 海康

2.1 三个硬性约束决定了技术路线

这个项目的需求边界其实很清晰,但每一条都卡得很死。第一,运行环境必须是浏览器,不能要求用户装客户端,这是 WebGL 的硬性前提。第二,视频源是海康设备,走的是 RTSP over TCP,浏览器原生不支持这个协议,必须做协议转换。第三,实时性要求高,延迟超过两秒操作员就会觉得“卡”,体验直接崩掉。

把这三条摆在一起,可选方案其实不多。纯前端方案用 flv.js 或 hls.js 播 HTTP-FLV 或 HLS,延迟通常在 2 到 5 秒,而且海康设备默认不输出这两种格式,需要额外转码服务。Electron 方案能直接调 ffmpeg,但部署体积大,不符合“浏览器直接打开”的要求。Unity WebGL 方案的优势在于,AVProVideo 插件本身封装了底层解码逻辑,配合转码服务把 RTSP 转成 WebGL 友好的格式,能在浏览器里拿到接近原生的播放体验。

这里有个容易踩的坑:很多人以为 AVProVideo 能直接播 RTSP,其实在 WebGL 平台下它依赖的是浏览器提供的媒体能力,最终播放的还是 HTTP 协议的视频流。所以转码这一步绕不开,区别只是转成什么格式、用什么工具转。

2.2 AVProVideo 在 WebGL 下的能力边界

AVProVideo 是一个跨平台的视频播放插件,在 Windows、macOS、iOS、Android 上都有不错的原生解码支持。但到了 WebGL 平台,它的实现方式变了——底层走的是 HTML5 Video 元素或者 MediaSource Extensions。这意味着两件事:一是支持的视频格式受浏览器限制,H.264 加 AAC 的 MP4 或 FLV 最稳;二是不能依赖硬件解码,性能取决于浏览器和机器配置。

我一般会先确认目标浏览器的媒体能力,Chrome 和 Edge 对 MSE 支持最好,Firefox 次之,Safari 在 WebGL 下的视频播放限制比较多。如果项目要求兼容 Safari,转码格式最好选 HLS,虽然延迟会高一点,但兼容性有保障。

提示:在 WebGL 平台下,AVProVideo 的播放能力本质上受限于浏览器,不要指望它能像原生平台那样直接解 RTSP 或 RTMP。

2.3 海康设备侧的取流方式选择

海康设备取流一般有三种方式:RTSP、SDK 回调、ISAPI 事件。这个 Demo 用的是 RTSP,因为它是设备默认开启的,不需要额外集成 SDK,跨平台性也最好。RTSP 地址的格式通常是:

rtsp://[username]:[password]@[ip]:[port]/Streaming/Channels/[channelID]

其中 channelID 的规则是:主码流用 101,子码流用 102,通道号从 1 开始。比如通道 1 的主码流就是 101,通道 2 的主码流是 201。子码流的分辨率低、码率小,适合在 WebGL 里做多路预览;主码流清晰度高,适合单路放大查看。

实际取流时还要注意鉴权方式,海康新固件默认走 digest 认证,老固件可能是 basic。如果转码服务连不上流,先检查认证方式是否匹配,这个坑我踩过不止一次。

3. 总体架构设计:从 RTSP 到 WebGL 的完整链路

3.1 四层结构拆开看每一环的职责

整个链路可以拆成四层:设备层、转码层、播放层、应用层。设备层就是海康摄像头,负责输出 RTSP 流。转码层负责把 RTSP 转成浏览器能播的格式,这个 Demo 里用的是 HTTP-FLV,因为延迟比 HLS 低,Chrome 和 Edge 都支持。播放层是 Unity WebGL 里的 AVProVideo 组件,负责拉流和解码。应用层是 Unity 里的 C# 脚本,负责控制播放、切换通道、叠加 UI。

这四层里最容易出问题的是转码层,因为它涉及到协议转换和进程管理。转码服务如果挂了,整个链路就断了。所以通常的做法是加一个健康检查接口,Unity 侧定时轮询,发现转码服务不可用就自动重连。

3.2 转码服务的配置与启动参数

转码服务用 ffmpeg 就能搭,核心命令如下:

ffmpeg -rtsp_transport tcp \ -i "rtsp://admin:password@192.168.1.64:554/Streaming/Channels/101" \ -c:v libx264 -preset ultrafast -tune zerolatency \ -c:a aac -ar 44100 -b:a 64k \ -f flv -flvflags no_duration_filesize \ "http://0.0.0.0:8080/live/stream1.flv"

参数说明:-rtsp_transport tcp强制走 TCP,避免 UDP 丢包导致花屏;-preset ultrafast和-tune zerolatency是降低延迟的关键,牺牲一点压缩率换实时性;-f flv指定输出格式为 FLV,配合 HTTP 服务就能给浏览器拉流。-flvflags no_duration_filesize是为了让 FLV 流可以持续输出,不会因为缺少时长信息而中断。

这个命令跑起来后,ffmpeg 会监听 8080 端口,Unity 侧通过http://localhost:8080/live/stream1.flv就能拉到流。实际部署时可以把 ffmpeg 包成一个服务,用 systemd 或 supervisor 管理,挂了自动重启。

3.3 Unity 侧 AVProVideo 的初始化流程

Unity 里的播放控制脚本主要做三件事:初始化 MediaPlayer、设置视频路径、处理播放事件。核心代码如下:

using RenderHeads.Media.AVProVideo; using UnityEngine; public class HikvisionPlayer : MonoBehaviour { public MediaPlayer mediaPlayer; public string streamUrl = "http://localhost:8080/live/stream1.flv"; void Start() { // 打开媒体,第二个参数是自动播放 mediaPlayer.OpenMedia(new MediaPath(streamUrl, MediaPathType.AbsolutePathOrURL), true); // 注册事件回调 mediaPlayer.Events.AddListener(OnVideoEvent); } void OnVideoEvent(MediaPlayer mp, MediaPlayerEvent.EventType eventType, ErrorCode code) { switch (eventType) { case MediaPlayerEvent.EventType.ReadyToPlay: Debug.Log("流已就绪,开始播放"); mp.Play(); break; case MediaPlayerEvent.EventType.Error: Debug.LogError($"播放出错: {code}"); // 这里可以加自动重连逻辑 Invoke(nameof(RetryOpen), 2f); break; } } void RetryOpen() { mediaPlayer.OpenMedia(new MediaPath(streamUrl, MediaPathType.AbsolutePathOrURL), true); } }

这段代码的关键点在于事件回调的处理。WebGL 下视频加载是异步的,不能调完OpenMedia就立刻Play,必须等ReadyToPlay事件。另外错误处理很重要,网络抖动或转码服务重启都会导致播放中断,加一个延迟重连能大幅提升稳定性。

3.4 多路视频的布局与性能取舍

监控场景通常要看多路画面,但 WebGL 下同时解码多路视频对性能压力很大。我的经验是,Chrome 里同时播 4 路 720p 的 FLV 流基本是上限,再多了就会掉帧。如果非要看更多路,可以用子码流降低分辨率,或者做成分页切换,一次只播 4 路。

布局上可以用 Unity 的 RawImage 做视频渲染目标,每个 MediaPlayer 对应一个 RawImage,然后用 GridLayoutGroup 自动排列。切换通道时不要销毁 MediaPlayer,而是复用现有的实例,只改 streamUrl,这样能避免频繁创建销毁带来的内存碎片。

4. 核心模块实现:播放控制、状态同步与异常处理

4.1 播放控制脚本的完整实现

播放控制不只是调 Play 和 Pause,还要处理通道切换、音量控制、截图这些操作。下面是一个更完整的控制脚本:

using UnityEngine; using RenderHeads.Media.AVProVideo; public class StreamController : MonoBehaviour { public MediaPlayer player; public string[] channelUrls; // 各通道的流地址 private int currentChannel = 0; public void SwitchChannel(int index) { if (index < 0 || index >= channelUrls.Length) return; currentChannel = index; // 先关闭当前流,再打开新流 player.CloseMedia(); player.OpenMedia(new MediaPath(channelUrls[index], MediaPathType.AbsolutePathOrURL), true); } public void CaptureFrame(string savePath) { // 截图功能,WebGL 下保存到 IndexedDB 或触发下载 Texture2D frame = player.ExtractFrame(null); if (frame != null) { byte[] bytes = frame.EncodeToPNG(); System.IO.File.WriteAllBytes(savePath, bytes); } } public void SetVolume(float volume) { player.Control.SetVolume(volume); } }

切换通道时先CloseMedia再OpenMedia是必须的,否则 AVProVideo 可能会保留上一个流的缓冲,导致画面错乱。截图功能在 WebGL 下要注意,不能直接写文件系统,得走浏览器下载或者存到 IndexedDB。

4.2 设备状态与视频画面的同步

监控画面通常要叠加设备名称、在线状态、时间戳这些信息。这些 UI 元素不要直接画在视频纹理上,而是用独立的 Canvas 叠加,这样视频分辨率变化时 UI 不会跟着变形。状态同步可以用 UnityWebRequest 定时请求后端接口,拿到设备状态后更新 Text 组件。

时间戳建议用视频播放时间而不是系统时间,因为转码和网络传输会引入延迟,用系统时间会对不上。AVProVideo 的player.Info.GetCurrentTime()能拿到当前播放时间,用它来驱动时间戳显示最准确。

4.3 断流重连与错误恢复机制

断流是监控场景的常态,网络抖动、设备重启、转码服务崩溃都会导致播放中断。一个健壮的重连机制应该包含三层:第一层是 AVProVideo 的错误事件回调,触发后延迟 2 秒重试;第二层是定时健康检查,每隔 10 秒请求一次转码服务的状态接口;第三层是转码服务自身的守护进程,ffmpeg 挂了自动拉起。

重连时要注意不要频繁重试,否则会给转码服务造成压力。我的做法是重试间隔指数退避,第一次 2 秒,第二次 4 秒,第三次 8 秒,最多重试 5 次。如果 5 次都失败,就在 UI 上显示“连接失败,请检查设备”,让用户手动重试。

5. 避坑与常见问题排查:那些让我熬夜的坑

5.1 画面黑屏但音频正常

现象:播放 FLV 流时能听到声音,但画面全黑。原因:通常是视频编码格式不被浏览器支持,比如 H.265 在 Chrome 里就无法通过 MSE 播放。解决:转码时强制指定-c:v libx264,确保输出 H.264。如果源流是 H.265,ffmpeg 会自动转码,但 CPU 占用会高很多,建议在设备侧直接配置成 H.264 输出。

5.2 延迟越播越大

现象:刚开始延迟还行,播了十几分钟后画面越来越滞后。原因:ffmpeg 默认会做缓冲,加上浏览器端的 MSE 缓冲,累积起来延迟就上去了。解决:ffmpeg 加-tune zerolatency和-fflags nobuffer,浏览器端在 AVProVideo 里设置player.Control.SetPlaybackRate(1.0f)并定期调用player.Control.Seek(player.Info.GetCurrentTime() + 0.1f)来追帧。不过追帧会导致画面跳跃,要权衡使用。

5.3 WebGL 构建后视频无法播放

现象:在 Unity Editor 里播放正常,构建成 WebGL 后视频黑屏。原因:WebGL 下跨域请求被浏览器拦截,转码服务的 HTTP 响应头缺少 CORS 配置。解决:在转码服务的 HTTP 服务器上加Access-Control-Allow-Origin: *,如果用的是 nginx 做代理,在配置里加add_header Access-Control-Allow-Origin *;。另外 Unity WebGL 的播放器设置里要勾选“Enable WebGL 2.0”和“Allow downloads”。

5.4 多路播放时浏览器崩溃

现象:同时播 4 路以上视频时,浏览器标签页崩溃。原因:WebGL 下每路视频都占用独立的解码器和纹理内存,超过浏览器限制就会崩。解决:控制同时播放的路数,Chrome 下建议不超过 4 路 720p。如果必须看更多,用子码流降低分辨率,或者做成分页切换。另外可以在 AVProVideo 里设置player.Control.SetTextureSize(1280, 720)限制纹理大小。

5.5 转码服务 CPU 占用过高

现象:ffmpeg 进程 CPU 占用跑到 100%,机器卡顿。原因:-preset ultrafast虽然快,但压缩率低,码率高,CPU 还是要做大量计算。解决:如果设备支持,直接输出 H.264 子码流,ffmpeg 只做协议转换不做转码,用-c:v copy直接复制视频流。这样 CPU 占用能降到 10% 以下,但要求源流本身就是浏览器支持的格式。

6. 验收与答辩:怎么证明这套方案真的能跑

6.1 验收标准要量化到具体指标

答辩时最怕被问“延迟多少”“能播几路”“稳定性怎么样”,这些都要有具体数据。我一般会准备一张验收表,现场演示时逐项对照:

验收项合格标准测试方法
首帧时间≤ 3 秒从点击播放到画面出现计时
端到端延迟≤ 2 秒用手机秒表对比画面和实际时间
同时播放路数≥ 4 路 720p逐步增加路数直到掉帧
断流恢复时间≤ 5 秒手动断开网络再恢复,计时
连续运行时长≥ 2 小时无崩溃挂机测试,记录内存和 CPU

这些数据最好提前跑三遍取平均值,答辩时直接报数字,比说“很流畅”有说服力得多。

6.2 演示流程的设计技巧

演示不要一上来就播视频,先讲架构图,让评委理解数据流向。然后按“单路播放 → 切换通道 → 多路同屏 → 断流重连”的顺序演示,每一步都对应一个技术点。断流重连这个环节特别加分,因为很多人的 Demo 一断流就废了,你能自动恢复就说明考虑得周全。

如果现场网络不稳定,提前准备一个本地视频文件作为备用源,万一 RTSP 连不上就切到本地文件,保证演示不翻车。这个习惯我每次答辩都会用,算是给自己留的后悔药。

6.3 答辩时高频问题的准备

评委常问的问题就那么几个:为什么不用 WebRTC?延迟具体怎么测的?多路播放性能瓶颈在哪?转码服务挂了怎么办?这些问题提前准备好答案,最好能结合实测数据回答。比如问为什么不用 WebRTC,可以说 WebRTC 虽然延迟低,但需要额外的信令服务器和 STUN/TURN 穿透,部署复杂度高,而这个 Demo 的目标是快速验证,HTTP-FLV 方案更轻量。

还有一个容易被忽略的点:代码里要留好注释和日志。答辩时评委可能会让你现场改一个参数,比如把延迟从 2 秒调到 1 秒,如果你代码里参数都是硬编码的,改起来就很狼狈。我一般会把关键参数抽成 public 变量,在 Inspector 里就能调,现场演示时改一下就能看到效果,评委印象分会高很多。

从那以后我每次做视频接入类的项目,都会先把验收表列出来,再倒推着写代码,这样不会漏掉关键指标。希望这套方案能帮到你,少走一些我踩过的弯路。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询