Web端专业级H264/H265 直播流播放器实现-JessibucaPro播放器

原创
2023/11/30 17:37
阅读数 29

概况

这个主要是参加“深圳 liveVideoStack” 的ppt的文字版的分享。


进入主题

大家好:今天我给大家带来的分享的题目是: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 格式,可以看出

  1. H.264优势在于兼容性高,pc和移动端都支持。H.265兼容性低,兼容依赖浏览器版本和底层硬件支持。
  2. 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等方法请求到流数据。

图- stream

目前播放器支持的请求协议有 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硬解码

目前的现状是:

  1. chrome 107版本以上外加需要硬件支持才能够支持硬解码H265。
  2. edge 79版本以上外加需要硬件支持才能够支持硬解码H265。
  3. FireFox 直接就不支持。

播放器的解决方案是:

  1. 使用ffmpeg+webassembly,通过软解码来支持H265解码。
  2. 使用sharedArrayBuffer,来提升软解码性能。
  3. 使用SIMD指令集加速解码,来提升硬解码性能。

效果如下:


IOS不支持MediaSource硬解码

目前的现状是:

  1. iPadOS 13+ 才支持。
  2. ios 完全不支持。

播放器的解决方案是:

  1. 使用ffmpeg+webassembly。
  2. IOS16.3+使用webcodec解码。

效果如下:

音频格式是G711a/G711u

目前的现状是:

  1. Fmp4只支持aac/mp3格式的音频,不支持G711a/G711u格式的音频。

播放器的解决方案是:

1.使用FFmpeg+Webassembly进行软解码,然后借助AudioContext进行播放。

Webrtc如何播放H265的流

目前的现状是:

  1. WebRTC本身只支持VP8、VP9、H264、AV1格式。

播放器的解决方案是:

  1. 流媒体服务器(monibuca)通过DataChannel传输音视频数据,借助MediaSource/Webcodec/Webassembly解码播放。

兼容国产系统/国产浏览器

目前的现状是:

  1. 国产操作系统(麒麟等)/浏览器(统信等),对于H264/H265硬解码支持度不够,使用的Chromium内核版本都比价低。

播放器的解决方案是:

  1. 当不支持硬解码的时候,使用ffmpeg+WebAssembly进行软解码播放。

MediaRecorder不支持录制mp4(MPEG-4)格式

目前的现状是:

  1. MediaRecorder只支持录制成webm格式文件。

播放器的解决方案是:

  1. 使用ffmpeg+WebAssembly录制成mp4格式文件。


性能

介绍完了播放器在web兼容性上面的解决方案,我们再看下播放器在性能优化上面的一些方案。

主要介绍四种优化方案:

  1. 低延迟优化
  2. Worker线程降低主线程压力
  3. 多线程软解码提升软解码性能
  4. OffscreenCanvas优化渲染

低延迟优化

为了保证低延迟,播放器设计实现了缓冲区JitterBuffer,添加延迟丢帧机制,添加网络延迟检测机制。

达到的效果:

通过尽可能的优化,播放器做到了,

  1. 首屏时间小于1s
  2. 公网环境网络稳定的情况下延迟小于1s
  3. 内网环境下可以通过配置使得延迟低于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

  1. opencv 是一个跨平台的计算机视觉库,可以支持增强现实,人脸识别,动作识别等领域。底层库。
  2. mediapipe:谷歌基于opencv开发出来的功能强大的机器学习框架。两个都可以借助webassembly 在web端跑运行。

人脸识别


物品识别


马赛克检查,视频遮挡检查,黑屏、 绿屏检查



最后

谢谢大家。




展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部