Skip to content

Command, Input, Output and FrameJob fields

The declarative job types and every field on them. A Command is plain data: fill the struct directly, or build it with NewCommand and the functional options — both produce the same value, and JobSpec() renders either to the JSON the ffmpeg-wasi engine consumes.

Task-shaped versions of this material live in the how-to guides; this page is the field list.

Command

type Command struct {
    Inputs        []Input
    FilterComplex string
    Outputs       []Output
}
Field Builder option Default Meaning
Inputs WithInput, WithConcatInput empty Inputs in order. Index 0 is the first, and that index is what a map specifier like 0:v refers to.
FilterComplex WithFilterComplex empty The whole filter_complex graph as one string, parsed by libav's avfilter_graph_parse2. Omit it to mux or copy without a graph.
Outputs WithOutput empty Outputs in order.

JobSpec() is pure — no I/O — so it is safe to render and log a job before running it. RunJob(ctx, fs, cmd) is Run with the rendered spec.

Input

type Input struct {
    Path    string
    Concat  []string
    Seek    *Seek
    Format  string
    Options map[string]string
}
Field Builder option Default Meaning
Path WithInput(path) The input path, resolved against the afero.Fs you pass to Run.
Concat WithConcatInput(paths...) nil Like-codec files joined into one continuous input through the concat demuxer (a packet-level join, no re-encode). When set, Path is ignored. Distinct from the concat filter, which decodes and re-encodes.
Seek SeekTo(sec), SeekAccurateTo(sec) nil Start the input at a point instead of decoding from the beginning.
Format InputFormat(name) auto-probe Force the demuxer by name (rawvideo, s16le, mp4, …). Required for headerless input, and for a file whose extension would mislead the probe.
Options DemuxerOption(k, v) nil Demuxer options as an AVDictionary. Raw geometry rides here: video_size, pixel_format, framerate for rawvideo; sample_rate, ch_layout for PCM.

An option key the demuxer does not consume is an error from the engine, not a silent no-op — a misspelled pixel_fmt fails the job rather than producing wrong output.

Seek

type Seek struct {
    Start float64 // seconds
    Mode  string  // SeekFast (default when empty) or SeekAccurate
}
Mode Constant What it does Cost
fast SeekFast — the default when Mode is empty Demuxer jumps to the keyframe at or before Start; earlier packets are never read. cheap
accurate SeekAccurate Fast seek, then decode and discard up to the exact frame. a fraction of a GOP of decoding

SeekAccurate cannot feed a copied stream. A stream copy can only cut on keyframes, so Command.JobSpec() rejects the combination before the engine sees it:

afmpeg: output "out.mp4" maps copied stream "0:v" from an accurate-seek input
(copy cuts on keyframes; use SeekFast)

Output

