Webrtc播放H265的技术探索(datachannel+wasm)

news/2024/11/15 13:44:52/文章来源:https://www.cnblogs.com/feixiang-energy/p/18536950

  通过这个帖子把我对通过webrtc方式播放H265视频的技术探索过程记录下来。虽然最终不一定能够形成产品进行实现,但觉得也是一个有意义的过程。很多事情不就是这样吗?~

-----------------------------

一。背景

  1)由于Webrtc具有低延时、高稳定、浏览器原生支持等特点,目前使用webrtc进行视频播放已经是一个主流的方案;2)受限于专利许可、硬件支持、生态系统支持等限制,目前主流的浏览器并不将H265作为Webrtc的默认视频编解码器选项之一。3)由于H265编码相对于H264具有更高的视频压缩比和视频质量,当前现场的摄像机设备大多默认支持的是H265视频编码。

  在尽量不修改现场摄像机配置的前提下,进行H265视频的播放可以通过如下几种解决方案:1)后端转码:服务器后台进行H265到H264的视频转码,将转码后的视频传输到前端使用webrtc进行播放。缺点:视频转码会使服务器后台消耗大量计算资源,难以承担多用户多视频流的同时播放。2)FLV播放器:使用能够播放H265视频的FLV前端播放器。缺点:a)FLV播放会有1~3秒延迟;b)浏览器端解码会消耗客户端资源,对客户电脑硬件有要求;3)改造webrtc支持H265视频播放。预研基于webrtc的datachannel数据通道传输H265视频到前端播放器,定制前端播放器解码H265视频进行播放。

  方案1)具有可行性,但最好是通过给服务器搭配专用的GPU硬件转码芯片,否则纯CPU扛不住多路转码。

  方案2)如果对视频播放的时延要求不高,可以使用,传统的也都是这样的。

  方案3)是一个新的技术方向,市面上也有一些公司已经在使用了。

  基于方案3)可以预见的缺点:a)技术难度较大,需要对webrtc协议的深度理解,需要改造zlm后端,需要改造webrtc播放器。b)通过前端播放器进行解码仍会存对客户电脑硬件有要求的缺点,不过现在客户的电脑配置已经越来越高了。

  基于方案3)可以预见的优点:a)借助于webrtc协议底层udp、sctp、qos等优化技术,能够高效稳定的传输的H265视频流,视频播放整体延迟会比FLV要低。b)通过预研前端播放器视频解码方式,可以逐步适配wasm、webcodec等软硬件解码方案,能够最大程度发挥客户电脑的资源能力。通过前后端解码策略控制,寻找服务器端与客户端资源占用的最优解。

二。理论原理:

1.Datachannel介绍:

  webrtc涉及到协议栈如下图所示,主要分为两类。左侧基于TCP部分webrtc前期建立的SDP交互信令传输。其它核心协议是基于右侧的UDP搭建起来的,其中ICE、STUN、TURN用于网络建立,DTLS是用于对传输内容进行加密,SRTP是对音频和视频数据进行RTP封装之后再进行加密传输,SCTP是用于UDP数据的加密可靠传输,RTCPeerConnection用来建立和维护端到端的音视频传输连接,DataChannel用来支持端到端的任意文本或二进制数据传输。

   DataChannel的底层是基于UDP、DTLS、SCTP等技术实现。允许服务器与浏览器直接进行双向的、实时的数据传输。与音视频流不同,DataChannel主要用于传输任意类型的数据,如文本、文件、二进制数据等。可以用于文本聊天等即时通信,文件传输,游戏数据传输,实时协作控制、物联网数据传输等。由于DataChannel是基于UDP的并且可以传输任意类型的二进制数据,因此理论上也可以用于传输H265编码的视频数据,并且能够降低数据传输的延迟。并且SCTP协议封装了一些丢包重传、差错控制、数据加密等特性,可以保证视频数据稳定可靠的传输到浏览器端。因此在技术上是可以通过改造ZLM实现基于DataChannel数据通道传输H265视频的。

  如果要实现基于webrtc的datachannel播放H265视频,至少有如下几个方面需要去改造实现:1)webrtc使用的是SDP媒体协商机制,由于当前浏览器端并不支持H265编码,因此需要在浏览器端或ZLM端在媒体协商的地方进行一些修改,能够协商出H265编码,否则后续流程无法进行。2)webrtc传输视频流底层是使用RTP进行封装的,即使使用DataChannel传输H265视频流,底层其实还是使用的RTP对视频流进行封装。在服务端应该能够判断出视频编码类型,并通过DataChannel通道传输RTP视频流。在浏览器端应该能够通过DataChannel通道获取到RTP视频流,对RTP包解封装获取到原始的H265视频帧。因此需要对RTP的封装和解封装进行掌握和了解。3)前端播放器解析出原始的H265视频帧之后,需要进行解码和渲染。经过调研,前端浏览器视频解码的技术有wasm、webcodec、mse等,视频画面渲染的技术有canvas、webgl等,因此需要对前端视频解码渲染进行掌握和了解。

