zhaohappy / libmedia

一个 TypeScript 实现的高性能媒体库,支持 WebCodecs 和 Wasm。 A high-performance media library implemented in TypeScript, support WebCodecs and Wasm.
https://zhaohappy.github.io/libmedia/product/player/player.html
GNU Lesser General Public License v3.0
82 stars 13 forks source link
av1 dash decoder demux encoder flv h264 h265 hevc javascript m3u8 matroska mp4 mpegts mux player vp9 vvc webassembly webcodecs

libmedia

中文 | English

license

介绍

libmedia 是一个用于在 Web 平台上处理多媒体内容(如音频、视频、字幕)的工具库。

libmedia 有 TypeScript 模块和 WebAssembly 模块,并且设计理念上以 TypeScript 模块为主导;我们将音视频的封装解封装层放在 TypeScript 模块实现,这样就能使用异步 IO 来处理各种来源的流,可以让整个系统在非 SharedArrayBuffer 环境上运行;

解码编码模块放入 WebAssembly 模块中,这些模块可以从 FFmpeg 的 libavcodec 模块中编译而来,并且将每种解码器和编码器编译成单独的 wasm 模块,解决编译产物太大的问题,使用的时候只需要去加载要使用的模块。同时编解码模块可以使用 WebCodecs。

libmedia 的 API 设计上参照 FFmpeg 设计,很多数据结构概念都是一致的,所以你能看见诸如 AVStreamAVCodecParametersAVFormatContextAVPacketAVFrame 等数据结构。FFmpeg 作为音视频行业事实上的标准,其设计是非常优秀的;照着设计直接得到优秀的设计模式,还减少开发者学习理解的难度,毕竟做音视频开发的多少都对 FFmpeg 学习过;当然最主要的原因是我们需要让这些数据可以在 TypeScript 模块和 WebAssembly 模块中都可以进行读写操作,其在内存上的布局和 FFmpeg 保持一致是前提。

libmedia 是设计在多线程上的,只是可以回退到单线程上运行;所以对多线程开发比较亲和;开发者可以很优雅的基于此做多线程的开发,毕竟在音视频领域使用多线程带来的体验绝对要高出很多。

多线程

libmedia 支持多线程,但需要页面可以使用 SharedArrayBuffer,你可以通过在顶层文档的响应头上添加以下两个响应头:

来开启使用 SharedArrayBuffer,若不支持多线程将回退到主线程上运行。

工具

当前支持的封装格式

Format Input Output
flv
mov
mp4
mpegts
mpegps
matroska
webm
h264 裸流
hevc 裸流
vvc 裸流
mp3
oggs
ivf
aac
flac
wav
webvtt
srt
ass
ssa
ttml

编解码器

编解码器被编译成了单独的 wasm 模块,解码器在 dist/decode 目录下,编码器在 dist/encode 目录下。编解码器的 wasm 模块有三个版本分别为 baseline、atomic、simd。baseline 版本是基准版本,指令集对应到 WebAssembly 的 MVP 版本,但需要支持 Mutable Globals,兼容性最高,性能最低;atomic 增加了 atomic 原子操作指令集和 Bulk Memory 指令集;simd 增加了 simd 向量加速指令集,性能最高。目前的 simd 版本是靠编译器自动优化的,不同的编解码器实现效果不同(目前没有看见过有针对 wasm 指令集做加速优化的开源项目,如果想要更高的加速效果需要自己优化)。

三个版本和 webcodecs 的兼容性支持情况

环境 baseline atomic simd webcodecs
Chrome 74+ 75+ 91+ 94+
Firefox 61+ 79+ 89+ N/A(linux video only)
Safari 12+ 15+ 16.4+ 16.4+(video only)
Wasmtime 0.20+ 15+ 15+ N/A
Wasmer 0.7+ N/A N/A N/A
Node.js 12.0+ 16.4+ 16.4+ N/A
Deno 0.1+ 1.9+ 1.9+ N/A
wasm2c 1.0.1+ N/A N/A N/A

目前支持的解码 codecs 支持情况

codec baseline atomic simd webcodecs(Chrome)
h264
hevc ✅ (只支持硬解)
vvc
av1
vp8
vp9
mpeg4
theora
aac
mp3
opus
flac
speex
vorbis
ac3
eac3
dts
G.711 A-law
G.711 μ-law

目前支持的编码 codecs 支持情况

codec baseline atomic simd webcodecs(Chrome)
h264
hevc
vvc
av1
vp8
vp9
mpeg4
theora
aac
mp3
opus
flac
speex
vorbis
ac3
eac3
dts
G.711 A-law
G.711 μ-law

API

avformat

avcodec

avpipeline

avnetwork

avplayer

avtranscoder

avutil

io

开发

若你想集成此项目来开发,建议将本仓库作为子模块,项目使用了 cheap 库,需要你对 cheap 的使用有所了解。凡是使用了 libmedia API 的地方都需要使用 cheap 插件来编译。

当前本项目只支持使用 webpack 进行编译打包

下面介绍如何编译 AVPlayer 和 AVTranscoder 工具


# 克隆项目以及所有子模块
git clone https://github.com/zhaohappy/libmedia.git --recursive

# 进入 libmedia 目录
cd libmedia

# 安装依赖
npm install

# 编译 AVPlayer 开发版
npm run build-avplayer-dev

# 编译 AVTranscoder 开发版
npm run build-avtranscoder-dev

# 启动本地 http 服务
# 任何一个 http 服务都行,若报 edp 找不到,可以全局安装: npm install edp -g
edp webserver start --port=9000

# 浏览器访问 http://localhost:9000/test/avplayer.html

若要源码调试多线程 Worker 中的代码,设置 tsconfig.jsonENABLE_THREADS_SPLIT宏为 true并重新编译

{
  "cheap": {
    "defined": {
      "ENABLE_THREADS_SPLIT": true
    }
  }
}

tsconfig.json 还可设置其他宏来裁剪编译,你可以根据自己的需要更改相关设置,详情看 tsconfig.json -> cheap -> defined 中的配置

示例

examples/demux.ts 是解封装的使用示例

examples/mux.ts 是封装的使用示例

examples/decode.ts 是解码的使用示例

test/avplayer.html 是 AVPlayer 的使用示例,也是在线 demo 的实现

test/avtranscoder.html 是一个 AVTranscoder 的使用示例,也是在线 demo 的实现

相关文章

下一代 Web 音视频技术会是什么样的

开源协议

libmedia 使用 LGPL 开源协议,你需要遵守协议要求,详情查看 LGPL

但某些依赖库是 GPL 协议,如果你使用了这些依赖库则 libmedia 将被传染为 GPL 协议。这些依赖库使用在下面的组件:

依赖库开源协议

版权所有 (C) 2024-现在 赵高兴

Copyright (C) 2024-present, Gaoxing Zhao