webcodecs-utils
v0.2.5
Published
Utility functions for working with WebCodecs API
Maintainers
Readme
webcodecs-utils
Utility functions for working with the WebCodecs API, extracted from WebCodecs Fundamentals.
Installation
npm install webcodecs-utilsQuick Start
import { getBitrate, GPUFrameRenderer, extractChannels, MP4Demuxer } from 'webcodecs-utils';
// Calculate optimal bitrate (defaults to 30fps)
const bitrate = getBitrate(1920, 1080);
// Zero-copy video rendering with WebGPU
const renderer = new GPUFrameRenderer(canvas);
await renderer.init();
renderer.drawImage(videoFrame);
// Extract audio channels
const decoder = new AudioDecoder({
output: (audioData) => {
const channels = extractChannels(audioData);
const leftChannel = channels[0];
const rightChannel = channels[1];
},
error: (e) => console.error(e)
});
// Parse MP4 files
const demuxer = new MP4Demuxer(file);
await demuxer.load();
const videoChunks = await demuxer.extractSegment('video', 0, 10);Utilities
Video
getBitrate
Calculate optimal bitrate for video encoding based on resolution, framerate, and quality.
function getBitrate(
width: number,
height: number,
fps?: number, // default: 30
quality?: 'low' | 'good' | 'high' | 'very-high' // default: 'good'
): numbergetCodecString
Generate proper codec strings (avc1, vp09, etc.) with correct profile/level for VideoEncoder configuration.
function getCodecString(
codec: 'avc' | 'hevc' | 'vp8' | 'vp9' | 'av1',
width: number,
height: number,
bitrate: number
): stringGPUFrameRenderer
Zero-copy video frame rendering using WebGPU importExternalTexture, with fallback to ImageBitmapRenderer.
class GPUFrameRenderer {
constructor(canvas: HTMLCanvasElement | OffscreenCanvas, options?: {
filterMode?: 'linear' | 'bicubic'
})
async init(): Promise<void>
drawImage(videoFrame: VideoFrame): void
getMode(): 'webgpu' | 'bitmap' | null
getFilterMode(): 'linear' | 'bicubic'
setFilterMode(mode: 'linear' | 'bicubic'): void
destroy(): void
}Audio
extractChannels
Extract and de-interleave audio channels from AudioData into Float32Array[].
Handles both planar (f32-planar) and interleaved (f32) audio formats automatically. Returns an array of Float32Array buffers, one per channel (e.g., [left, right] for stereo).
function extractChannels(audioData: AudioData): Float32Array[]Example:
const channels = extractChannels(audioData);
const leftChannel = channels[0];
const rightChannel = channels[1]; // if stereo
// Process audio samples
for (let i = 0; i < leftChannel.length; i++) {
leftChannel[i] *= 0.5; // Reduce volume by 50%
}MP3Encoder
Encode AudioData to MP3 format using LameJS.
class MP3Encoder {
constructor(config: {
sampleRate: number;
bitRate: number;
channels: number;
})
processBatch(audioData: AudioData): Uint8Array
finish(): Blob
getEncodedSize(): number
}MP3Decoder
Decode MP3 files to raw PCM samples or AudioData objects.
class MP3Decoder {
constructor()
async initialize(): Promise<void>
async toSamples(mp3Buffer: ArrayBuffer): Promise<{
channels: Float32Array[],
sampleRate: number,
numberOfChannels: number
}>
async toAudioData(mp3Buffer: ArrayBuffer): Promise<AudioData[]>
async destroy(): Promise<void>
}Demux/Mux
MP4Demuxer
Parse MP4 files and extract EncodedVideoChunk/EncodedAudioChunk objects using MP4Box.
class MP4Demuxer {
constructor(file: File)
async load(onProgress?: (progress: number) => void): Promise<void>
getTracks(): TrackData
getVideoTrack(): VideoTrackData | undefined
getAudioTrack(): AudioTrackData | undefined
getVideoDecoderConfig(): VideoDecoderConfig | undefined
getAudioDecoderConfig(): AudioDecoderConfig | undefined
async extractSegment(
trackType: 'audio' | 'video',
startTime: number,
endTime: number
): Promise<EncodedVideoChunk[] | EncodedAudioChunk[]>
getInfo(): MP4Info
}Example:
const demuxer = new MP4Demuxer(file);
await demuxer.load((progress) => console.log(`Loading: ${progress * 100}%`));
const videoTrack = demuxer.getVideoTrack();
console.log(`Video: ${videoTrack.codec}, ${videoTrack.codedWidth}x${videoTrack.codedHeight}`);
const videoChunks = await demuxer.extractSegment('video', 0, 10);Browser Support
These utilities require:
- WebCodecs API - Chrome 94+, Edge 94+, Safari 17.4+ (some features)
- WebGPU (optional) - Chrome 113+, Edge 113+, Safari 18+ (for GPUFrameRenderer)
All utilities include compatibility checks and graceful degradation where applicable.
Development
# Install dependencies
npm install
# Start demo server (localhost:5173)
npm run dev
# Build library
npm run buildLicense
MIT
Related
- WebCodecs Fundamentals - Comprehensive WebCodecs guide
- MediaBunny - Full-featured WebCodecs library
