FFmpeg video/audio processing via Hot Box containers.

Provides functions for video transcoding, thumbnail extraction, audio extraction, and media probing using ffmpeg in isolated containers.

Each function runs ffmpeg inside a container with appropriate resource sizing. Input files are referenced by hot:// storage URLs and outputs are written back to hot:// storage.

Quick Start

// Probe a media file
info ::ffmpeg/probe("hot://uploads/video.mp4")
tap(info.format.duration)

// Extract a thumbnail
thumb ::ffmpeg/thumbnail("hot://uploads/video.mp4")
tap(thumb.url)

// Transcode to mp4
out ::ffmpeg/transcode("hot://uploads/video.mov", {format: "mp4", codec: "libx264"})
tap(out.url)

// Extract audio as mp3
audio ::ffmpeg/extract-audio("hot://uploads/video.mp4")
tap(audio.url)

// With explicit output path
thumb ::ffmpeg/thumbnail("hot://uploads/video.mp4", {
    output: "hot://media/video-thumb.jpg",
})

Container Requirements

Minimum Size medium

Values

DEFAULT_IMAGE

DEFAULT_IMAGE: Str "jrottenberg/ffmpeg:7-alpine"

Functions

build-extract-audio-args

fn (input-path: Str, output-path: Str, bitrate: Str, sample-rate: Int?, channels: Int?, extra-args: Vec?): Vec

Build ffmpeg CLI arguments for audio extraction.

build-extract-frames-args

fn (input-path: Str, output-pattern: Str, fps: Str, start: Str?, duration: Int?, width: Int?, height: Int?, quality: Int, extra-args: Vec?, keyframes-only: Bool?): Vec

Build ffmpeg CLI arguments for multi-frame image extraction.

build-probe-args

fn (input-path: Str): Vec

Build ffprobe CLI arguments for media probing.

build-thumbnail-args

fn (input-path: Str, output-path: Str, time: Str, width: Int?, height: Int?, quality: Int, extra-args: Vec?): Vec

Build ffmpeg CLI arguments for thumbnail extraction.

build-transcode-args

fn (input-path: Str, output-path: Str, opts: TranscodeOpts): Vec

Build ffmpeg CLI arguments for video transcoding.

check-box-result

fn (result: Map, tool-name: Str): Map

extract-audio

fn (input: Str): Map
fn (input: Str, opts: ExtractAudioOpts): Map

Extract the audio track from a video file.

Returns {url: Str, format: Str} with the output file URL in Hot storage.

Example

// Default: extract as MP3 at 192k
audio ::ffmpeg/extract-audio("hot://uploads/video.mp4")
audio.url     // "hot://ffmpeg/<uuid>/audio.mp3"

// Extract as FLAC
audio ::ffmpeg/extract-audio("hot://uploads/video.mp4", {format: "flac"})

// Extract mono WAV at 16kHz (good for speech processing)
audio ::ffmpeg/extract-audio("hot://uploads/video.mp4", {
    format: "wav",
    sample-rate: 16000,
    channels: 1
})
Container: small

extract-frames

fn (input: Str): Map
fn (input: Str, opts: ExtractFramesOpts): Map

Extract multiple image frames from a video.

Returns {frames: Vec<Map>, format: Str, output_prefix: Str}. Each frame has {url, index} where url is a hot:// URL.

Example

frames ::ffmpeg/extract-frames("hot://uploads/window.webm", {
    fps: "1/2",
    format: "jpg",
    output-prefix: "hot://hot-live/frames/window-1"
})
Container: medium

file-ext

fn (path: Str): Str

join-args

fn (args: Vec): Str

parse-probe-output

fn (stdout: Str?): Map

Parse ffprobe JSON output into a structured Map.

probe

fn (input: Str): Map
fn (input: Str, image: Str): Map

Get media file metadata using ffprobe.

Returns a Map containing format and streams information from ffprobe's JSON output: duration, size, bitrate, codecs, resolution, sample rates, etc.

Example

info ::ffmpeg/probe("hot://uploads/video.mp4")
info.format.duration     // "120.500000"
info.format.bit_rate     // "2500000"
info.streams             // [{codec_name: "h264", width: 1920, ...}, ...]
Container: small

resolve-output

fn (user-output: Str?, default: Str): Str

run-ffmpeg-box

fn (script: Str, box-size: Str, image: Str?, timeout: Int): Map

start-extract-audio

fn (input: Str): Map
fn (input: Str, opts: ExtractAudioOpts): Map

Start an audio extraction task without awaiting. Returns TaskInfo for use with ::hot::task/await.

Container: small

start-extract-frames

fn (input: Str): Map
fn (input: Str, opts: ExtractFramesOpts): Map

Start multi-frame image extraction without awaiting. Returns TaskInfo for use with ::hot::task/await.

Container: medium

start-ffmpeg-box

fn (script: Str, box-size: Str, image: Str?, timeout: Int): Map

start-probe

fn (input: Str): Map

Start a probe task without awaiting. Returns TaskInfo for use with ::hot::task/await.

Container: small

start-thumbnail

fn (input: Str): Map
fn (input: Str, opts: ThumbnailOpts): Map

Start a thumbnail extraction task without awaiting. Returns TaskInfo for use with ::hot::task/await.

Container: small

start-transcode

fn (input: Str, opts: TranscodeOpts): Map

Start a transcode task without awaiting. Returns TaskInfo for use with ::hot::task/await.

Container: medium

thumbnail

fn (input: Str): Map
fn (input: Str, opts: ThumbnailOpts): Map

Extract a thumbnail frame from a video file.

Returns {url: Str, format: Str} with the output file URL in Hot storage.

Example

