mediabunny
Version:
Pure TypeScript media toolkit for reading, writing, and converting media files, directly in the browser.
372 lines • 15.1 kB
TypeScript
/*!
* Copyright (c) 2026-present, Vanilagy and contributors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import { AudioCodec, MediaCodec, SubtitleCodec, VideoCodec } from './codec.js';
import { MaybePromise, Rotation } from './misc.js';
import { EncodedPacket } from './packet.js';
import { AudioSample, CropRectangle, VideoSample, VideoSampleResource } from './sample.js';
export declare const canEncodeVideoMemo: Map<string, Promise<boolean>>;
export declare const canEncodeAudioMemo: Map<string, Promise<boolean>>;
/**
* Configuration object that controls video encoding. Can be used to set codec, quality, and more.
* @group Encoding
* @public
*/
export type VideoEncodingConfig = {
/** The video codec that should be used for encoding the video samples (frames). */
codec: VideoCodec;
/**
* The target bitrate for the encoded video, in bits per second. Alternatively, a subjective {@link Quality} can
* be provided.
*/
bitrate: number | Quality;
/**
* The interval, in seconds, of how often frames are encoded as a key frame. The default is 2 seconds. Frequent key
* frames improve seeking behavior but increase file size. When using multiple video tracks, you should give them
* all the same key frame interval.
*/
keyFrameInterval?: number;
/**
* Video frames may change size over time. This field controls the behavior in case this happens.
*
* - `'deny'` (default) will throw an error, requiring all frames to have the exact same dimensions.
* - `'passThrough'` will allow the change and directly pass the frame to the encoder.
* - `'fill'` will stretch the image to fill the entire original box, potentially altering aspect ratio.
* - `'contain'` will contain the entire image within the original box while preserving aspect ratio. This may lead
* to letterboxing.
* - `'cover'` will scale the image until the entire original box is filled, while preserving aspect ratio.
*
* The "original box" refers to the dimensions of the first encoded frame.
*/
sizeChangeBehavior?: 'deny' | 'passThrough' | 'fill' | 'contain' | 'cover';
/**
* Optional transformations to apply to the video frames before they are passed to the encoder.
*/
transform?: VideoTransformOptions;
/** Called for each successfully encoded packet. Both the packet and the encoding metadata are passed. */
onEncodedPacket?: (packet: EncodedPacket, meta: EncodedVideoChunkMetadata | undefined) => unknown;
/**
* Called when the internal [encoder config](https://www.w3.org/TR/webcodecs/#video-encoder-config), as used by the
* WebCodecs API, is created.
*/
onEncoderConfig?: (config: VideoEncoderConfig) => unknown;
} & VideoEncodingAdditionalOptions;
/**
* Options for transforming video frames before encoding.
* @group Encoding
* @public
*/
export type VideoTransformOptions = {
/**
* The width in pixels to resize the frames to. If height is not set, it will be deduced
* automatically based on aspect ratio.
*/
width?: number;
/**
* The height in pixels to resize the frames to. If width is not set, it will be deduced
* automatically based on aspect ratio.
*/
height?: number;
/**
* The fitting algorithm in case both width and height are set.
*
* - `'fill'` will stretch the image to fill the entire box, potentially altering aspect ratio.
* - `'contain'` will contain the entire image within the box while preserving aspect ratio. This may lead to
* letterboxing.
* - `'cover'` will scale the image until the entire box is filled, while preserving aspect ratio.
*
* To avoid ambiguity, this field must not be set when `sizeChangeBehavior` is `'fill'`, `'contain'` or
* `'deny'`, since `sizeChangeBehavior` already determines the fitting algorithm.
*/
fit?: 'fill' | 'contain' | 'cover';
/**
* The clockwise rotation by which to rotate the frames. Rotation is applied before resizing.
*/
rotate?: Rotation;
/**
* Specifies the rectangular region of the frames to crop to. The crop region will automatically be
* clamped to the dimensions of the frame. Cropping is performed after rotation but before resizing.
*/
crop?: CropRectangle;
/**
* Whether to discard or keep the transparency information of the video samples. The default is `'keep'`.
*/
alpha?: 'keep' | 'discard';
/**
* The frame rate in hertz to normalize the video frame stream to.
*/
frameRate?: number;
/**
* Allows for custom user-defined processing of video frames, e.g. for applying overlays, color transformations,
* or timestamp modifications. Will be called for each video frame after transformations and frame rate
* corrections.
*
* Must return a {@link VideoSample}, a {@link VideoSampleResource} or a `CanvasImageSource`, an array of them, or
* `null` for dropping the frame. When non-timestamped data is returned, the timestamp and duration from the input
* sample will be used.
*/
process?: (sample: VideoSample) => MaybePromise<CanvasImageSource | VideoSample | VideoSampleResource | (CanvasImageSource | VideoSample | VideoSampleResource)[] | null>;
/**
* Forces every video frame through the transformation step even if no transformation properties are defined.
* This can be used, for example, to bake rotation into the encoded video frames.
*/
force?: boolean;
};
export declare const validateVideoEncodingConfig: (config: VideoEncodingConfig) => void;
/**
* Additional options that control video encoding.
* @group Encoding
* @public
*/
export type VideoEncodingAdditionalOptions = {
/**
* What to do with alpha data contained in the video samples.
*
* - `'discard'` (default): Only the samples' color data is kept; the video is opaque.
* - `'keep'`: The samples' alpha data is also encoded as side data. Make sure to pair this mode with a container
* format that supports transparency (such as WebM or Matroska).
*/
alpha?: 'discard' | 'keep';
/** Configures the bitrate mode; defaults to `'variable'`. */
bitrateMode?: 'constant' | 'variable';
/**
* The latency mode used by the encoder; controls the performance-quality tradeoff.
*
* - `'quality'` (default): The encoder prioritizes quality over latency, and no frames can be dropped.
* - `'realtime'`: The encoder prioritizes low latency over quality, and may drop frames if the encoder becomes
* overloaded to keep up with real-time requirements.
*/
latencyMode?: 'quality' | 'realtime';
/**
* The full codec string as specified in the Mediabunny Codec Registry. This string must match the codec
* specified in `codec`. When not set, a fitting codec string will be constructed automatically by the library.
*/
fullCodecString?: string;
/**
* A hint that configures the hardware acceleration method of this codec. This is best left on `'no-preference'`,
* the default.
*/
hardwareAcceleration?: 'no-preference' | 'prefer-hardware' | 'prefer-software';
/**
* An encoding scalability mode identifier as defined by
* [WebRTC-SVC](https://w3c.github.io/webrtc-svc/#scalabilitymodes*).
*/
scalabilityMode?: string;
/**
* An encoding video content hint as defined by
* [mst-content-hint](https://w3c.github.io/mst-content-hint/#video-content-hints).
*/
contentHint?: string;
};
export declare const validateVideoEncodingAdditionalOptions: (codec: VideoCodec, options: VideoEncodingAdditionalOptions) => void;
export declare const buildVideoEncoderConfig: (options: {
codec: VideoCodec;
width: number;
height: number;
bitrate: number | Quality;
framerate: number | undefined;
squarePixelWidth?: number;
squarePixelHeight?: number;
} & VideoEncodingAdditionalOptions) => VideoEncoderConfig;
/**
* Configuration object that controls audio encoding. Can be used to set codec, quality, and more.
* @group Encoding
* @public
*/
export type AudioEncodingConfig = {
/** The audio codec that should be used for encoding the audio samples. */
codec: AudioCodec;
/**
* The target bitrate for the encoded audio, in bits per second. Alternatively, a subjective {@link Quality} can
* be provided. Required for compressed audio codecs, unused for PCM codecs.
*/
bitrate?: number | Quality;
/**
* Optional transformations to apply to the audio samples before they are passed to the encoder.
*/
transform?: AudioTransformOptions;
/** Called for each successfully encoded packet. Both the packet and the encoding metadata are passed. */
onEncodedPacket?: (packet: EncodedPacket, meta: EncodedAudioChunkMetadata | undefined) => unknown;
/**
* Called when the internal [encoder config](https://www.w3.org/TR/webcodecs/#audio-encoder-config), as used by the
* WebCodecs API, is created.
*/
onEncoderConfig?: (config: AudioEncoderConfig) => unknown;
} & AudioEncodingAdditionalOptions;
/**
* Options for transforming audio samples before encoding.
* @group Encoding
* @public
*/
export type AudioTransformOptions = {
/** The desired number of output channels to up/downmix to. */
numberOfChannels?: number;
/** The desired output sample rate in hertz to resample to. */
sampleRate?: number;
/**
* The desired sample format (and therefore bit depth) of the audio samples before they are passed to the encoder.
* Can be used to control bit depth with certain output codecs such as FLAC.
*/
sampleFormat?: 'u8' | 's16' | 's32' | 'f32';
/**
* Allows for custom user-defined processing of audio samples, e.g. for applying audio effects or timestamp
* modifications. Called for each audio sample after resampling and remixing.
*
* Must return an {@link AudioSample}, an array of them, or `null` for dropping the sample.
*/
process?: (sample: AudioSample) => MaybePromise<AudioSample | AudioSample[] | null>;
};
export declare const validateAudioEncodingConfig: (config: AudioEncodingConfig) => void;
/**
* Additional options that control audio encoding.
* @group Encoding
* @public
*/
export type AudioEncodingAdditionalOptions = {
/** Configures the bitrate mode. */
bitrateMode?: 'constant' | 'variable';
/**
* The full codec string as specified in the Mediabunny Codec Registry. This string must match the codec
* specified in `codec`. When not set, a fitting codec string will be constructed automatically by the library.
*/
fullCodecString?: string;
};
export declare const validateAudioEncodingAdditionalOptions: (codec: AudioCodec, options: AudioEncodingAdditionalOptions) => void;
export declare const buildAudioEncoderConfig: (options: {
codec: AudioCodec;
numberOfChannels: number;
sampleRate: number;
bitrate?: number | Quality;
} & AudioEncodingAdditionalOptions) => AudioEncoderConfig;
/**
* Represents a subjective media quality level.
* @group Encoding
* @public
*/
export declare class Quality {
}
/**
* Represents a very low media quality.
* @group Encoding
* @public
*/
export declare const QUALITY_VERY_LOW: Quality;
/**
* Represents a low media quality.
* @group Encoding
* @public
*/
export declare const QUALITY_LOW: Quality;
/**
* Represents a medium media quality.
* @group Encoding
* @public
*/
export declare const QUALITY_MEDIUM: Quality;
/**
* Represents a high media quality.
* @group Encoding
* @public
*/
export declare const QUALITY_HIGH: Quality;
/**
* Represents a very high media quality.
* @group Encoding
* @public
*/
export declare const QUALITY_VERY_HIGH: Quality;
/**
* Checks if the browser is able to encode the given codec.
* @group Encoding
* @public
*/
export declare const canEncode: (codec: MediaCodec) => Promise<boolean>;
/**
* Checks if the browser is able to encode the given video codec with the given parameters.
* @group Encoding
* @public
*/
export declare const canEncodeVideo: (codec: VideoCodec, options?: {
width?: number;
height?: number;
bitrate?: number | Quality;
} & VideoEncodingAdditionalOptions) => Promise<boolean>;
/**
* Checks if the browser is able to encode the given audio codec with the given parameters.
* @group Encoding
* @public
*/
export declare const canEncodeAudio: (codec: AudioCodec, options?: {
numberOfChannels?: number;
sampleRate?: number;
bitrate?: number | Quality;
} & AudioEncodingAdditionalOptions) => Promise<boolean>;
/**
* Checks if the browser is able to encode the given subtitle codec.
* @group Encoding
* @public
*/
export declare const canEncodeSubtitles: (codec: SubtitleCodec) => Promise<boolean>;
/**
* Returns the list of all media codecs that can be encoded by the browser.
* @group Encoding
* @public
*/
export declare const getEncodableCodecs: () => Promise<MediaCodec[]>;
/**
* Returns the list of all video codecs that can be encoded by the browser.
* @group Encoding
* @public
*/
export declare const getEncodableVideoCodecs: (checkedCodecs?: VideoCodec[], options?: {
width?: number;
height?: number;
bitrate?: number | Quality;
}) => Promise<VideoCodec[]>;
/**
* Returns the list of all audio codecs that can be encoded by the browser.
* @group Encoding
* @public
*/
export declare const getEncodableAudioCodecs: (checkedCodecs?: AudioCodec[], options?: {
numberOfChannels?: number;
sampleRate?: number;
bitrate?: number | Quality;
}) => Promise<AudioCodec[]>;
/**
* Returns the list of all subtitle codecs that can be encoded by the browser.
* @group Encoding
* @public
*/
export declare const getEncodableSubtitleCodecs: (checkedCodecs?: SubtitleCodec[]) => Promise<SubtitleCodec[]>;
/**
* Returns the first video codec from the given list that can be encoded by the browser.
* @group Encoding
* @public
*/
export declare const getFirstEncodableVideoCodec: (checkedCodecs: VideoCodec[], options?: {
width?: number;
height?: number;
bitrate?: number | Quality;
}) => Promise<VideoCodec | null>;
/**
* Returns the first audio codec from the given list that can be encoded by the browser.
* @group Encoding
* @public
*/
export declare const getFirstEncodableAudioCodec: (checkedCodecs: AudioCodec[], options?: {
numberOfChannels?: number;
sampleRate?: number;
bitrate?: number | Quality;
}) => Promise<AudioCodec | null>;
/**
* Returns the first subtitle codec from the given list that can be encoded by the browser.
* @group Encoding
* @public
*/
export declare const getFirstEncodableSubtitleCodec: (checkedCodecs: SubtitleCodec[]) => Promise<SubtitleCodec | null>;
//# sourceMappingURL=encode.d.ts.map