Create a new media file from scratch using various sources:
import { Output, BufferTarget, Mp4OutputFormat, CanvasSource, AudioBufferSource, QUALITY_HIGH,} from 'mediabunny';// An Output represents a new media fileconst output = new Output({ format: new Mp4OutputFormat(), // The format of the file target: new BufferTarget(), // Where to write the file (here, to memory)});// Example: add a video track driven by a canvasconst videoSource = new CanvasSource(canvas, { codec: 'avc', bitrate: QUALITY_HIGH,});output.addVideoTrack(videoSource);// Example: add an audio track driven by AudioBuffersconst audioSource = new AudioBufferSource({ codec: 'aac', bitrate: QUALITY_HIGH,});output.addAudioTrack(audioSource);// Set some metadata tagsoutput.setMetadataTags({ title: 'My Movie', artist: 'Me',});await output.start();// Add some video framesfor (let frame = 0; frame < 900; frame++) { await videoSource.add(frame / 30, 1 / 30);}// Add some audio dataawait audioSource.add(audioBuffer1);await audioSource.add(audioBuffer2);await output.finalize();const buffer = output.target.buffer; // ArrayBuffer containing the final MP4 file
You can create files of many different formats - see Output formats
Media data can be added from different sources - see Media sources
Convert between different media formats with automatic transmuxing or transcoding:
import { Input, Output, Conversion, ALL_FORMATS, BlobSource, BufferTarget, Mp4OutputFormat,} from 'mediabunny';// Create an input from the source fileconst input = new Input({ formats: ALL_FORMATS, source: new BlobSource(file),});// Define the output fileconst output = new Output({ format: new Mp4OutputFormat(), target: new BufferTarget(),});const conversion = await Conversion.init({ input, output });if (!conversion.isValid) { // The conversion isn't possible and would error upon execution. // Check `discardedTracks` for the reasons. return;}// List of tracks that won't make it into the output:conversion.discardedTracks;conversion.onProgress = (progress) => { console.log(`Progress: ${progress * 100}%`);};await conversion.execute();// Conversion is completeconst buffer = output.target.buffer; // ArrayBuffer containing the final MP4 file
This code will automatically transmux (copy media data) when possible, and transcode (re-encode media data) when necessary.
Decode video frames and audio chunks from a media file:
import { Input, ALL_FORMATS, BlobSource, VideoSampleSink, AudioSampleSink,} from 'mediabunny';const input = new Input({ formats: ALL_FORMATS, source: new BlobSource(file),});// Read video framesconst videoTrack = await input.getPrimaryVideoTrack();if (videoTrack) { const decodable = await videoTrack.canDecode(); if (decodable) { const sink = new VideoSampleSink(videoTrack); // Get the video frame at timestamp 5s const videoSample = await sink.getSample(5); videoSample.timestamp; // in seconds videoSample.duration; // in seconds // Draw the frame to a canvas videoSample.draw(ctx, 0, 0); // Loop over all frames in the first 30s of video for await (const sample of sink.samples(0, 30)) { // Process each frame... } }}
See Media sinks for all the ways to extract media data from tracks.
2
Extract video thumbnails
Generate thumbnail images from video files:
import { Input, ALL_FORMATS, BlobSource, CanvasSink,} from 'mediabunny';const input = new Input({ formats: ALL_FORMATS, source: new BlobSource(file),});const videoTrack = await input.getPrimaryVideoTrack();if (videoTrack) { const decodable = await videoTrack.canDecode(); if (decodable) { const sink = new CanvasSink(videoTrack, { width: 320, // Automatically resize the thumbnails }); // Get the thumbnail at timestamp 10s const result = await sink.getCanvas(10); result.canvas; // HTMLCanvasElement | OffscreenCanvas result.timestamp; // in seconds result.duration; // in seconds // Generate five equally-spaced thumbnails through the video const startTimestamp = await videoTrack.getFirstTimestamp(); const endTimestamp = await videoTrack.computeDuration(); const timestamps = [0, 0.2, 0.4, 0.6, 0.8].map( (t) => startTimestamp + t * (endTimestamp - startTimestamp) ); // Loop over these timestamps for await (const result of sink.canvasesAtTimestamps(timestamps)) { // Process each thumbnail... } }}
3
Compress media files
Reduce file size by resizing, lowering quality, or trimming:
import { Input, Output, Conversion, ALL_FORMATS, BlobSource, BufferTarget, Mp4OutputFormat, QUALITY_LOW,} from 'mediabunny';const input = new Input({ formats: ALL_FORMATS, source: new BlobSource(file),});const output = new Output({ format: new Mp4OutputFormat(), target: new BufferTarget(),});const conversion = await Conversion.init({ input, output, video: track => ({ width: 480, bitrate: QUALITY_LOW, discard: track.number > 1, // Keep only the first video track }), audio: track => ({ numberOfChannels: 1, bitrate: QUALITY_LOW, discard: track.number > 1, // Keep only the first audio track }), trim: { // Keep only the first 60 seconds start: 0, end: 60, }, tags: {}, // Remove any metadata tags});await conversion.execute();
4
Record live media
Capture from webcam or microphone and save to a file:
import { Output, BufferTarget, WebMOutputFormat, MediaStreamVideoTrackSource, MediaStreamAudioTrackSource, QUALITY_MEDIUM} from 'mediabunny';const userMedia = await navigator.mediaDevices.getUserMedia({ video: true, audio: true,});const videoTrack = userMedia.getVideoTracks()[0];const audioTrack = userMedia.getAudioTracks()[0];const output = new Output({ format: new WebMOutputFormat(), target: new BufferTarget(),});if (videoTrack) { const source = new MediaStreamVideoTrackSource(videoTrack, { codec: 'vp9', bitrate: QUALITY_MEDIUM, }); output.addVideoTrack(source);}if (audioTrack) { const source = new MediaStreamAudioTrackSource(audioTrack, { codec: 'opus', bitrate: QUALITY_MEDIUM, }); output.addAudioTrack(source);}await output.start();// Recording happens automatically...// Stop when ready:await output.finalize();