2.RTP协议学习:

  前期已经有过相关技术储备,只不过把视频编码改为H265即可,套路差不多:

  https://www.cnblogs.com/feixiang-energy/p/18350369

  https://www.cnblogs.com/feixiang-energy/p/18525281

3.WASM学习:

  什么是WebAssembly?1)一种新型的代码,可以运行在 Web 浏览器,提供一些新特性并主要专注于高性能;2)主要不是用于写,而是 C/C++、C#、Rust 等语言编译的目标,所以你即使不知道如何编写 WebAssembly 代码也能利用它的优势;3)其他语言编写的代码也能以近似于原生速度运行,客户端 App 也能在 Web 上运行;4)在浏览器或 Node.js 中可以导入 WebAssembly 模块,JS 框架能够使用 WebAssembly 来获得巨大的性能优势和新的特性的同时在功能上易于使用。

  WebAssembly与JS的关系?1)WebAssembly 是一种与 JavaScript 不同的语言,被设计为与 JS 互为补充并能协作,使得 Web 开发者能够重复利用两种语言的优点;2)JS 是高层次的语言,灵活且极具表现力,动态类型、不需要编译步骤,并且有强大的生态,非常易于编写 Web 应用;3)WebAssembly 是一种低层次、类汇编的语言,使用一种紧凑的二级制格式,能够以近乎原生的性能运行,并提供了低层次的内存模型,是 C++、Rust 等语言的编译目标,使得这类语言编写的代码能够在 Web 上运行(需要注意的是,WebAssembly 将在未来提供垃圾回收的内存模型等高层次的目标)。

  如何移植C++应用?1)EMScripten 将 C/C++ 代码喂给 Clang 编译器(一个基于 LLVM 编译架构的 C/C++ 编译器),编译成 LLVM IR;2)EMScripten 将 LLVM IR 转换成 .wasm 的二进制字节码;3)WebAssembly 无法直接获取到 DOM,只能调用 JS,传入整形或浮点型的等原始数据类型,因此 WebAssembly 需要调用 JS 来获取 Web API 和调用,EMScripten 则通过创建了 HTML 文件和 JS 胶水代码来达到上述效果。

 三。后端改造ZLM实现DataChannel推送H265视频流

1.ZLM开启DataChannel支持:

1)修改CMakeLists.txt文件,ENABLE_SCTP字段设置为ON。

2)安装libusrsctp库:

git clone  https://github.com/sctplab/usrsctp.git 
cd usrsctp
./bootstrap
make && sudo make install

3)重新编译ZLM,提示WebRTC datachannel功能已打开。

4)扩展ZLM,封装接口支持发送简单文本信息。a)ZLM的webRtcTransport.cpp类中封装了sendDataChannel函数。支持两种ppid。51:文本string;53:二进制。b)ZLM的webRtcTransportManager是一个webrtc连接的全局管理器,在其中增加根据app和stream查找连接的函数。c)ZLM的WebApi.cpp封装了HTTP接口调用,在其中增加发送datachannel的接口函数。

 5)简单测试验证:前端播放器已经能够回调输出通过datachannel传输的文本数据。(其实这个功能也有很大的应用意义)

6)改造ZLM的SDP协商细节。核心逻辑在WebRtcTransport::getAnswerSdp和RtcConfigure::matchMedia中实现,主要是根据浏览器提供的offerSDP内容匹配当前MediaSource的音视频编码,协商出真正建立连接的媒体编码格式。由于浏览器offerSDP中不包含H265,因此当视频流为H265编码时,会匹配失败。

