FFmpeg encoder
The %ffmpeg encoder supports all options for
ffmpeg’s muxers and encoders, including
private options. Options are passed as key/value pairs, with values of
type string, int, or float.
Unrecognized or unused options raise an error at encoder instantiation.
Here are some examples:
Interleaved muxing
FFmpeg provides two muxing APIs: interleaved and non-interleaved. The interleaved API buffers packets to ensure audio and video streams stay in sync, preventing output that starts with a long audio chunk before any video. This comes at the cost of higher memory usage.
The non-interleaved API sends encoded packets directly to output without buffering, which can reduce latency and memory usage.
The %ffmpeg encoder supports both. It defaults to the
interleaved API when encoding more than one stream. Set the mode
explicitly with
%ffmpeg(interleaved=<true|false|"default">, ...).
Note that some video encoders buffer frames before producing output,
which can cause issues even with interleaving enabled (the interleave
buffer has a maximum size). With libx264, set
tune = "zerolatency" to ensure the encoder starts producing
data immediately.
Encoding examples
- AAC at
22050Hzusing thefdk-aacencoder andmpegtsmuxer
%ffmpeg(format="mpegts",
%audio(
codec="libfdk_aac",
samplerate=22050,
b="32k",
afterburner=1,
profile="aac_he_v2"
)
)- MP3 encoding using
libshineat48000Hz
%ffmpeg(format="mp3", %audio(codec="libshine", samplerate=48000))- AC3 audio and H264 video encapsulated in an MPEG-TS stream
%ffmpeg(
format="mpegts",
%audio(codec="ac3", channel_coupling=0),
%video(
codec="libx264",
b="2600k",
"x264-params"="scenecut=0:open_gop=0:min-keyint=150:keyint=150",
preset="ultrafast"
)
)- AC3 audio and H264 video encapsulated in an MPEG-TS stream using ffmpeg raw frames
%ffmpeg(
format="mpegts",
%audio.raw(codec="ac3", channel_coupling=0),
%video.raw(
codec="libx264",
b="2600k",
"x264-params"="scenecut=0:open_gop=0:min-keyint=150:keyint=150",
preset="ultrafast"
)
)- MP3 encoding using
libmp3lameand video copy
%ffmpeg(
format="mp3",
%audio(codec="libmp3lame"),
%video.copy
)The full syntax is as follows:
%ffmpeg(
format=<format>,
# Metadata to be passed when initializing the output
metadata=[("label","value"), ...],
# Audio section
%audio(codec=<codec>, <option_name>=<option_value>, ...),
# Or:
%audio.raw(codec=<codec>, <option_name>=<option_value>, ...),
# Or:
%audio.copy(<option>),
# Video section
%video(codec=<codec>, <option_name>=<option_value>, ...),
# Or:
%video.raw(codec=<codec>, <option_name>=<option_value>, ...),
# Or:
%video.copy(<option>),
# Generic options
<option_name>=<option_value>, ...
)Where:
<format>is a string value (e.g."mpegts") as returned byffmpeg -formats, ornone. Whennoneor omitted, the encoder auto-detects the format.<codec>is a string value (e.g."libmp3lame"), as returned by theffmpeg -codecscommand.<option_name>is any syntactically valid variable name or string. Strings are used for option names of the formfoo-bar.%audio(...)sets options for the audio codec. Unused options raise an exception. Any option supported byffmpegmay be passed. Streams encoded with%audiouse liquidsoap’s internal frame format.%audio.raw(...)behaves like%audiobut keeps audio data in ffmpeg’s internal format. This avoids data copies and is required for ffmpeg filters.%audio.copypasses data through without decoding or re-encoding. This avoids CPU usage but the data cannot be processed by operators likefade.{in,out}orsmart_cross. All streams must share the same data format.%video(...)sets options for the video codec. Unused options raise an exception. Any option supported byffmpegmay be passed.%video.rawand%video.copybehave like their%audiocounterparts.- Generic options are passed to audio, video, and format (container) setup. Unused options raise an exception.
HLS output
The %ffmpeg encoder is the primary encoder for HLS
output, as it is the only encoder that produces MPEG-TS muxed data,
which most HLS clients require.
File output
Some formats, such as mp4, require rewinding the stream
to write a header after encoding finishes. For historical reasons, such
formats cannot be used with output.file. The
output.url operator addresses this — the encoder controls
the output file and can write headers at the end. The
%ffmpeg encoder supports output.url.
Copy options
The %audio.copy and %video.copy encoders
have two mutually exclusive options to handle keyframes:
%audio.copy(wait_for_keyframe)and%video.copy(wait_for_keyframe): Wait until at least one keyframe has been passed to start passing encoded packets from a new stream.%audio.copy(ignore_keyframe)and%video.copy(ignore_keyframe): Ignore all keyframes.
These options are useful when switching between encoded streams.
With wait_for_keyframe, the encoder discards packets at
the start of a new stream until a keyframe is received. Playback pauses
until it can resume cleanly without decoding glitches. This option is
applied globally when possible: if a video track has keyframes but an
audio track does not, the audio track discards packets until a video
keyframe is received. This is the default.
With ignore_keyframe, encoded data is passed through
immediately. Content starts right away but playback may stall until a
keyframe is received.
Note that some audio encoders also produce keyframes.
Hardware acceleration
The %ffmpeg encoder supports multiple hardware
acceleration backends provided by ffmpeg.
If the encoder supports hardware acceleration without extra
configuration, selecting the codec (for example
codec="h264_videotoolbox" on macOS) may be all that is
needed.
FFmpeg provides three types of hardware acceleration:
- Internal hardware acceleration requiring no specific configuration.
- Device-based hardware acceleration using a specific device.
- Frame-based hardware acceleration using a specific pixel format.
The type of hardware acceleration to use for a given stream can be
specified using the hwaccel option. Its value is one of:
"auto", "none", "internal",
"device" or "frame".
For device-based acceleration, specify the device with
hwaccel_device. For frame-based acceleration, specify the
pixel format with hwaccel_pixel_format. In most cases,
liquidsoap can infer these from the codec.
Here’s an example:
enc = %ffmpeg(
format="mpegts",
%video(
hwaccel="device",
hwaccel_device="/dev/...",
...
)
)Hardware acceleration support is highly hardware-dependent and not all combinations have been tested. If you encounter issues, feel free to reach out to check whether your use case is supported.