Skip to main content
Media sinks provide APIs for extracting media data from input files. Like media sources, sinks come at different abstraction levels, letting you choose between convenience and control.

Overview of media sinks

Media sinks can be organized into three abstraction levels:

High-level sinks

CanvasSink, AudioBufferSinkEasy to use, provides processed output ready for display/playback.

Mid-level sinks

VideoSampleSink, AudioSampleSinkAccess to decoded samples, handles decoding internally.

Low-level sinks

EncodedPacketSinkDirect packet access, you handle decoding.

When to use each sink

EncodedPacketSink

Best for: Metadata extraction, remuxing without decoding, custom decoding pipelines EncodedPacketSink provides direct access to encoded packets without decoding. Use this when you only need packet metadata or want to implement custom decoding.
src/media-sink.ts
Advantages:
  • No decoding overhead
  • Access to packet metadata
  • Perfect for remuxing operations
  • Fast iteration over packet structure
Source code: src/media-sink.ts:120-375

VideoSampleSink

Best for: Frame-by-frame processing, video analysis, custom rendering VideoSampleSink decodes video packets into raw VideoFrames, giving you access to decoded pixel data.
src/media-sink.ts
Advantages:
  • Direct access to decoded frames
  • Integration with VideoFrame API
  • Efficient sparse sampling
  • Automatic decoding pipeline
Important: Always call close() on VideoSamples when done to free memory. Source code: src/media-sink.ts:1361-1440

CanvasSink

Best for: Thumbnail generation, video preview, frame export, display in browser CanvasSink provides the most convenient way to extract video frames as canvases, with built-in support for resizing, rotation, and cropping.
src/media-sink.ts
Advantages:
  • Ready-to-display canvases
  • Built-in resizing, rotation, cropping
  • Canvas pooling for memory efficiency
  • Perfect for thumbnails and previews
Source code: src/media-sink.ts:1516-1719

AudioSampleSink

Best for: Audio analysis, waveform generation, custom audio processing AudioSampleSink decodes audio packets into raw AudioData, giving you access to decoded audio samples.
src/media-sink.ts
Advantages:
  • Access to raw audio samples
  • Integration with AudioData API
  • Precise sample-level control
  • Automatic decoding
Source code: src/media-sink.ts:2034-2092

AudioBufferSink

Best for: Web Audio API integration, playback, audio processing with Web Audio AudioBufferSink provides decoded audio as AudioBuffers, ready for use with the Web Audio API.
src/media-sink.ts
Advantages:
  • Direct AudioBuffer support
  • Perfect for Web Audio API
  • Ready for playback
  • Easy audio processing
Source code: src/media-sink.ts:2094+

Advanced usage patterns

Efficient sparse sampling

When you need samples at specific timestamps, use samplesAtTimestamps instead of multiple getSample calls:

Generating thumbnails

Generate evenly-spaced thumbnails efficiently:

Extracting key frames only

Combine EncodedPacketSink with VideoSampleSink to extract only key frames:

Audio waveform generation

Generate a waveform visualization:

Range iteration with break

Exit iteration early while ensuring proper cleanup:

Canvas pool optimization

Use canvas pooling to minimize memory allocation:
For sequential iteration, poolSize: 1 is sufficient and optimal.

Verifying key packets

Some files incorrectly mark packet types. Verify key packets to ensure decoder compatibility:

Metadata-only packet retrieval

When you only need packet metadata, avoid loading packet data:

Decode vs. presentation order

Understanding the difference between decode and presentation order is crucial:
  • Presentation order: The order in which frames are displayed (sorted by timestamp)
  • Decode order: The order in which packets must be decoded (may differ due to B-frames)
Consider frames with B-frames:
EncodedPacketSink methods:
  • packets() - Returns packets in decode order
  • getPacket(timestamp) - Searches by presentation timestamp
VideoSampleSink and CanvasSink methods:
  • All methods use presentation order

Best practices

1

Choose the right abstraction

Use high-level sinks (CanvasSink, AudioBufferSink) unless you need sample-level control.
2

Close samples and frames

Always call close() on VideoSamples and AudioSamples to prevent memory leaks.
3

Use sparse sampling wisely

Use samplesAtTimestamps() instead of multiple getSample() calls for efficiency.
4

Enable canvas pooling

Use poolSize option in CanvasSink to reduce memory allocation overhead.
5

Break early when needed

Use break in for-await loops to exit early while ensuring proper cleanup.
6

Verify key packets when needed

Enable verifyKeyPackets if you encounter decoder errors with key frames.

Performance considerations

Memory management

  • Always close VideoSamples and AudioSamples
  • Use canvas pooling for CanvasSink
  • Use metadata-only packets when possible
  • Break out of iterations early if possible

Decoding efficiency

  • Use sparse sampling for non-sequential access
  • Prefer range iteration for sequential access
  • Use EncodedPacketSink to skip decoding entirely
  • Consider decoder queue sizes

See also