Package for streaming (MPEG-TS, HLS, fragmented MP4)¶
The intermediate-profile engine (spec 0015)
writes the web-delivery containers — MPEG-TS, HLS, DASH, fragmented MP4 — all to the mounted
afero.Fs, with no network: segment files and playlists are written as files for you to
serve however you like.
Two knobs drive it: OutputFormat forces a muxer the path extension wouldn't imply, and
FormatOption passes options to that muxer (as opposed to WithOption, which configures the
encoder).
Remux to MPEG-TS, no re-encode¶
Container conversion to TS is a stream copy — the engine
auto-inserts the h264_mp4toannexb bitstream filter TS needs:
cmd := afmpeg.Command{
Inputs: []afmpeg.Input{{Path: "in.mp4"}},
Outputs: []afmpeg.Output{{
Path: "out.ts", Map: []string{"0:v", "0:a"},
VideoCodec: afmpeg.CodecCopy, AudioCodec: afmpeg.CodecCopy,
}},
}
Because TS segments carry continuous timestamps, they also concat-copy cleanly — the full
audio+video join that mp4's audio priming makes impossible: WithConcatInput("a.ts", "b.ts")
with copy codecs.
HLS: one output, a set of files¶
An HLS output is a single outputs[] entry whose path is the playlist; the muxer writes the
segment files itself:
cmd := afmpeg.NewCommand(
afmpeg.WithInput("in.mp4"),
afmpeg.WithFilterComplex("[0:v]null[v]"),
afmpeg.WithOutput("stream.m3u8", afmpeg.Map("[v]"),
afmpeg.OutputFormat("hls"), afmpeg.VideoCodec("libopenh264"),
afmpeg.FormatOption("hls_time", "4"),
afmpeg.FormatOption("hls_segment_filename", "seg_%03d.ts"),
afmpeg.FormatOption("hls_list_size", "0")),
)
_, _ = rt.RunJob(ctx, fs, cmd)
// fs now holds stream.m3u8 + seg_000.ts, seg_001.ts, …
The result entry for a segmenting output carries segmented: true; the segments are discoverable
on the fs by the pattern you gave. DASH is the same shape with OutputFormat("dash") and a
.mpd manifest.
Fragmented MP4 / CMAF¶
The mp4 muxer fragments via movflags — passed as a format option, not an encoder one:
afmpeg.WithOutput("frag.mp4", afmpeg.Map("[v]"), afmpeg.VideoCodec("libopenh264"),
afmpeg.FormatOption("movflags", "+frag_keyframe+empty_moov+default_base_moof"))
Which build has these?¶
The container batch lands in the intermediate profile (ffmpeg-wasi-intermediate-<variant>.wasm),
not the minimal lean build — see profiles.
Point WithModuleFile/WithModuleRelease at an intermediate module to use them.