7)经过SDP交互媒体信息、ICE协商网络连接、DTLS秘钥握手等一系列操作之后。在WebRtcPlayer::onStartWebRTC函数中开始发送数据,在ZLM的代码架构中,webrtc播放和其他协议的播放差不多,都认为是一个Player,通过在MediaSource的视频环形缓存队列上注册Reader回调函数实现,当RTSP拉流端接收到新的RTP视频帧时,通过回调的方式进入到webrtc的发送方法。

8)修改WebRtcTransportImp::canSendRtp函数,先粗暴的不判断answerSDP中是否协商出发送通道,直接返回True。

9)修改webrtc发送视频帧的代码。判断当视频编码为H265时,不再使用SRTP的videoChannel媒体通道发送,而是使用DataChannel发送原始RTP帧。

 10)ZLM通过datachannel发送H265测试验证。通过RTSP方式拉取一个H265的视频,通过Webrtc的方式进行播放。可以通过前端的consol日志查看,接收到了原始的H265视频帧。

 四。WASM播放H265技术验证:

1)emsdk环境搭建,略。

 2)编写简单Demo测试JS加载C++函数。略

3)找到一个开源项目:https://github.com/sonysuqin/WasmVideoPlayer

4)编译ffmpeg-wasm的过程:使用的是ffmpeg-4.4.4.tar.gz

编译选项配置:
emconfigure ./configure --cc="emcc" --cxx="em++" --ar="emar" --ranlib="emranlib" --objcc=emcc --dep-cc=emcc --prefix=../WasmVideoPlayer/dist --enable-cross-compile --target-os=none --arch=x86_32 --cpu=generic --enable-gpl --enable-version3 --disable-avdevice --disable-swresample --disable-postproc --disable-avfilter --disable-programs --disable-logging --disable-everything --enable-avformat --enable-decoder=hevc --enable-decoder=h264 --enable-decoder=aac --disable-ffplay --disable-ffprobe --disable-asm --disable-doc --disable-devices --disable-network --disable-hwaccels --disable-parsers --disable-bsfs --disable-debug --enable-protocol=file --enable-demuxer=mov --enable-demuxer=flv --disable-indevs --disable-outdevs------------------------
编译:
emcc make -j4 && make install------------------------
生成libffmpeg.wasm和libffmpeg.jsexport TOTAL_MEMORY=67108864
export EXPORTED_FUNCTIONS="[ \'_initDecoder', \'_uninitDecoder', \'_openDecoder', \'_closeDecoder', \'_sendData', \'_decodeOnePacket', \'_seekTo', \'_main','_malloc','_free'
]"

echo "Running Emscripten..."
emcc decoder.c dist/lib/libavformat.a dist/lib/libavcodec.a dist/lib/libavutil.a dist/lib/libswscale.a dist/lib/libswresample.a \-O3 \-I "dist/include" \-s WASM=1 \-s TOTAL_MEMORY=${TOTAL_MEMORY} \-s EXPORTED_FUNCTIONS="${EXPORTED_FUNCTIONS}" \-s EXTRA_EXPORTED_RUNTIME_METHODS="['addFunction']" \-s RESERVED_FUNCTION_POINTERS=14 \-s FORCE_FILESYSTEM=1 \-o libffmpeg.jsecho "Finished Build"

 5)跑通WasmVideoPlayer演示Demo,实现在web页面上播放H265格式的MP4文件

 五。最终目标:通过webrtc+datachannel+wasm实现H265的视频播放。

。未完成项:

 

  • 1.继续完善SDP协商机制。通过修改前端代码增加H265选项或修改ZLM后台逻辑,使得能够匹配出H265的媒体通道协商。
  • 2.继续预研前端浏览器通过WASM方式进行H265视频解码的实现方案。
  • 3.继续进一步研究H265的RTP封装逻辑。能够实现在浏览器端通过WASM的方式将RTP包重新解析为原始的H265视频帧。
  • 4.预研基于ZLMRTCClien.js进行修改,将Datachannel接收H265视频帧与WASM技术相结合,实现视频画面渲染播放。
  • 5.由于WASM技术只能使用CPU进行视频解码,已经有点落伍。未来可以研究比较新的前端webcodec、mse等硬件解码方式。提升播放器解码性能。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/829383.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MR756-ASEMI汽车用整流二极管MR756

MR756-ASEMI汽车用整流二极管MR756编辑:ll MR756-ASEMI汽车用整流二极管MR756 型号:MR756 品牌:ASEMI 封装:BUTTON 正向电流:6A 反向电压:1000V 正向压降:1.2V 引线数量:2 芯片个数:1 芯片尺寸:MIL 漏电流:10ua 恢复时间:35ns 浪涌电流:400A 芯片材质: 正向电压:…

