概况
这个主要是参加“深圳 liveVideoStack” 的ppt的文字版的分享。
深圳 liveVideoStack
讲师介绍
关于Jessibuca
- 官网地址:jessibuca.com
- Demo: Demo
- Doc:Doc
- Github地址:Github
关于JessibucaPro
- 地址:JessibucaPro
- Demo: Demo
- AI:AI
- 插件:插件
进入主题
大家好:今天我给大家带来的分享的题目是:Web端专业级H264/H265 直播流播放器实现 - jessibucaPro 播放器实现。
本次分享主要介绍‘背景’,‘架构,兼容性,性能’,还有”展望未来“三个部分。
第一部分(背景)
直播行业概况
我们看下现在的直播行业概况。
目前主要使用到直播的三个领域,分别是监控平台,直播平台,还有互动直播。其中监控平台,例如道路车辆监控,马路安全监控平台,主要是安防领域,比如海康,大华等。
然后就是直播平台,比较典型的是斗鱼,虎牙,抖音这种面向c端的平台。最后就是互动直播领域,主要有在线教育,音视频会议这种,像腾讯会议,zoom等。
web端直播协议
目前web端支持的直播格式有:
- hls(m3u8+ts/mp4)
- HDL(flv)
- FMP4
- Raw(H264,H255)
web端支持的直播的协议有:
- HTTP
- WebSokcet
- WebTransport
- Webrtc
H.264 vs H.265
对比H.264 格式和 H.265 格式,可以看出
- H.264优势在于兼容性高,pc和移动端都支持。H.265兼容性低,兼容依赖浏览器版本和底层硬件支持。
- H.265的压缩比、视频质量、性能要高于H.264。
压缩比:同等分辨率情况下,H.265 所需要的带宽要低于h264所需的带宽。
视频质量:H.264能够支持到最高2k,但是H.265可以支持到4k。
性能:H.264的性能要远低于H.265。
H.264对比H.265兼容性如图:
红的完全不支持,暗绿色是部分支持(需要一定条件才能支持),绿色是完全支持。
对比可以发现:左边,H.264,一片绿,说明支持度非常高,对于pc端的chrome,edge,safari,firefox,opera,ie,移动端安卓的chrome,ios的safari都支持。
右边,H.265,只有小部分绿,大部分都是暗绿,依赖一定条件的支持,对于pc端,大部分浏览器(chrome,edge,opera,ie)需要底层硬件支持,firefox完全不支持,移动端安卓chrome也需要底层硬件支持,只有pc 端的safa和移动端的ios 上的safari支持。
Webassembly 兼容性
基本也是全绿,除了IE 。其他pc 和移动端都支持。
WebAssembly(缩写为 wasm)是一种使用非 JavaScript 代码,并使其在浏览器中运行的方法。这些代码可以是 C、C++ 或 Rust 等。它们会被编译进你的浏览器,在你的 CPU 上以接近原生的速度运行。这些代码的形式是二进制文件,你可以直接在 JavaScript 中将它们当作模块来用。
业务需求
业务所需:
- 水印-用来版权保护防盗录,内容识别等。
- 低延迟-安防监控,直播会议所需。
- 视频流加密-主要是为了保护直播流的安全。
- 电子放大-主要是安防安防领域所需。
- 广角渲染-广角摄像头,主要是安防安防领域所需。
- 音频g711a/u格式-摄像头支持的音频格式,主要是安防安防领域所需。
- 实时框-主要是ai识别画识图。
低延迟直播流播放器
在这些web端的需求和背景下,我们需要一款能够支持各种直播协议(http、websocket、webtransport等),支持H.264、H.265硬解码+软解码,支持丰富功能(水印、低延迟、视频流加密等)的直播流播放器。
第二部分(架构、兼容性、性能)
介绍完背景部分,第二部分,我们来看下播放器的架构,在浏览器兼容性兼容性的解决方案,以及一些性能优化部分。
架构
首先我们看下播放器的架构部分,整个播放器主要由7大模块组成。
左边是核心模块,从上到下,分别是Stream模块、Demux模块、Decoder模块、Render模块。右边扩展模块,从上到下,分别是UI模块、Crypto模块、Recorder模块。
Stream模块
主要是网络请求模块:支持http、websocket、webtransport、webrtc协议。借助web端提供的fetch、websocket、xmlhttprequest等方法请求到流数据。
目前播放器支持的请求协议有 15种格式:
- ws(s)-raw 即ws://host-name:port/jessica/live/test (该协议只对接了monibuca服务器,其他服务器需要额外对接)
- ws(s)-flv 即ws://host-name:port/jessica/live/test.flv(chrome下ip会报安全错误,建议域名形式访问,检查下端口范围chrome浏览器是否允许,chrome会默认禁用很多端口)
- http(s)-flv 即http://host-name:port/hdl/live/test.flv
- Hls 即http://host-name:port/hls/live/test.m3u8 (支持H264/H265)
- WebTransport 即wt://host-name:port/play/live/test (该协议只对接了monibuca服务器,其他服务器需要额外对接)
- Webrtc 即 webrtc://host-name:port/webrtc/play/live/test (支持H264/H265, 仅支持https://或者http://localhost环境)
- Webrtc-zlmediakit 即 webrtc://host-name:port/index/api/webrtc?app=live&stream=stream-name&type=play (支持H264, 仅支持https://或者http://localhost环境)
- Webrtc-srs 即 webrtc://host-name:port/rtc/v1/play/live/test (支持H264, 仅支持https://或者http://localhost环境)
- Webrtc-others 即 webrtc://host-name:port/live/test (支持H264, 仅支持https://或者http://localhost环境)
- http(s)-fmp4 即http://host-name:port/your-path/live/test.(f)mp4
- ws(s)-fmp4 即ws://host-name:port/your-path/live/test.(f)mp4
- http(s)-h264 即http://host-name:port/jessica/live/test.h264
- ws(s)-h264 即ws://host-name:port/jessica/live/test.h264
- http(s)-h265 即http://host-name:port/jessica/live/test.h265
- ws(s)-h265 即ws://host-name:port/jessica/live/test.h265
- ws(s)-mpeg4 即ws://host-name:port/your-path/live/test.mpeg4
从中可以小结下:
- 协议同时支持https、wss
- 同时支持H264和H265编码格式
- 支持webcodecs硬解码(H264+H265)和MSE硬解码(H264+H265)
- 支持HLS(H264+H265)软解码、硬解码
- 支持m7s webrtc(H264+H265(软解码、硬解码)),
- 支持zlmediakit webrtc(H264)
- 支持srs webrtc(H264)
- 支持others webrtc(H264)
- 支持加密流(国标SM4、m7s加密流)
- 支持裸流(H264+H265)
- 支持Fmp4格式(H264+H265)
- 支持mpeg4格式(H264)
Demux模块
这个模块主要的工作是:将流数据进行解封装出一帧一帧H264、H265数据。
目前播放器支持的封装格式有:
- hls (http) (m3u8+ts/mp4) 视频(H264、H265) 音频(AAC、MP3)
- Flv (http+ws) 视频(H264、H265) 音频(AAC、MP3、G711A、G711U)
- M7S (ws) 视频(H264、H265) 音频(AAC、MP3、G711A、G711U)
- FMP4 (http) 视频(H264、H265) 音频(AAC、MP3)
- MPEG4 (ws) 视频(H264)
- Raw (ws) 视频(H264、H265)
Decoder模块
decoder模块主要是负责解码,默认播放器支持三种解码模式(两种硬解码,一种软解码)
- MediaSource 硬解码
- Webcodec 硬解码
- ffmpeg(Webassembly) 软解码
MediaSource 硬解码
主要是将一帧一帧H264、H265数据再次封装成Fmp4片段,然后喂给MediaSource来通过播放器底层硬解码音视频数据。渲染在video标签上面。
Webcodec 硬解码
主要是将一帧一帧H264、H265数据解码成videoFrame对象,可以通过canvas 或者 video 渲染。
ffmpeg(Webassembly) 软解码
主要是将一帧一帧H264、H265数据解码成YUV数据,可以通过canvas 或者 video 渲染。
Render模块
主要是渲染模块,目前播放支持video标签+canvas标签渲染。
对于各个解码模块后续的渲染模块,支持程度:
解码器 | video渲染 | canvas渲染 |
---|---|---|
MediaSource | ✅ | ✅ |
Webcodec | ✅ | ✅ |
ffmpeg(Webassembly) | ✅ | ✅ |
UI模块
目前播放器支持的UI模块有:
- 全屏 测试地址
- 声音控制 测试地址
- 网速显示测试地址
- 截图 测试地址
- 进度条 测试地址
- 播放倍率 测试地址
- 显示比例 测试地址
- 视频录制 录制FLV、WEBM,录制Mp4
- 分辨率切换 测试地址
- ptz指令操作 测试地址
- 右键菜单 测试地址
- 性能面板 测试地址
- 电子放大 测试地址
- 快捷键
- 水印(局部,全屏,动态,幽灵)测试地址
Crypto模块
目前播放器支持的加密模式有
- m7s 私有格式 测试地址
- SM4 国标加密 测试地址
- XOR 加密
- 支持扩展加密其他私有加密格式
Recorder模块
目前播放器支持的录制格式有
- flv 格式 测试地址
- Webm格式 测试地址
- Mp4 格式 测试地址
兼容性
介绍完播放器的整体架构,接下来我们看下播放器在web端兼容性上面的解决方案。
主要分享6个业务场景,分别是:
- 电脑硬件不支持H265硬解码
- IOS不支持MediaSource硬解码
- 音频格式是G711a/G711u
- Webrtc如何播放H265的流
- 兼容国产系统/国产浏览器
- MediaRecorder不支持录制mp4(MPEG-4)格式
电脑硬件不支持H265硬解码
目前的现状是:
- chrome 107版本以上外加需要硬件支持才能够支持硬解码H265。
- edge 79版本以上外加需要硬件支持才能够支持硬解码H265。
- FireFox 直接就不支持。
播放器的解决方案是:
- 使用ffmpeg+webassembly,通过软解码来支持H265解码。
- 使用sharedArrayBuffer,来提升软解码性能。
- 使用SIMD指令集加速解码,来提升硬解码性能。
效果如下:
另外测试地址: 测试地址
IOS不支持MediaSource硬解码
目前的现状是:
- iPadOS 13+ 才支持。
- ios 完全不支持。
播放器的解决方案是:
- 使用ffmpeg+webassembly。
- IOS16.3+使用webcodec解码。
效果如下:
音频格式是G711a/G711u
目前的现状是:
- Fmp4只支持aac/mp3格式的音频,不支持G711a/G711u格式的音频。
播放器的解决方案是:
1.使用FFmpeg+Webassembly进行软解码,然后借助AudioContext进行播放。
Webrtc如何播放H265的流
目前的现状是:
- WebRTC本身只支持VP8、VP9、H264、AV1格式。
播放器的解决方案是:
- 流媒体服务器(monibuca)通过DataChannel传输音视频数据,借助MediaSource/Webcodec/Webassembly解码播放。
兼容国产系统/国产浏览器
目前的现状是:
- 国产操作系统(麒麟等)/浏览器(统信等),对于H264/H265硬解码支持度不够,使用的Chromium内核版本都比价低。
播放器的解决方案是:
- 当不支持硬解码的时候,使用ffmpeg+WebAssembly进行软解码播放。
MediaRecorder不支持录制mp4(MPEG-4)格式
目前的现状是:
- MediaRecorder只支持录制成webm格式文件。
播放器的解决方案是:
- 使用ffmpeg+WebAssembly录制成mp4格式文件。
测试地址:测试地址
性能
介绍完了播放器在web兼容性上面的解决方案,我们再看下播放器在性能优化上面的一些方案。
主要介绍四种优化方案:
- 低延迟优化
- Worker线程降低主线程压力
- 多线程软解码提升软解码性能
- OffscreenCanvas优化渲染
低延迟优化
为了保证低延迟,播放器设计实现了缓冲区JitterBuffer,添加延迟丢帧机制,添加网络延迟检测机制。
达到的效果:
通过尽可能的优化,播放器做到了,
- 首屏时间小于1s
- 公网环境网络稳定的情况下延迟小于1s
- 内网环境下可以通过配置使得延迟低于0.8s
Worker线程降低主线程压力
通过worker线程,播放器可以通过配置支持将网络请求模块stream,解封装模块demux,和解码模块decoder全部放在worker线程里面进行,然后将解码之后的数据传输到主线程进行渲染和播放。
达到的效果
多线程软解码提升软解码性能
开启多线程解码,借助多核来进行软解码,来提升解码性能。
首先需要再编译ffmpeg的时候添加多线程参数。然后在将ffmpeg编译打包成webassembly的时候,也需要配置多线程参数。在编写c的业务代码的时候也需要配置使用的多核数量,最后播放器在浏览器上面运行的时候,需在网站的相应头上面添加两个相应参数。这样播放器就使用多线程来软解码音视频了。
达到的效果
左边图是没有开启多线程的,右边的开启了多线程的。对比我们可以发现,例如同样是webassembly软解码265的1080p 在机器是cpu i7_8700k 显卡是rtx2080的机器上面可以支持同时4路流播放,但是如果开启了多线程,那就可以支持到8路流同时播放。性能翻倍了。
OffscreenCanvas优化渲染
最后,我们看下offscreen canvas 离屏画布。
支持两种模式:
transfer
worker 线程创建OffscreenCanvas,使用webgl进行绘制,然后将生成的ImageBitmap ,通过postmessage到主线程,然后借助canvas 进行渲染
commit
主线程创建OffscreenCanvas,然后通过postmesage将canvas句柄传递到worker线程,然后worker 线程使用webgl进行绘制渲染。
区别
区别就是transfer需要一直postmessage 传递数据,而commit模式只需要主线程一次将canvas句柄传递到worker线程。 根据业务情况采用不同的模式。
达到的效果
展望未来
介绍完了播放器在web端的一些性能优化,我们再看下展望未来。
播放器可以支持人脸识别,物品识别,让播放器端提供ai能力。可以支持马赛克检查,视频遮挡检查,黑屏、 绿屏检查。 来提升播放效果。
人脸识别、物品识别
对于人脸识别,物品识别,我们可以采用的方案有:opencv 、 mediapipe
- opencv 是一个跨平台的计算机视觉库,可以支持增强现实,人脸识别,动作识别等领域。底层库。
- mediapipe:谷歌基于opencv开发出来的功能强大的机器学习框架。 两个都可以借助webassembly 在web端跑运行。
人脸识别
人脸识别测试地址 测试地址
物品识别
物品识别测试地址 测试地址
马赛克检查,视频遮挡检查,黑屏、 绿屏检查
黑屏、绿屏、花屏、马赛克检查 测试地址 测试地址
遮挡物检查测试地址测试地址
最后
关于Jessibuca
- 官网地址:jessibuca.com
- Demo: Demo
- Doc:Doc
- Github地址:Github
关于JessibucaPro
- 地址:JessibucaPro
- Demo: Demo
- AI:AI
- 插件:插件
谢谢大家。