简介
输出格式指定了由Output写入的数据的容器格式。Mediabunny 支持许多常用的容器格式,每种格式都有特定的选项。
许多格式还提供数据回调,这是针对输出文件中特定数据区域触发的特殊回调函数。
输出格式属性
所有输出格式都有一组通用的属性可供查询。
// 获取格式的扩展名:
format.fileExtension; // => '.mp4'
// 获取格式的基础 MIME 类型:
format.mimeType; // => 'video/mp4'
// 检查该格式可以包含哪些编解码器:
format.getSupportedCodecs(); // => MediaCodec[]
format.getSupportedVideoCodecs(); // => VideoCodec[]
format.getSupportedAudioCodecs(); // => AudioCodec[]
format.getSupportedSubtitleCodecs(); // => SubtitleCodec[]
// 检查该格式是否支持带有旋转和翻转元数据的视频轨道:
format.supportsVideoTransformationMetadata; // => boolean请参阅兼容性表以查看哪些编解码器可与哪种输出格式配合使用。
不同格式在可包含的轨道数量和类型上也存在差异。您可以使用以下方法检索此信息:
format.getSupportedTrackCounts(); // => TrackCountLimits
type TrackCountLimits = {
video: { min: number, max: number },
audio: { min: number, max: number },
subtitle: { min: number, max: number },
total: { min: number, max: number },
};仅追加写入
某些输出格式配置采用仅追加模式写入。这意味着它们仅向文件末尾添加新数据,而无需回退到之前写入的部分进行覆盖。或者,从形式上讲:任何写入操作的字节偏移量恰好等于此前已写入的字节数。
仅追加格式与StreamTarget结合使用时具有某些有用特性。它们支持与Media Source Extensions配合使用,并允许通过网络轻松流式传输,例如用于文件上传。
MP4
此输出格式用于创建 MP4 文件。
import { Output, Mp4OutputFormat } from 'mediabunny';
const output = new Output({
format: new Mp4OutputFormat(options),
// ...
});以下选项可用:
type IsobmffOutputFormatOptions = {
fastStart?: false | 'in-memory' | 'reserve' | 'fragmented';
minimumFragmentDuration?: number;
metadataFormat?: 'mdir' | 'mdta' | 'udta' | 'auto';
onFtyp?: (data: Uint8Array, position: number) => unknown;
onMoov?: (data: Uint8Array, position: number) => unknown;
onMdat?: (data: Uint8Array, position: number) => unknown;
onMoof?: (data: Uint8Array, position: number, timestamp: number) => unknown;
};fastStart
控制文件中元数据的位置。将元数据置于文件开头称为“快速启动”(Fast Start),并提供某些优势:文件更容易在没有范围请求的情况下通过 Web 流式传输,且像 YouTube 这样的网站可以在视频上传时就开始处理它。然而,将元数据置于文件开头可能在写入步骤中需要更多的处理和内存。本库提供完全控制元数据放置的功能,可通过将fastStart设置为以下选项之一来实现:false
禁用快速启动,将元数据放置在文件末尾。速度最快且占用内存最少。'in-memory'
通过将所有媒体块保留在内存中直到文件最终确定,生成带有快速启动的文件。这会产生高质量且紧凑的输出,但代价是最终确定步骤更昂贵且对内存要求更高。此选项确保仅追加写入,尽管所有写入操作都在最后批量完成。
'reserve'
通过在文件开头预留空间来生成带有快速启动的文件,稍后将在此处写入元数据。这需要预先了解文件的预期长度。使用此选项时,您必须为所有轨道设置轨道元数据中的maximumPacketCount字段。'fragmented'
生成分片 MP4 (fMP4)文件,通过将样本元数据分组为“片段”(媒体的短节段)并将其均匀分布在文件中,同时将通用元数据放在文件开头。分片文件非常适合流式传输场景,因为每个片段都可以单独播放,而无需了解其他片段。此外,无论文件大小如何增长,它们的创建都保持轻量级,因为它们不需要长时间将媒体保留在内存中。然而,分片文件的广泛性和完整性支持不如常规 MP4 文件,某些播放器也不提供对其的搜索功能。此选项确保仅追加写入。
警告
此选项需要数据包缓冲。
undefined
默认选项;在使用BufferTarget时行为类似于'in-memory',否则类似于false。
minimumFragmentDuration
仅在fastStart为'fragmented'时相关。设置片段必须具有的最小持续时间(秒),以便最终确定并写入文件。默认为 1 秒。metadataFormat
用于写入元数据标签的元数据格式。'auto'(默认):对于 MP4 表现如'mdir',对于 QuickTime 表现如'udta',与 FFmpeg 的默认行为匹配。'mdir':使用 'mdir' 处理程序格式将标签写入moov/udta/meta。'mdta':使用 'mdta' 处理程序格式将标签写入moov/udta/meta,等同于 FFmpeg 的use_metadata_tags标志。这允许使用任意长度的自定义键。'udta':直接将标签写入moov/udta。
onFtyp
当输出文件的 ftyp (File Type) box 写入后将被调用。onMoov
当输出文件的 moov (Movie) box 写入后将被调用。onMdat
对输出文件的每个最终确定的 mdat (Media Data) box 进行调用。如果不使用fastStart: 'fragmented',则不建议使用此回调,因为将存在一个单体 mdat box,可能需要大量内存。onMoof
对输出文件的每个最终确定的 moof (Movie Fragment) box 进行调用。同时传递片段的起始时间戳(秒)。
QuickTime 文件格式 (.mov)
此输出格式创建 QuickTime 文件 (.mov)。
import { Output, MovOutputFormat } from 'mediabunny';
const output = new Output({
format: new MovOutputFormat(options),
// ...
});可用的选项与 MP4 使用的 IsobmffOutputFormatOptions 相同。
CMAF
此输出格式创建单个通用媒体应用格式 (CMAF) 段 (.m4s)。
import { Output, CmafOutputFormat } from 'mediabunny';
const output = new Output({
format: new CmafOutputFormat(options),
initTarget: new BufferTarget(), // 例如
// ...
});CMAF 段需要一个单独的初始化段,该段将写入由 OutputOptions.initTarget 指定的目标。
可用的选项与 MP4 使用的 IsobmffOutputFormatOptions 相同,但移除了 fastStart 选项,且 minimumFragmentDuration 默认为 Infinity。
CMAF 主要设计用作 HLS 的段格式。
WebM
此输出格式创建 WebM 文件。
import { Output, WebMOutputFormat } from 'mediabunny';
const output = new Output({
format: new WebMOutputFormat(options),
// ...
});提供以下选项:
type MkvOutputFormatOptions = {
appendOnly?: boolean;
minimumClusterDuration?: number;
onEbmlHeader?: (data: Uint8Array, position: number) => void;
onSegmentHeader?: (data: Uint8Array, position: number) => unknown;
onCluster?: (data: Uint8Array, position: number, timestamp: number) => unknown;
};appendOnly
配置输出以追加方式写入数据。这对于在创建过程中实时流式传输输出非常有用。注意,启用时,某些功能(如文件时长或搜索)将被禁用或受到影响,因此如果您希望稍后使用而写入媒体文件,请不要使用此选项。此选项确保追加写入。
minimumClusterDuration
设置集群必须具有的最小持续时间(秒),以便最终确定并写入文件。默认为 1 秒。onEbmlHeader
当输出文件的 EBML header 写入后将被调用。onSegmentHeader
当 Matroska Segment 元素的头部部分写入后将被调用。头部数据包括 Segment 元素及其内部所有内容,直到(但不包括)第一个 Matroska Cluster。onCluster
对输出文件的每个最终确定的 Matroska Cluster 进行调用。同时传递集群的起始时间戳(秒)。
Matroska (.mkv)
此输出格式创建 Matroska 文件 (.mkv)。
import { Output, MkvOutputFormat } from 'mediabunny';
const output = new Output({
format: new MkvOutputFormat(options),
// ...
});可用的选项与 WebM 使用的 MkvOutputFormatOptions 相同。
Ogg
此输出格式创建 Ogg 文件。
import { Output, OggOutputFormat } from 'mediabunny';
const output = new Output({
format: new OggOutputFormat(options),
// ...
});此格式确保追加写入。
提供以下选项:
type OggOutputFormatOptions = {
maximumPageDuration?: number;
onPage?: (data: Uint8Array, position: number, source: MediaSource) => unknown;
};maximumPageDuration
每个 Ogg page 的最大持续时间(秒)。如果添加另一个 packet 会导致 page 超过此持续时间,则提前刷新 page。这对于需要更频繁页面输出的流式传输上下文非常有用。默认情况下,仅在 page 超过一定大小时才刷新。onPage
对输出文件的每个最终确定的 Ogg page 进行调用。同时传递 backing page track (logical bitstream) 的 媒体源。
MP3
此输出格式创建 MP3 文件。
import { Output, Mp3OutputFormat } from 'mediabunny';
const output = new Output({
format: new Mp3OutputFormat(options),
// ...
});以下选项可用:
type Mp3OutputFormatOptions = {
xingHeader?: boolean;
onXingFrame?: (data: Uint8Array, position: number) => unknown;
};xingHeader
控制是否在 MP3 文件开头写入包含附加元数据及索引的 Xing header。默认为true。设置为
false时,此选项可确保仅追加写入。onXingFrame
当 Xing 元数据帧完成时将被调用,这发生在写入过程的末尾。仅当xingHeader未设置为false时,此回调才会触发。
大多数浏览器不支持编码 MP3。请使用官方的 @mediabunny/mp3-encoder 包来为编码器提供多态支持(polyfill)。
WAVE
此输出格式用于创建 WAVE (.wav) 文件。
import { Output, WavOutputFormat } from 'mediabunny';
const output = new Output({
format: new WavOutputFormat(options),
// ...
});以下选项可用:
type WavOutputFormatOptions = {
large?: boolean;
metadataFormat?: 'info' | 'id3';
onHeader?: (data: Uint8Array, position: number) => unknown;
};large
启用后,将写入 RF64 文件,允许文件大小超过 4 GiB,而常规 WAVE 文件无法做到这一点。metadataFormat
用于写入元数据标签的元数据格式。'info'(默认):将元数据写入 RIFF INFO LIST chunk,这是 WAVE 中包含元数据标签的默认方式。仅允许写入有限的一组标签。'id3':将元数据写入 ID3 chunk。非默认设置,但在实践中被许多标签工具使用。允许写入更大且更丰富的标签集。
onHeader
文件头写入完成后将被调用。文件头由 RIFF 头、format chunk 以及 data chunk 的开头(大小为 0 的占位符)组成。
ADTS
此输出格式用于创建 ADTS (.aac) 文件。
import { Output, AdtsOutputFormat } from 'mediabunny';
const output = new Output({
format: new AdtsOutputFormat(options),
// ...
});此格式可确保仅追加写入。
以下选项可用:
type AdtsOutputFormatOptions = {
onFrame?: (data: Uint8Array, position: number) => unknown;
};onFrame
每写入一个 ADTS 帧时将被调用。
FLAC
此输出格式用于创建 FLAC (.flac) 文件。
import { Output, FlacOutputFormat } from 'mediabunny';
const output = new Output({
format: new FlacOutputFormat(options),
// ...
});以下选项可用:
type FlacOutputFormatOptions = {
appendOnly?: boolean;
onFrame?: (data: Uint8Array, position: number) => unknown;
};appendOnly
配置输出仅在末尾追加新数据,适用于在创建文件的同时进行直播流式传输。启用后,STREAMINFO block 将不会以准确的 min/max block size、frame size 或总样本数进行最终确定,因此如果您希望写入供后续使用的干净文件,请不要使用此选项。此选项可确保仅追加写入。
onFrame
每写入一个 FLAC 帧时将被调用。
MPEG-TS
此输出格式用于创建 MPEG Transport Stream (.ts) 文件。
import { Output, MpegTsOutputFormat } from 'mediabunny';
const output = new Output({
format: new MpegTsOutputFormat(options),
// ...
});此格式可确保仅追加写入。
以下选项可用:
type MpegTsOutputFormatOptions = {
onPacket?: (data: Uint8Array, position: number) => unknown;
};onPacket
每写入一个 188 字节的 Transport Stream 数据包时将被调用。
HLS
此输出格式用于创建与 HTTP Live Streaming (HLS) 协议兼容的媒体文件。HLS 媒体由一组 .m3u8 播放列表文件和媒体片段文件表示,意味着此格式会写入多个文件,需要使用 带路径的 Output(pathed Output)。
此输出格式会创建以下文件:
- 主播放列表 .m3u8 文件,包含可用播放列表的列表。主播放列表始终会被发出,并写入根路径。
- 每个播放列表对应一个 .m3u8 文件,每个文件包含媒体片段列表。
- 许多媒体片段,包含实际的媒体数据。
若要发出使用 #EXT-X-PROGRAM-DATE-TIME 标签将片段时间戳映射到现实时间的媒体播放列表,请将所有输出轨道的 BaseTrackMetadata.isRelativeToUnixEpoch 设置为 true。
import { Output, PathedTarget, MpegTsOutputFormat } from 'mediabunny';
const output = new Output({
format: new HlsOutputFormat(options),
target: new PathedTarget('master.m3u8', ({ path }) => {
// 返回一个目标
}),
});此格式可为主播放列表和媒体播放列表确保仅追加写入;对于媒体片段,则取决于媒体片段的格式。
以下选项可用:
export type HlsOutputFormatOptions = {
segmentFormat: OutputFormat | OutputFormat[];
targetDuration?: number;
singleFilePerPlaylist?: boolean;
live?: boolean;
maxLiveSegmentCount?: number;
getPlaylistPath?: (info: HlsOutputPlaylistInfo) => MaybePromise<FilePath>;
getSegmentPath?: (info: HlsOutputSegmentInfo) => MaybePromise<FilePath>;
getInitPath?: (info: HlsOutputPlaylistInfo) => MaybePromise<FilePath>;
onMaster?: (content: string) => unknown;
onPlaylist?: (content: string, info: HlsOutputPlaylistInfo) => unknown;
onSegment?: (target: Target, info: HlsOutputSegmentInfo) => unknown;
onInit?: (target: Target, info: HlsOutputPlaylistInfo) => unknown;
};segmentFormat
必填。指定每个媒体段(media segment)的文件格式。并非所有播放器都支持所有格式;建议优先使用最常用的格式:MpegTsOutputFormat、CmafOutputFormat、AdtsOutputFormat和Mp3OutputFormat。当指定格式数组时,对于每个播放列表(playlist),会选择第一个能够包含该播放列表所有轨道的格式。这使得您例如可以将音频打包为.aac文件,将视频打包为.ts文件。
targetDuration
指定每个媒体段的目标(最大)持续时间(秒),默认为2秒。Mediabunny 会尝试不生成超过目标持续时间的媒体段,但如果提供的关键帧间隔长于目标持续时间,则被迫生成更长的段。因此,请确保至少每
targetDuration秒编码一个关键帧以保证段长度,这可以通过VideoEncodingConfig.keyFrameInterval进行控制。singleFilePerPlaylist
是否将播放列表的所有媒体段捆绑到单个文件中。然后通过范围请求提取单独的段。live
如果为true,复用器将处于“直播模式”,随着新段的创建持续发出更新的播放列表。主播放列表将在所有播放列表至少被发出一次后立即发出,并且每次有段最终确定时都会继续发出,以进一步细化BANDWIDTH属性的准确性。当为
false(默认值)时,所有播放列表仅在输出最终确定时发出一次。maxLiveSegmentCount
在直播模式下,此参数控制每个播放列表中包含的最大段数。默认为Infinity,意味着播放列表的大小会持续增长。getPlaylistPath
返回给定媒体播放列表的文件路径。如果返回的路径是相对的,则相对于根路径。默认为
'playlist-{n}.m3u8',其中n是主播放列表中媒体播放列表的基于1的索引。getSegmentPath
返回给定媒体段的文件路径。如果返回的路径是相对的,则相对于包含它的播放列表的路径。默认为
'segment-{n}-{k}{ext}',其中n是主播放列表中包含媒体播放列表的基于1的索引,k是该播放列表中段的基于1的索引,ext是段格式的文件扩展名(包括前导点)。如果
singleFilePerPlaylist为true,则默认为'segments-{n}{ext}'。getInitPath
返回给定媒体初始化段(init segment)的文件路径。如果返回的路径是相对的,则相对于包含它的播放列表的路径。仅对需要初始化文件的段格式(如
CmafOutputFormat)必要。默认为
'init-{n}{ext}',其中n是主播放列表中包含媒体播放列表的基于1的索引,ext是段格式的文件扩展名(包括前导点)。onMaster
每当写入主播放列表时调用。onPlaylist
每当写入媒体播放列表时调用。onSegment
每当媒体段完全写入后调用。在单文件模式下,此函数仅在播放列表最终确定时调用一次。onInit
在媒体播放列表初始化时调用,在任何段写入之前。在单文件模式下,此函数永远不会被调用。