Choose the streams, encoding, and destination for one output.
Create outputs with FFix.output/3, new/3, or a FFix.Muxer helper. Pass
them to FFix.command/2 to assemble the invocation.
source = FFix.input("interview.mp4")
output =
FFix.output(
[FFix.video(source, 0), FFix.audio(source, 0)],
"excerpt.mp4",
t: 30
)The source list determines mapping order. Bare streams use FFmpeg's default
encoders; FFix.Encoder and FFix.stream_copy/1 choose encoding explicitly.
General output options, such as t, apply to this destination. See
FFix.Command.Mapping for encoding several tracks and FFix.Muxer for
container options.
Named mappings and callbacks
Some FFmpeg options refer to output-stream positions. Give mappings names and use an option callback to build those references from the final order. This is useful for an HLS master playlist with two video renditions sharing one audio rendition:
alias FFix.{Encoder, Filter, Muxer}
source = FFix.input("interview.mp4")
[high, low] = source |> FFix.video(0) |> Filter.fps(fps: 24) |> Filter.split(outputs: 2)
high = high |> Filter.scale(w: -2, h: 720) |> Encoder.libx264(b: "1800k", g: 48)
low = low |> Filter.scale(w: -2, h: 360) |> Encoder.libx264(b: "600k", g: 48)
sound = Encoder.aac(FFix.audio(source, 0), b: "128k")
output =
Muxer.hls([high: high, low: low, sound: sound], "hls/%v.m3u8",
hls_time: 4,
master_pl_name: "master.m3u8",
var_stream_map: fn streams ->
Enum.join([
"#{streams.high.specifier},agroup:audio,name:720p",
"#{streams.low.specifier},agroup:audio,name:360p",
"#{streams.sound.specifier},agroup:audio,name:audio,default:yes"
], " ")
end
)
FFix.command(output)Create the hls directory before executing. The callback receives:
%{
high: %{index: 0, specifier: "v:0"},
low: %{index: 1, specifier: "v:1"},
sound: %{index: 2, specifier: "a:0"}
}index counts every output stream. specifier counts within its media type.
Reordering the mappings updates these values automatically. Counts restart
for each output, and names must be unique atoms within that output. Unnamed
mappings count toward positions but have no entry in the callback map.
Callbacks are accepted as encoder, muxer, and general output option values.
Every mapping in that output must identify one required stream of known media
so the positions can be calculated. Use indexed media selections or filter
outputs rather than :all, optional selections, or raw queries.
Keep callbacks repeatable
Each option callback runs once per serialization. Inspecting a command and then executing it calls the callbacks twice. Keep them free of side effects.
Callback results undergo normal option-value checks. They must be values,
rather than another callback. Missing names raise KeyError; exceptions from
your callback propagate to the caller. Construction and FFix.validate!/1
check the layout while leaving callbacks unevaluated.
See the HLS muxer reference for playlist and rendition options.
Summary
Functions
Declares an output from a source or ordered source list, a target, and options.
Types
@type t() :: %FFix.Command.Output{ mappings: [FFix.Command.Mapping.t()], muxer: FFix.Muxer.t() | nil, options: [option()], target: target() }
@type target() :: String.t() | :stdout | {:pipe, non_neg_integer()} | {:url, String.t()}
Functions
@spec new(FFix.Command.binding() | [FFix.Command.binding()], target(), [option()]) :: t()
Declares an output from a source or ordered source list, a target, and options.
FFix.Command.Output.new([main: video, sound: audio], "interview.mp4", t: 30)Sources may be stream references, selections, or configured mappings. For
explicit low-level commands, graph export handles are also accepted; see
FFix.Command.new/1.
Targets can be path/URL strings, {:url, url}, :stdout, or {:pipe, descriptor}.
The muxer: option accepts a FFix.Muxer configuration. Remaining options are
general FFmpeg output controls; see FFix.Command for option syntax.