python之判断语句

一、if语句 (1)单分支: 格式: if 判断条件 执行语句块1 else: 执行语句块2 备注:判断条件 if中可以使用比较运算符,<,!=,,>=,<= 案例1: a=10 if a != 10: print("你中奖了") else: print("谢谢惠顾") 2、if语句多分支 if 判断条件1: 执…

DE-9IM 空间关系模型

参考博客: 空间拓扑关系描述:9交叉模型(DE-9IM) | 会飞的大象 DE-9IM 空间关系模型 - 乌合之众 - 博客园 DE-9IM 空间关系模型 与Boost Geometry Lib - SuperVan - 博客园简述 DE-9IM 是Dimensionally Extended 9-Intersection Model的缩写,它是Egenhofer在《point set topol…

BUU BRUTE 1 wp

BUU BRUTE 1 引子 burpsuite实战指南 尝试一下发现用户名和密码是分离的,手动输入常用用户名,发现为 admin,得到提示密码是四位数字。 之后用 bp Intruder 尝试爆破,设置 payload需要注意的是如果请求间隔太短会报 429 错误,fix 一下请求间隔时间或者设置自动控制 429 即…

LeetCode 3014[输入单词需要的最少按键次数I]

LeetCode 3014[输入单词需要的最少按键次数I]题目 链接 LeetCode 3014[输入单词需要的最少按键次数I] 详情实例 实例1实例2提示题解 思路 一圈下来8个字母,每个字母按1次 二圈下来16个字母,前8个字母每个按1次,后8个字母,每个按2次 三圈下来24个字母,前8个字母每个按1次,…

解压缩支持文件时出错:灾难性故障处理方式

电脑系统WIN10,在反复安装卸载文件后,再安装软件时出现, 解压缩支持文件时出错: 灾难性故障在解决之前,卸载软件出现报错提示。手动删除软件所在目录,打算重装,也是出现同样的错误提示。 解决方法: 在此电脑--C:\Program Files (x86)\InstallShield Installation Inform…

cmu15545-哈希表(Hash Table)

基本概念 哈希和树一样,是数据库系统中用于访问数据的方法。空间复杂度:$O(n)$ 时间复杂度:$O(1)~ O(n)$ 权衡:更大的哈希空间(碰撞减少),还是更少的哈希空间(碰撞处理)? 哈希函数CRC-64(1975)MurmurHash (2008)Google CityHash (2011)Facebook XXHash (2012) 【最常…

实验3 类和对象-基础编程2

实验任务1: Button.hpp,Window.hpp,task1.cpp,源码,运行测试结果如下#pragma once#include <iostream> #include <string>using std::string; using std::cout;// 按钮类 class Button { public:Button(const string &text);string get_label() const;voi…

【论文系列】DDIM ---DDPM上的优化

What DDIM是啥? DDIM(Denoising Diffusion Implicit Models) 是一种扩散模型的变体,旨在加速图像生成过程并保持生成质量。它是在DDPM(Denoising Diffusion Probabilistic Models)的基础上发展出来的,提供了一种更高效的去噪采样过程,减少了采样所需的步骤数量。 Why D…

解决zip解压之后中文乱码问题

1、打开windows 设置 语言和区域2、打开管理语言设置3、取消勾选这个Beta,然后重启即可

VMware ESXi 6.7 U3u (ESXi670-202403001) 下载

VMware ESXi 6.7 U3u (ESXi670-202403001) 下载VMware ESXi 6.7 U3u (ESXi670-202403001) 下载 VMware ESXi 6 Extend Support Release 请访问原文链接:https://sysin.org/blog/vmware-esxi-6/ 查看最新版。原创作品,转载请保留出处。 作者主页:sysin.org产品简介 VMware ES…

VMware vCenter Server 6.7U3w 发布下载 - ESXi 集中管理软件

VMware vCenter Server 6.7U3w 发布下载 - ESXi 集中管理软件VMware vCenter Server 6.7U3w (安全更新) - ESXi 集中管理软件 集中式控制 vSphere 环境 请访问原文链接:https://sysin.org/blog/vmware-vcenter-6/ 查看最新版。原创作品,转载请保留出处。 作者主页:sysin.org…