Functions
Functions and constants exported by @mcut/media.
Constants
DEFAULT_ACTIVITY_FRAME_MS
const DEFAULT_ACTIVITY_FRAME_MS = 30Default analysis frame length for audio activity, 30 ms.
DEFAULT_ACTIVITY_THRESHOLD
const DEFAULT_ACTIVITY_THRESHOLD = 0.004Default RMS level above which a frame counts as sound.
DEFAULT_MIN_SILENCE_MS
const DEFAULT_MIN_SILENCE_MS = 120Default length below which a silent run is treated as sound, 120 ms.
DEFAULT_MIN_SOUND_MS
const DEFAULT_MIN_SOUND_MS = 120Default length below which a sound run is treated as silence, 120 ms.
MAX_HASHABLE_BYTES
const MAX_HASHABLE_BYTES = 512 * 1024 * 1024The largest blob size that hashBlob will digest, 512 MiB.
containerFormats
const containerFormats = {
mp4: {
label: 'MP4',
extension: 'mp4',
mimeType: 'video/mp4',
createOutputFormat: () => Promise<Mp4OutputFormat>,
},
webm: {
label: 'WebM',
extension: 'webm',
mimeType: 'video/webm',
createOutputFormat: () => Promise<WebMOutputFormat>,
},
mkv: {
label: 'MKV',
extension: 'mkv',
mimeType: 'video/x-matroska',
createOutputFormat: () => Promise<MkvOutputFormat>,
},
} satisfies Record<string, ContainerFormat>The closed table of export containers, MP4, WebM, and MKV, each muxed by the matching Mediabunny output format. Each factory is async () => new (await import('mediabunny')).Mp4OutputFormat() and so on, because Mediabunny loads on first use.
Functions
mediabunnyProber
const mediabunnyProber: MediaProberThe default MediaProber. Its id is mediabunny and its probe reads a blob origin through probeMedia.
createAsset
async function createAsset(origin: MediaOrigin, prober: MediaProber = mediabunnyProber): Promise<AssetRef>Probes a media origin with the given prober and returns an AssetRef with an object URL as src and a SHA-256 hash when the blob is small enough to hash. Image origins skip the prober and are measured with probeImage.
preloadMediabunny
async function preloadMediabunny(): Promise<void>Loads Mediabunny ahead of the first media call. Call it once the shell has painted so the first import or preview does not wait on the download.
inputFor
async function inputFor(src: MediaSourceLike): Promise<Input>Opens a Mediabunny Input over a blob or a blob or HTTP URL. Mediabunny itself loads on the first call, so nothing in @mcut/media pulls the demuxers and muxers into an app's startup bundle.
probeImage
function probeImage(src: string): Promise<{ width: number; height: number }>Loads an image URL in the browser and resolves with its intrinsic width and height.
probeMedia
async function probeMedia(src: MediaSourceLike): Promise<MediaProbe>Reads the duration, dimensions, track presence, and MIME type of an audio or video file.
getVideoThumbnail
async function getVideoThumbnail(
src: MediaSourceLike,
options: ThumbnailOptions = {},
): Promise<HTMLCanvasElement | OffscreenCanvas | null>Captures one poster frame from a video into a canvas, preferring native video capture and falling back to a Mediabunny canvas sink, or returns null for audio-only files.
getVideoThumbnailUrl
async function getVideoThumbnailUrl(
src: MediaSourceLike,
options: ThumbnailOptions = {},
): Promise<string | null>Returns a poster frame as a data URL, or null for audio-only files.
extractAudioToWav
async function extractAudioToWav(
src: MediaSourceLike,
options: ExtractAudioOptions = {},
): Promise<Blob | null>Decodes a file's audio track into a PCM WAV blob at 16 kHz mono by default, retrying without resampling when conversion fails, or returns null when there is no audio track.
ensureFallbackAudioEncoders
function ensureFallbackAudioEncoders(): Promise<void>Registers the WASM AAC encoder once when the runtime cannot encode AAC natively, loading it on demand.
getActiveMediaItems
function getActiveMediaItems(project: Project, timeMs: number): ActiveMediaItem[]Returns the video feeds the preview pool keeps live at timeMs on visible tracks, with their source time, rate, and reversal. Audio clips and audio-only multicam sources are left out because PreviewAudio plays sound.
exportProject
async function exportProject(
project: Project,
options: ExportProjectOptions = {},
): Promise<ExportResult>Renders a project to a video file in the browser, mixing audio on the main thread and then decoding, compositing, encoding, and muxing frames in a worker when one is available.
getExportSupport
async function getExportSupport(format: ContainerFormatId = 'mp4'): Promise<{
video: boolean
audio: boolean
}>Resolves with whether the browser can encode video and audio for the given container format.
renderProjectStill
Renders one timeline frame to a PNG blob. A timeMs past the project end throws, and the error names the project duration. A timeMs at the project end renders the last frame. soloElementId draws only that element, including a multicam composite, and throws when that element is not on screen. width caps the PNG width and keeps the project aspect ratio. Omit it to render at the project size. The result carries the PNG blob, the pixel size, and the ids of the elements drawn.
findSceneChanges
async function findSceneChanges(project: Project, options?: SceneChangeOptions): Promise<SceneChangeReport>Reports the timeline times where the picture of one video clip or one multicam source changes. It decodes the source, downscales every frame it samples to 64 by 36 luma, and compares each sample with the one stepMs before it. A pair counts as a change when the fraction of cells whose luma moves by more than 24 of 255 reaches the threshold for sensitivity. It then decodes every frame between that pair and puts the change on the frame with the largest difference. The report lists the changes with the fraction that changed, and the segments between them.
renderContactSheet
async function renderContactSheet(project: Project, options?: ContactSheetOptions): Promise<ContactSheet>Renders a PNG grid of thumbnails of one video clip or one multicam source, one tile per time, each labelled with its timeline time in seconds. Pass timesMs for exact times, or count to spread tiles evenly over the range. Times outside the range are dropped, and the call throws when none is left.
listContainerFormats
function listContainerFormats(): ContainerFormatEntry[]Returns every entry of the containerFormats table with its id, in table order.
getFilmstrip
async function getFilmstrip(
src: MediaSourceLike,
options: FilmstripOptions,
): Promise<Filmstrip | null>Draws evenly spaced frames of a video side by side into one canvas, preferring native video capture and falling back to a Mediabunny canvas sink, or returns null.
canUseNativeVideoPreview
function canUseNativeVideoPreview(media: VideoPreviewCapability): booleanReturns true when an asset plays through a native video element rather than decoded frames, based on its nativePreview flag, container, and canPlayType.
isMatroskaLike
function isMatroskaLike(media: VideoPreviewCapability): booleanReturns true when the file name or MIME type indicates a Matroska container.
bucketPeaks
function bucketPeaks(samples: Float32Array, buckets: number): Float32ArrayFolds samples into the given number of buckets, each holding the maximum absolute amplitude of its span.
extractAudioPeaks
async function extractAudioPeaks(
src: MediaSourceLike,
options: AudioPeaksOptions = {},
): Promise<AudioPeaks | null>Decodes a file's audio and reduces it to waveform peaks over the source range, or returns null when there is no audio track.
analyzeAudioActivity
async function analyzeAudioActivity(
src: MediaSourceLike,
options: AudioActivityOptions = {},
): Promise<AudioActivity | null>Decodes a media source's primary audio track and returns its sound and silence windows, or null when there is no audio track.
analyzeAudioSamples
function analyzeAudioSamples(
samples: Float32Array,
sampleRate: number,
options: AudioActivityOptions = {},
): AudioActivitySplits mono PCM samples into frames, classifies them by RMS, smooths short runs, and returns sound and silence windows with a summary.
hashBlob
async function hashBlob(blob: Blob): Promise<string | null>Returns the SHA-256 hex digest of a blob, or null when the store is unsupported or the blob is too large.
isMediaStoreSupported
function isMediaStoreSupported(): booleanReturns true when the origin private file system and WebCrypto are available.
loadMediaBlob
async function loadMediaBlob(hash: string): Promise<Blob | null>Loads the blob stored under a hash from the origin private file system, or null.
pruneMediaBlobs
async function pruneMediaBlobs(keep: ReadonlySet<string>): Promise<number>Deletes stored blobs whose hash is not in keep and returns how many were removed.
saveMediaBlob
async function saveMediaBlob(hash: string, blob: Blob): Promise<boolean>Stores a blob under its hash in the origin private file system, skipping the write when it is already present, and returns whether it is stored.
constantSpeedOf
function constantSpeedOf(timeMap: TimeMap | undefined): ConstantSpeed | nullReturns the constant rate and source span a two-point linear time map encodes, or null for ramps and freezes.
stretchStereo
async function stretchStereo(data: StereoData, tempo: number): Promise<StereoData>Stretches stereo PCM by tempo with pitch preserved, so a tempo of 2 yields half the length.
crossCorrelateEnvelopes
function crossCorrelateEnvelopes(
a: Float32Array,
b: Float32Array,
maxLagBuckets: number,
): { lag: number; confidence: number }Cross-correlates two zero-meaned envelopes over a bounded lag range and returns the lag in buckets that best aligns b to a together with a confidence score.
extractEnvelope
async function extractEnvelope(
src: MediaSourceLike,
{ windowS = 60, rateHz = 100, signal }: AudioSyncOptions = {},
): Promise<Float32Array | null>Decodes the first windowS seconds of a source's audio into an RMS envelope at rateHz buckets per second, or null without audio.
findSyncOffsetMs
async function findSyncOffsetMs(
a: MediaSourceLike,
b: MediaSourceLike,
options: AudioSyncOptions = {},
): Promise<SyncResult | null>Returns how many milliseconds after recording a started recording b started, with a confidence score, or null when either has no audio.
createLocalFaceDetector
createLocalFaceDetector(options) returns a detector whose detect(src, { sampleRateHz, signal }) reads a video in a module worker, 5 times a second by default, and resolves to one FaceSample per sample time. The worker bundles the MIT-licensed YuNet 2023mar model from OpenCV Zoo, so no run downloads it. Calls run one at a time, and an aborted signal rejects its call and stops the worker.
| Option | Meaning |
|---|---|
ortWasmPaths | { mjs, wasm } URLs of the onnxruntime files, loaded instead of the jsDelivr copies |
onProgress | Called with { phase, progress }, where phase is model during the download and detect while frames are read, and progress runs from 0 to 1 |
createWorker | Replaces the worker the detector starts |