容器格式
Mediabunny 支持许多常用的媒体容器格式,所有格式均支持双向操作(读取与写入):
- 基于 ISOBMFF 的格式 (.mp4, .m4v, .m4a, ...)
- QuickTime 文件格式 (.mov)
- 分段 MP4 (CMAF) (.m4s)
- Matroska (.mkv)
- WebM (.webm)
- Ogg (.ogg)
- MP3 (.mp3)
- WAVE (.wav)
- ADTS (.aac)
- FLAC (.flac)
- MPEG 传输流 (.ts)
- HLS (.m3u8)
编解码器
Mediabunny 支持广泛的视频、音频和字幕编解码器。更具体地说,它支持 WebCodecs API 指定的所有编解码器,并开箱即用支持一些额外的 PCM 编解码器。
WebCodecs API 提供的编解码器的可用性取决于浏览器,因此本库无法保证。Mediabunny 提供特殊的工具函数来检查哪些编解码器可以进行编码。如果浏览器不支持该编解码器的原生实现,您也可以指定自定义编码器以提供您自己的编码器/解码器实现。
关于每种编解码器及其对应数据包格式的精确定义,请参阅 Mediabunny 编解码器注册表。
Mediabunny 内置了所有音频 PCM 编解码器的解码器和编码器,这意味着它们始终受支持。
视频编解码器
'avc'- 高级视频编码 (AVC) / H.264'hevc'- 高效视频编码 (HEVC) / H.265'vp8'- VP8'vp9'- VP9'av1'- AOMedia Video 1 (AV1)'prores'- Apple ProRes [1]
音频编解码器
'aac'- 高级音频编码 (AAC) [2]'opus'- Opus'mp3'- MP3 [3]'vorbis'- Vorbis'flac'- 无损音频编解码器 (FLAC) [4]'ac3'- 杜比数字 (AC-3) [5]'eac3'- 杜比数字增强 (E-AC-3) [5:1]'dts'- DTS 相干声学 [6]'pcm-u8'- 8 位无符号 PCM'pcm-s8'- 8 位有符号 PCM'pcm-s16'- 16 位小端有符号 PCM'pcm-s16be'- 16 位大端有符号 PCM'pcm-s24'- 24 位小端有符号 PCM'pcm-s24be'- 24 位大端有符号 PCM'pcm-s32'- 32 位小端有符号 PCM'pcm-s32be'- 32 位大端有符号 PCM'pcm-f32'- 32 位小端浮点 PCM'pcm-f32be'- 32 位大端浮点 PCM'pcm-f64'- 64 位小端浮点 PCM'pcm-f64be'- 64 位大端浮点 PCM'ulaw'- μ-law PCM'alaw'- A-law PCM
字幕编解码器
'webvtt'- WebVTT
兼容性表
并非所有编解码器都能与所有容器配合使用。下表列出了支持的编解码器 - 容器组合:
| .mp4 | .mov | .mkv | .webm[7] | .ogg | .mp3 | .wav | .aac | .flac | .ts | |
|---|---|---|---|---|---|---|---|---|---|---|
'avc' | ✓ | ✓ | ✓ | ✓ | ||||||
'hevc' | ✓ | ✓ | ✓ | ✓ | ||||||
'vp8' | ✓ | ✓ | ✓ | ✓ | ||||||
'vp9' | ✓ | ✓ | ✓ | ✓ | ||||||
'av1' | ✓ | ✓ | ✓ | ✓ | ||||||
'prores' | ✓ | ✓ | ✓ | |||||||
'aac' | ✓ | ✓ | ✓ | ✓ | ✓ | |||||
'opus' | ✓ | ✓ | ✓ | ✓ | ✓ | |||||
'mp3' | ✓ | ✓ | ✓ | ✓ | ✓ | |||||
'vorbis' | ✓ | ✓ | ✓ | ✓ | ✓ | |||||
'flac' | ✓ | ✓ | ✓ | ✓ | ||||||
'ac3' | ✓ | ✓ | ✓ | ✓ | ||||||
'eac3' | ✓ | ✓ | ✓ | ✓ | ||||||
'dts' | ✓ | ✓ | ✓ | ✓ | ||||||
'pcm-u8' | ✓ | ✓ | ✓ | |||||||
'pcm-s8' | ✓ | |||||||||
'pcm-s16' | ✓ | ✓ | ✓ | ✓ | ||||||
'pcm-s16be' | ✓ | ✓ | ✓ | |||||||
'pcm-s24' | ✓ | ✓ | ✓ | ✓ | ||||||
'pcm-s24be' | ✓ | ✓ | ✓ | |||||||
'pcm-s32' | ✓ | ✓ | ✓ | ✓ | ||||||
'pcm-s32be' | ✓ | ✓ | ✓ | |||||||
'pcm-f32' | ✓ | ✓ | ✓ | ✓ | ||||||
'pcm-f32be' | ✓ | ✓ | ||||||||
'pcm-f64' | ✓ | ✓ | ✓ | |||||||
'pcm-f64be' | ✓ | ✓ | ||||||||
'ulaw' | ✓ | ✓ | ||||||||
'alaw' | ✓ | ✓ | ||||||||
'webvtt'[8] | (✓) | (✓) | (✓) |
对于 HLS,支持的编解码器取决于所选的段格式。
查询编解码器的可编码性
Mediabunny 提供了实用函数,您可以用来检查浏览器是否可以编码给定的编解码器。此外,您还可以检查编解码器是否可以使用特定的配置进行编码。
canEncode测试编解码器是否可以使用典型设置进行编码:
import { canEncode } from 'mediabunny';
canEncode('avc'); // => Promise<boolean>
canEncode('opus'); // => Promise<boolean>视频编解码器使用 1280x720 进行检查,而音频编解码器使用 2 通道、48 kHz 进行检查。
您也可以使用特定配置检查可编码性:
import { canEncodeVideo, canEncodeAudio, Quality } from 'mediabunny';
canEncodeVideo('hevc', {
width: 1920, height: 1080, frameRate: 60, quality: new Quality({ bitrate: 1e7 })
}); // => Promise<boolean>
canEncodeAudio('aac', {
numberOfChannels: 1, sampleRate: 44100, quality: new Quality({ bitrate: 192e3 })
}); // => Promise<boolean>此外,VideoEncodingConfig和AudioEncodingConfig的大多数属性也可以在此处使用。
此外,您可以使用以下函数一次性检查多个编解码器的可编码性,并返回受支持的编解码器列表:
import {
getEncodableCodecs,
getEncodableVideoCodecs,
getEncodableAudioCodecs,
getEncodableSubtitleCodecs,
Quality,
} from 'mediabunny';
getEncodableCodecs(); // => Promise<MediaCodec[]>
getEncodableVideoCodecs(); // => Promise<VideoCodec[]>
getEncodableAudioCodecs(); // => Promise<AudioCodec[]>
getEncodableSubtitleCodecs(); // => Promise<SubtitleCodec[]>
// 这些函数也接受可选的配置选项。
// 这里,我们检查 AVC、HEVC 和 VP8 中哪些可以在 1920x1080 @10Mbps 下编码:
getEncodableVideoCodecs(
['avc', 'hevc', 'vp8'],
{ width: 1920, height: 1080, quality: new Quality({ bitrate: 1e7 }) },
); // => Promise<VideoCodec[]>如果您只想查找浏览器可以编码的最佳编解码器,可以使用这些函数,它们将返回浏览器支持的第一个编解码器:
import {
getFirstEncodableVideoCodec,
getFirstEncodableAudioCodec,
getFirstEncodableSubtitleCodec,
Quality,
} from 'mediabunny';
getFirstEncodableVideoCodec(['avc', 'vp9', 'av1']); // => Promise<VideoCodec | null>
getFirstEncodableAudioCodec(['opus', 'aac']); // => Promise<AudioCodec | null>
getFirstEncodableVideoCodec(
['avc', 'hevc', 'vp8'],
{ width: 1920, height: 1080, quality: new Quality({ bitrate: 1e7 }) },
); // => Promise<VideoCodec | null>如果列出的编解码器均不受支持,则返回 null。
这些函数与 输出格式 结合使用时特别有用,可检索同时被编码器及容器格式支持的最佳编解码器:
import {
Mp4OutputFormat,
getFirstEncodableVideoCodec,
} from 'mediabunny';
const outputFormat = new Mp4OutputFormat();
const containableVideoCodecs = outputFormat.getSupportedVideoCodecs();
const bestVideoCodec = await getFirstEncodableVideoCodec(containableVideoCodecs);编解码器可编码性检查会考虑自定义编码器。
查询编解码器可解码性
如果您已经有一个 InputTrack,可以使用其 canDecode 方法检查其可解码性,该方法会使用轨道的实际编解码器配置:
const canDecodeTrack = await inputTrack.canDecode(); // => boolean然而,即使没有具体的轨道,您也可以评估可解码性。canDecode 测试是否可以使用典型设置对编解码器进行解码:
import { canDecode } from 'mediabunny';
canDecode('avc'); // => Promise<boolean>
canDecode('opus'); // => Promise<boolean>视频编解码器使用 1280x720 进行检查,而音频编解码器使用 2 声道、48 kHz 进行检查。
您还可以使用特定配置检查可解码性:
import { canDecodeVideo, canDecodeAudio } from 'mediabunny';
canDecodeVideo('hevc', {
codedWidth: 1920, codedHeight: 1080
}); // => Promise<boolean>
canDecodeAudio('aac', {
numberOfChannels: 1, sampleRate: 44100
}); // => Promise<boolean>此处也可以使用 VideoDecoderConfig 和 AudioDecoderConfig 的所有其他属性。
此外,您可以使用以下函数一次性检查多个编解码器的可解码性,并获取受支持的编解码器列表:
import {
getDecodableCodecs,
getDecodableVideoCodecs,
getDecodableAudioCodecs,
} from 'mediabunny';
getDecodableCodecs(); // => Promise<MediaCodec[]>
getDecodableVideoCodecs(); // => Promise<VideoCodec[]>
getDecodableAudioCodecs(); // => Promise<AudioCodec[]>
// 这些函数也接受可选的配置选项。
// 这里,我们检查 AVC、HEVC 和 VP8 中哪些可以在 1920x1080 下解码:
getDecodableVideoCodecs(
['avc', 'hevc', 'vp8'],
{ codedWidth: 1920, codedHeight: 1080 },
); // => Promise<VideoCodec[]>编解码器可解码性检查会考虑自定义解码器。
自定义编码器/解码器
Mediabunny 允许您注册自己的自定义编码器和解码器——如果您想在所有浏览器都不支持的编解码器上进行多态填充,或者希望在非 WebCodecs 环境(如 Node.js)中使用 Mediabunny,这将非常有用。
可以为库支持的所有视频和音频编解码器注册编码器和解码器。无法添加新的编解码器。
警告
Mediabunny 要求自定义编码器和解码器遵循非常具体的实现规则。请特别注意标有 "必须" 的部分以确保兼容性。
自定义编码器
要创建自定义视频或音频编码器,您需要创建一个扩展 CustomVideoEncoder 或 CustomAudioEncoder 的类。然后,您 必须 使用 registerEncoder 注册此类:
import { CustomAudioEncoder, registerEncoder } from 'mediabunny';
class MyAwesomeMp3Encoder extends CustomAudioEncoder {
// ...
}
registerEncoder(MyAwesomeMp3Encoder);以下属性在每个编码器实例上可用,并由库设置:
class {
// 对于视频编码器:
codec: VideoCodec;
config: VideoEncoderConfig;
onPacket: (packet: EncodedPacket, meta?: EncodedVideoChunkMetadata) => unknown;
// 对于音频编码器:
codec: AudioCodec;
config: AudioEncoderConfig;
onPacket: (packet: EncodedPacket, meta?: EncodedAudioChunkMetadata) => unknown;
// 对于两者:
onError: (error: unknown) => void;
}codec 和 config 指定要使用的具体编解码器配置,而 onPacket 是一个方法,您的代码在创建每个编码包时必须调用它。onError 是一个您可以调用的方法,用于抛出发生在常规方法调用之外的任何带外错误(例如来自异步后台任务);否则这些错误将不会被捕获。
您必须在自定义编码器类中实现以下方法:
class {
// For video encoders:
static supports(codec: VideoCodec, config: VideoEncoderConfig): boolean;
// For audio encoders:
static supports(codec: AudioCodec, config: AudioEncoderConfig): boolean;
init(): Promise<void> | void;
encode(sample: VideoSample, options: VideoEncoderEncodeOptions): Promise<void> | void; // For video
encode(sample: AudioSample): Promise<void> | void; // For audio
flush(): Promise<void> | void;
close(): Promise<void> | void;
}supports
这是一个静态方法,如果编码器能够编码指定的编解码器则必须返回true,否则返回false。如果返回true,库将创建您编码器类的新实例并用于编码,其优先级高于默认编码器。init
由库在您的类实例化后调用。在此处放置任何初始化逻辑。encode
对每个待编码的样本进行调用。生成的编码包必须随后传递给onPacket方法。flush
当期望编码器完成所有尚未完成编码的剩余样本的编码过程时调用。此方法必须仅在所有传递给encode的样本都已完全编码后才返回/解析。之后,它必须重置其内部状态以准备下一批编码。close
当不再需要编码器且可以释放其内部资源时调用。
该类的所有实例方法都可以返回 promises。在这种情况下,库将确保对所有方法调用进行序列化,以确保没有两个方法会同时运行。
WARNING
传递给 onPacket 的包必须处于解码顺序。
Custom decoders
要创建自定义视频或音频解码器,您需要创建一个扩展 CustomVideoDecoder 或 CustomAudioDecoder 的类。然后,您必须使用 registerDecoder 注册此类:
import { CustomAudioDecoder, registerDecoder } from 'mediabunny';
class MyAwesomeMp3Decoder extends CustomAudioDecoder {
// ...
}
registerDecoder(MyAwesomeMp3Decoder);以下属性在每个解码器实例上可用,并由库设置:
class {
// For video decoders:
codec: VideoCodec;
config: VideoDecoderConfig;
onSample: (sample: VideoSample) => unknown;
// For audio decoders:
codec: AudioCodec;
config: AudioDecoderConfig;
onSample: (sample: AudioSample) => unknown;
// For both:
onError: (error: unknown) => void;
}codec 和 config 指定要使用的具体编解码器配置,而 onSample 是一个方法,您的代码在创建每个视频/音频样本时必须调用它。onError 是一个您可以调用的方法,用于抛出发生在常规方法调用之外的任何带外错误(例如来自异步后台任务);否则这些错误将不会被捕获。
您必须在自定义解码器类中实现以下方法:
class {
// For video decoders:
static supports(codec: VideoCodec, config: VideoDecoderConfig): boolean;
// For audio decoders:
static supports(codec: AudioCodec, config: AudioDecoderConfig): boolean;
init(): Promise<void> | void;
decode(packet: EncodedPacket): Promise<void> | void;
flush(): Promise<void> | void;
close(): Promise<void> | void;
}supports
这是一个静态方法,如果解码器能够解码指定的编解码器则必须返回true,否则返回false。如果返回true,库将创建您解码器类的新实例并用于解码,其优先级高于默认解码器。init
由库在您的类实例化后调用。在此处放置任何初始化逻辑。decode
对每个待解码的EncodedPacket进行调用。生成的视频或音频样本必须随后传递给onSample方法。flush
当期望解码器完成所有尚未完成解码的剩余包的解码过程时调用。此方法必须仅在所有传递给decode的包都已完全解码后才返回/解析。之后,它必须重置其内部状态以准备下一批解码。close
当不再需要解码器且可以释放其内部资源时调用。
该类的所有实例方法都可以返回 promises。在这种情况下,库将确保对所有方法调用进行序列化,以确保没有两个方法会同时运行。
WARNING
传递给 onSample 的样本必须按递增的时间戳排序。这尤其意味着如果解码器正在解码使用B 帧的视频流,则解码器必须在内部保留这些帧,以便能够按显示时间戳对其排序发出。每次调用 flush 时,此严格排序要求都会重置。
WebCodecs 不支持 ProRes。要对其进行解码,请使用
@mediabunny/prores扩展包。@mediabunny/server扩展包为服务器端环境提供解码和编码支持。在某些浏览器中,WebCodecs 不支持 AAC 编码。您可以使用
@mediabunny/aac-encoder扩展包进行填充。WebCodecs 不支持 MP3 编码。您可以使用
@mediabunny/mp3-encoder扩展包进行填充。WebCodecs 不支持 FLAC 编码。您可以使用
@mediabunny/flac-encoder扩展包进行填充。AC-3 和 E-AC-3 不是 WebCodecs 原生支持的编解码器。要编码或解码这些编解码器,可以使用
@mediabunny/ac3扩展包。DTS 不是 WebCodecs 原生支持的编解码器。要编码或解码它,可以使用
@mediabunny/dts扩展包。WebM 仅支持 Matroska 所支持的一小部分编解码器。但是,该库在技术上可以读取 WebM 中所有 Matroska 支持的编解码器。
WebVTT 只能写入,不能读取。