type Output struct {
    Path             string
    Map              []string
    VideoCodec       string
    AudioCodec       string
    SubtitleCodec    string
    Options          map[string]string
    BitstreamFilters map[string]string
    Duration         float64
    End              float64
    CopyTS           bool
    Format           string
    FormatOptions    map[string]string
    Metadata         map[string]string
    Chapters         string
    StreamMetadata   map[string]StreamMeta
}
Field Builder option Default Meaning
Path WithOutput(path) Output path in the afero.Fs. The muxer is guessed from its extension unless Format says otherwise.
Map Map(label), repeated nil What to mux: graph output pads in brackets ([vout]) and/or input streams as in:type[:idx] specifiers (0:v, 0:a:0, 0:s).
VideoCodec VideoCodec(name) engine default for the container The video encoder (libopenh264, libx264, …) or CodecCopy to remux.
AudioCodec AudioCodec(name) engine default for the container The audio encoder (aac, libopus, …) or CodecCopy.
SubtitleCodec — (set the field) none Encoder for a subtitle stream mapped as N:s (srt, webvtt, mov_text), or CodecCopy. Works alone (a sidecar .srt) or alongside video and audio (an embedded track).
Options WithOption(k, v) nil Encoder options — crf, preset, b:v, frames:v, … Nothing is filtered out.
BitstreamFilters BitstreamFilter(mapKey, name) auto Override the bitstream filter for one copied stream, keyed by its Map entry. "none" force-disables. Absent, the muxer inserts whatever the container requires.
Duration Duration(sec) 0 (to the end) Stop after this many seconds (ffmpeg's -t).
End End(sec) 0 (to the end) Stop at this position (ffmpeg's -to).
CopyTS CopyTS() false Keep source timestamps instead of zero-basing the output. Under CopyTS, End is an absolute source position.
Format OutputFormat(name) from the path extension Force the muxer (hls, dash, segment, mpegts, …).
FormatOptions FormatOption(k, v) nil Muxer options passed to write_headerhls_time, hls_segment_filename, movflags, … Distinct from Options, which reach the encoder.
Metadata — (set the field) nil Container-level tags on the output (title, artist, …).
Chapters — (set the field) drop chapters "copy" carries the first input's chapters across; an input index ("1") picks another; "" or "none" drops them. Authoring chapters inline is not supported.
StreamMetadata — (set the field) nil Per-stream language, disposition flags and tags, keyed by the Map entry the stream comes from.

Fields with no builder option are set on the struct. Both forms are first-class — the builder covers the common ones, the struct covers all of them.

StreamMeta

type StreamMeta struct {
    Language    string            // e.g. "eng"
    Disposition []string          // e.g. {"default", "forced"}
    Tags        map[string]string // arbitrary per-stream tags
}

Applied to the output stream before the header is written.

CodecCopy

afmpeg.CodecCopy is the string "copy". Set it on VideoCodec, AudioCodec or SubtitleCodec and name the source stream in Map — the packets pass through untouched, with no decode and no encode.

What Command.JobSpec() rejects

Validation happens in Go, before the engine is invoked. Three things fail here:

Condition Error
Duration or End negative output "…": Duration and End must be non-negative
both Duration and End set output "…": Duration and End are mutually exclusive
a copied Map entry whose input has SeekAccurate output "…" maps copied stream "…" from an accurate-seek input

Everything else — an unknown codec, a map entry naming a stream that does not exist, a filtergraph that will not parse — is the engine's to reject, and comes back as a non-zero Result.ExitCode with the detail in Result.Stderr.

FrameJob

The frames op: pull still images out of one video input, without hand-tuning an fps/select graph into the image2 muxer.

type FrameJob struct {
    Input   string
    Format  string
    Options map[string]string
    Select  FrameSelect
    Path    string
    Codec   string
    Scale   string
    Count   int
}
Field Default Meaning
Input The video path.
Format / Options auto-probe Force and parameterise the demuxer, exactly as on Input.
Select Which frames. Exactly one selector, see below.
Path Required. Output template with an optional integer token, e.g. out/frame_%03d.png. A template with no token is valid only for a single frame.
Codec png Image encoder — png, mjpeg, webp, …
Scale none ffmpeg scale arguments applied to each frame, e.g. 320:-2.
Count 0 (engine default) Caps how many frames are emitted.

An empty Path fails before the engine is reached: afmpeg: FrameJob.Path (output template) is required.

FrameSelect — exactly one

type FrameSelect struct {
    Timestamp      *float64
    Timestamps     []float64
    Interval       float64
    SceneThreshold *float64
    Thumbnail      bool
}
Selector Picks
Timestamp the single frame at that second (a pointer, so 0 means the first frame rather than "unset")
Timestamps one frame at each listed second
Interval a frame every N seconds across the input (N > 0)
SceneThreshold scene-change frames scoring above the threshold (select='gt(scene,T)')
Thumbnail representative frames via the thumbnail filter

Setting none or more than one fails in Go:

afmpeg: FrameSelect must set exactly one of
Timestamp/Timestamps/Interval/SceneThreshold/Thumbnail

See also