duckmedia

May 3, 2026 · View on GitHub

A DuckDB native extension for media file analysis. Exposes FFmpeg's demux metadata as SQL table functions with proper DuckDB types.

Table Functions

FunctionDescription
dm_format(path)Container-level metadata (format, duration, bitrate)
dm_streams(path)Per-stream metadata with DuckDB ENUMs for color/codec fields
dm_packets(path)All demuxed packets in mux order (filter by stream_index in SQL)

Quick Start

LOAD 'duckmedia.duckdb_extension';

-- Container info
SELECT * FROM dm_format('/path/to/video.mp4');

-- Stream metadata (video + audio)
SELECT * FROM dm_streams('/path/to/video.mp4');

-- Packets for video stream only
SELECT * FROM dm_packets('/path/to/video.mp4')
WHERE stream_index = 0;

-- Keyframes (flags bit 0)
SELECT * FROM dm_packets('/path/to/video.mp4')
WHERE stream_index = 0 AND (flags & 1) = 1;

Building

Requires Nix with flakes enabled.

nix develop                             # enter devshell (Rust + FFmpeg + DuckDB)
cargo duckdb-ext build -- --release     # build extension with metadata footer

Test:

duckdb -unsigned -c "
  SET allow_extensions_metadata_mismatch=true;
  LOAD 'target/release/duckmedia.duckdb_extension';
  SELECT * FROM dm_format('/path/to/video.mp4');
"

Reproducible build:

nix build
# Output: result/lib/duckmedia.duckdb_extension

Design

  • Strict 1:1 FFmpeg mapping — no computed columns; derivations (e.g. duration_seconds, is_keyframe) belong in SQL
  • No intermediate Rust structs — FFmpeg fields written directly to DuckDB chunks
  • Proper DuckDB ENUMscodec_type, color_range, color_space, color_primaries, color_transfer, chroma_location, field_order
  • Lazy packet iteration — reads via av_read_frame one batch at a time

Dependencies

  • Rust (stable)
  • FFmpeg 7 (pinned; ffmpeg-sys-next incompatible with FFmpeg 8+)
  • DuckDB (for testing)
  • quack-rs v0.12 (Rust DuckDB extension SDK)