Skip to content

Read & write metadata and chapters

afmpeg reads and writes container-level tags, per-stream language/disposition/tags, and chapters (spec 0020). Writing tags and chapters works in any profile; it rides the mux, so it pairs naturally with a stream copy.

Read what's there

Probe surfaces the container tags, its chapters, and per-stream metadata:

p, err := rt.Probe(ctx, fs, "in.mkv")
// p.Tags["title"], p.Tags["artist"]        — container tags
// p.Chapters[i].Start / .End / .Title      — chapters (seconds + title)
for _, s := range p.Streams {
    // s.Language, s.Disposition (["default"], ["forced"], …), s.Tags
}

Write container tags

Set Output.Metadata — a copy is enough, no re-encode needed:

cmd := afmpeg.Command{
    Inputs: []afmpeg.Input{{Path: "in.mp4"}},
    Outputs: []afmpeg.Output{{
        Path:       "out.mp4",
        Map:        []string{"0:v", "0:a"},
        VideoCodec: afmpeg.CodecCopy,
        AudioCodec: afmpeg.CodecCopy,
        Metadata:   map[string]string{"title": "My Film", "artist": "Me"},
    }},
}
res, err := rt.RunJob(ctx, fs, cmd)

Set per-stream language, disposition, and tags

Output.StreamMetadata is keyed by the stream's Map entry (a graph pad like "[vout]" or a copied input stream like "0:a"):

Outputs: []afmpeg.Output{{
    Path:       "out.mkv",
    Map:        []string{"0:v", "0:a"},
    VideoCodec: afmpeg.CodecCopy,
    AudioCodec: afmpeg.CodecCopy,
    StreamMetadata: map[string]afmpeg.StreamMeta{
        "0:a": {
            Language:    "eng",
            Disposition: []string{"default"},
            Tags:        map[string]string{"title": "Commentary"},
        },
    },
}},

Carry chapters across

Output.Chapters is a passthrough directive — "copy" carries the first input's chapters onto the output, an input index ("1") picks another input, and "" / "none" drops them. Authoring chapters inline is not supported.

Outputs: []afmpeg.Output{{
    Path:       "out.mp4",
    Map:        []string{"0:v", "0:a"},
    VideoCodec: afmpeg.CodecCopy,
    AudioCodec: afmpeg.CodecCopy,
    Chapters:   "copy",
}},

See also