首页 > 其他分享 >Webrtc播放H265的技术探索(datachannel+wasm)

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

时间:2024-11-09 16:57:19浏览次数:3  
标签:视频 -- H265 datachannel disable wasm 播放 webrtc

  通过这个帖子把我对通过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.js

export 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.js

echo "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等硬件解码方式。提升播放器解码性能。

 

标签:视频,--,H265,datachannel,disable,wasm,播放,webrtc
From: https://www.cnblogs.com/feixiang-energy/p/18536950

相关文章

  • 在 termux 中配置 rust 写 wasm 的环境
    最近我开始学用rust写wasm。不用说,我是一个非常好学的人。所以我想随时随地都能学习wasm。刚好我手机上有个termux,我就开始琢磨在termux上配个环境。没想到还不是一件很容易的事。所以写这篇文章记录一下。安装rust很明显需要先安装rust。但是termux上好像没......
  • 使用 Cursor 和 Devbox 快速开发基于 Rust 的 WASM 智能合约
    本教程以一个智能合约(使用NEAR的一个官方FungibleTokens来实现)的例子来介绍一下Devbox的强大功能,轻松构建环境,轻松发布。NEAR是一个去中心化的应用平台,使用了分片技术的区块链。免责申明:本教程仅适合用来学习智能合约。FungibleTokens我就不解释了,有兴趣的自己去搜......
  • 折腾笔记[1]-打包ffmpeg-cli到单个wasm二进制
    摘要使用c2w打包ffmpeg-cli到单个wasm二进制,实现ffmpeg可执行文件平台无关运行(BuildOnce,RunAnywhere)。AbstractUsingc2wtopackagetheffmpeg-cliintoasinglewasmbinary,achievingplatform-independentexecutionoftheffmpegexecutable(BuildOnce,RunA......
  • 使用 Rust 和 wasm-pack 开发 WebAssembly 应用
    一、什么是WebAssembly?WebAssembly是一种运行在现代Web浏览器中的新型二进制指令格式。它是一种低级别的字节码,可以被多种语言编译,并在浏览器中高效运行。1.1WebAssembly的背景与概念高性能计算:WebAssembly旨在提高Web应用的性能,接近原生速度,适合计算密集型任务......
  • Rust编写wasm入门
    创建项目cargonew--libmy-wasm添加依赖Cargo.toml[dependencies]wasm-bindgen = "0.2"[lib]crate-type = ["cdylib"]编写代码src/lib.rsuse wasm_bindgen::prelude::*;#[wasm_bindgen]pub fn add(a: i32, b: i32) -> i32 {       a + b......
  • 【教程】如何使用 MYScrcpy,一行Python代码获取Android设备 屏幕/摄像头 H264/H265 原
    MYScrcpy1.5.8Github/Gitee1.5.8版本新增获取原始视频流(H264/H265)方法,供小伙伴们在需要原生H264/H265串流时使用要求MYScrcpy>1.5.8pipinstall-Umysc安卓设备开启调试模式,安卓版本>5(摄像头需>11)H265需安卓设备支持H265编码步骤MYScrcpy从设计之初......
  • 两种常见的视频编解码:H264和H265
    H.264(也称为AVC:AdvancedVideoCoding)是一种广泛使用的视频编码标准,以其高压缩比和良好的视频质量而著称。它能够以较低的比特率编码高质量视频,适合录制、缩小视频以及通过网络共享高清数字视频数据。H.264支持多种分辨率、帧速率和颜色深度,因此被广泛应用于各种平台和软......
  • webrtc的H265播放
    webrtc的H265播放播放器软解使用软解显示硬解sctp封包播放器播放器支持传递canvas、videos、div,然后底下根据参数选择可播放的元素。如果不是H265流用videos播放(调用原生api)如果是H265&&支持webcodes用videos播放(调用原生api)如果是H265&&不支持......
  • 创新实践:流媒体服务器如何推动WebRTC支持H.265及JS硬软解码(MSE硬解、WASM软解)
    为了实现这一全面的解决方案,我们投入了近半年的时间进行调研与研发。我们的主要目标是:让流媒体服务器能够直接传输H.265编码的视频,而无需将其转码为H.264,从而使Chrome浏览器能够无缝解码并播放H.265视频。值得注意的是,目前市场上许多软硬件产品仍采用将H.265转码为H.264的方式来......
  • 创新实践:流媒体服务器如何推动WebRTC支持H.265及JS硬软解码(MSE硬解、WASM软解)
    为了实现这一全面的解决方案,我们投入了近半年的时间进行调研与研发。我们的主要目标是:让流媒体服务器能够直接传输H.265编码的视频,而无需将其转码为H.264,从而使Chrome浏览器能够无缝解码并播放H.265视频。值得注意的是,目前市场上许多软硬件产品仍采用将H.265转码为H.264的......