// Default: first frame at 1 second, JPEG
thumb ::ffmpeg/thumbnail("hot://uploads/video.mp4")
thumb.url     // "hot://ffmpeg/<uuid>/thumbnail.jpg"

// With options
thumb ::ffmpeg/thumbnail("hot://uploads/video.mp4", {
    time: "00:00:10",
    width: 320,
    format: "png"
})
Container: small

transcode

fn (input: Str, opts: TranscodeOpts): Map

Transcode a video file to a different format or encoding.

Returns {url: Str, format: Str} with the output file URL in Hot storage.

Example

// Convert MOV to MP4 with H.264
out ::ffmpeg/transcode("hot://uploads/video.mov", {
    format: "mp4",
    codec: "libx264",
    crf: 23
})
out.url     // "hot://ffmpeg/<uuid>/output.mp4"

// Convert to WebM with VP9
out ::ffmpeg/transcode("hot://uploads/video.mp4", {
    format: "webm",
    codec: "libvpx-vp9",
    audio-codec: "libopus",
    bitrate: "2M"
})
Container: medium

version

fn (): Map
fn (image: Str?): Map

Return ffmpeg version information.

Example

ver ::ffmpeg/version()
ver.version
Container: small

Types

ExtractAudioOpts

ExtractAudioOpts type {
    format: Str?,
    bitrate: Str?,
    sample-rate: Int?,
    channels: Int?,
    output: Str?,
    extra-args: Vec?,
    image: Str?,
    size: Str?,
    timeout: Int?
}

Options for audio extraction.

Fields

  • format — Output format: "mp3", "aac", "flac", "wav", "opus" (default: "mp3")
  • bitrate — Bitrate, e.g. "192k", "320k" (default: "192k")
  • sample-rate — Sample rate in Hz, e.g. 44100, 48000
  • channels — Number of channels: 1 for mono, 2 for stereo
  • output — Output hot:// URL (default: auto-generated)
  • extra-args — Additional ffmpeg arguments
  • image — Custom Docker image with ffmpeg
  • size — Box size override (default: "small")
  • timeout — Execution timeout in seconds (default: 300)

ExtractFramesOpts

ExtractFramesOpts type {
    fps: Str?,
    start: Str?,
    duration: Int?,
    width: Int?,
    height: Int?,
    format: Str?,
    quality: Int?,
    output-prefix: Str?,
    extra-args: Vec?,
    keyframes-only: Bool?,
    image: Str?,
    size: Str?,
    timeout: Int?
}

Options for extracting multiple image frames from a video.

Fields

  • fps — Frame extraction rate, e.g. "1/2" for one frame every two seconds (default: "1/2")
  • start — Optional start position, e.g. "00:00:05" or "8.5". Applied as a trim filter (accurate on index-less streaming inputs), so the whole input up to this point is still decoded.
  • duration — Optional extraction duration in seconds
  • width — Output width in pixels (default: source width)
  • height — Output height in pixels (default: source height)
  • format — Output format: "jpg", "png", "webp" (default: "jpg")
  • quality — Quality 1-31, lower is better (default: 2)
  • output-prefix — Output hot:// directory/prefix (default: auto-generated)
  • extra-args — Additional ffmpeg arguments appended before the output pattern
  • keyframes-only — When true, pass -skip_frame nokey before input so only decodable keyframes are extracted (default: false)
  • image — Custom Docker image with ffmpeg
  • size — Box size override (default: "medium")
  • timeout — Execution timeout in seconds (default: 300)

ThumbnailOpts

ThumbnailOpts type {
    time: Str?,
    width: Int?,
    height: Int?,
    format: Str?,
    quality: Int?,
    output: Str?,
    extra-args: Vec?,
    image: Str?,
    size: Str?,
    timeout: Int?
}

Options for thumbnail extraction.

Fields

  • time — Seek position, e.g. "00:00:05" (default: "00:00:01")
  • width — Output width in pixels (default: source width)
  • height — Output height in pixels (default: source height)
  • format — Output format: "jpg", "png", "webp" (default: "jpg")
  • quality — Quality 1–31, lower is better (default: 2)
  • output — Output hot:// URL (default: auto-generated)
  • extra-args — Additional ffmpeg arguments
  • image — Custom Docker image with ffmpeg (default: jrottenberg/ffmpeg:7-alpine)
  • size — Box size override (default: "small")
  • timeout — Execution timeout in seconds (default: 300)

TranscodeOpts

TranscodeOpts type {
    format: Str,
    codec: Str?,
    audio-codec: Str?,
    bitrate: Str?,
    audio-bitrate: Str?,
    resolution: Str?,
    preset: Str?,
    crf: Int?,
    output: Str?,
    extra-args: Vec?,
    image: Str?,
    size: Str?,
    timeout: Int?
}

Options for video transcoding.

Fields

  • format — Output format, e.g. "mp4", "webm", "mkv" (required)
  • codec — Video codec, e.g. "libx264", "libvpx-vp9" (default: auto)
  • audio-codec — Audio codec, e.g. "aac", "libopus" (default: auto)
  • bitrate — Video bitrate, e.g. "2M", "500k"
  • audio-bitrate — Audio bitrate, e.g. "128k", "192k"
  • resolution — Output resolution, e.g. "1280x720"
  • preset — Encoding preset, e.g. "fast", "medium", "slow"
  • crf — Constant Rate Factor 0–51 (default: 23 for x264)
  • output — Output hot:// URL (default: auto-generated)
  • extra-args — Additional ffmpeg arguments
  • image — Custom Docker image with ffmpeg
  • size — Box size override (default: "medium")
  • timeout — Execution timeout in seconds (default: 300)