Transcoding profiles¶
Profiles define what outputs Encore produces for a given job. They are YAML files that list one or more encode types (video, audio, thumbnails).
How profiles work¶
Profiles are loaded from a profile index file — a YAML file that maps profile names to their file paths:
Point Encore to the index file with the encore-settings.profile.location property:
Profile file paths are relative to the index file location.
Profile structure¶
A profile has the following top-level fields:
| Field | Default | Description |
|---|---|---|
name |
(none) | Profile name |
description |
(none) | Human-readable description |
scaling |
bicubic |
FFmpeg scaling algorithm |
deinterlaceFilter |
yadif |
FFmpeg deinterlace filter |
joinSegmentParams |
{} |
Additional FFmpeg parameters used when joining segments |
encodes |
(required) | List of encode outputs (see types below) |
Encode types¶
Each entry in encodes has a type field that determines what kind of output is produced.
VideoEncode¶
For any FFmpeg-supported video codec (e.g., DNxHD, ProRes). Requires explicit codec and format.
- type: VideoEncode
codec: dnxhd
height: 1080
suffix: _archive
format: mxf
twoPass: false
params:
b:v: 185M
pix_fmt: yuv422p10le
| Field | Default | Description |
|---|---|---|
codec |
(required) | FFmpeg video codec name |
suffix |
(required) | Output file suffix (e.g., _archive) |
format |
(required) | Output container format |
width |
(auto) | Target width in pixels |
height |
(auto) | Target height in pixels |
twoPass |
false |
Enable two-pass encoding |
params |
{} |
FFmpeg output parameters |
filters |
[] |
Additional FFmpeg video filters |
audioEncode |
(none) | Single audio encode to mux into the output |
audioEncodes |
[] |
Multiple audio encodes to mux into the output |
inputLabel |
main |
Which video input to use (see Multiple Inputs) |
optional |
false |
Skip instead of failing if input label not found |
enabled |
true |
Set to false to disable this encode |
cropTo |
(none) | Crop to aspect ratio before scaling (e.g., 1:1) |
padTo |
(none) | Pad to aspect ratio after scaling (e.g., 16:9) |
vmaf |
(none) | VMAF quality metrics configuration (see VMAF) |
Note
When both width and height are set, Encore scales while maintaining aspect ratio and rounding to divisible-by-2 dimensions. When only one is set, the other is calculated proportionally.
X264Encode¶
H.264 video encoding using libx264. Has all the fields from VideoEncode with codec fixed to libx264 and format defaulting to mp4, plus codec-specific parameters:
- type: X264Encode
suffix: _x264_720
height: 720
twoPass: true
params:
b:v: 2000k
maxrate: 3000k
bufsize: 4000k
pix_fmt: yuv420p
x264-params:
bframes: 6
ref: 4
me: hex
audioEncode:
type: AudioEncode
bitrate: 128k
| Field | Default | Description |
|---|---|---|
x264-params |
{} |
x264 codec-specific parameters |
format |
mp4 |
Output container format |
X265Encode¶
H.265/HEVC video encoding using libx265. Has all the fields from VideoEncode with codec fixed to libx265 and format defaulting to mp4, plus codec-specific parameters:
- type: X265Encode
suffix: _x265_1080
height: 1080
twoPass: true
params:
b:v: 3000k
pix_fmt: yuv420p
x265-params:
bframes: 6
ref: 4
| Field | Default | Description |
|---|---|---|
x265-params |
{} |
x265 codec-specific parameters |
format |
mp4 |
Output container format |
AudioEncode¶
Full-featured audio encoding with channel layout mixing and optional dialogue enhancement.
| Field | Default | Description |
|---|---|---|
codec |
aac |
FFmpeg audio codec |
bitrate |
(auto) | Output bitrate (e.g., 128k) |
samplerate |
48000 |
Sample rate in Hz |
channelLayout |
stereo |
Target channel layout |
suffix |
auto-generated | Output file suffix |
params |
{} |
Additional FFmpeg parameters |
filters |
[] |
Audio filters |
audioMixPreset |
default |
Audio mix preset name (see Configuration Reference) |
format |
mp4 |
Output container format |
inputLabel |
main |
Which audio input to use |
optional |
false |
Skip if no matching input |
enabled |
true |
Disable this encode |
dialogueEnhancement |
(disabled) | Dialogue enhancement settings (see below) |
Dialogue enhancement
Dialogue enhancement makes speech easier to follow — a common accessibility aid. Encore offers two variants, selected via the type field on dialogueEnhancement:
native(default) — uses only stock FFmpeg filters. Synthesises a centre channel from stereo viadialoguenhance; surround inputs with an existing centre channel are passed through to the sidechain step directly.dn— a neural model (DeepFilterNet 3) running inside FFmpeg via theaf_dnenhancefilter. Cleaner separation in difficult material, and improves surround content too because the existing centre channel is cleaned before the background is ducked.
Both variants end the same way: the dialogue (centre) channel is used as the sidechain to FFmpeg's sidechaincompress, so the background level dips while someone is speaking and returns when they stop.
Native
- type: AudioEncode
bitrate: 128k
suffix: _STEREO_DE
dialogueEnhancement:
type: native # optional — native is the default
enabled: true
sidechainCompress:
ratio: 8
threshold: 0.012
attack: 100
release: 1000
dialogueEnhanceStereo:
enabled: true
original: 1
enhance: 1
voice: 2
| Field | Default | Description |
|---|---|---|
enabled |
false |
Master switch for the variant |
sidechainCompress.ratio |
8 |
Compression ratio applied to the background bus |
sidechainCompress.threshold |
0.012 |
Centre level at which ducking engages |
sidechainCompress.attack |
100 |
Attack time, ms |
sidechainCompress.release |
1000 |
Release time, ms |
dialogueEnhanceStereo.enabled |
true |
Synthesise a centre channel from stereo L/R via dialoguenhance |
dialogueEnhanceStereo.original |
1 |
Centre factor to keep in front (0–1) |
dialogueEnhanceStereo.enhance |
1 |
Dialogue boost (0–3) |
dialogueEnhanceStereo.voice |
2 |
Voice-detection strength (2–32) |
The native variant works on stereo inputs (when dialogueEnhanceStereo.enabled is true) and any surround layout that already has a centre channel. For stereo, FFmpeg's dialoguenhance synthesises a centre channel and the effective post-enhancement layout becomes 3.0. For surround sources the existing centre channel is used directly — dialoguenhance is not invoked, and the effective layout is unchanged. Mono inputs and surround layouts without a centre channel are not supported — the encode is skipped when optional: true, otherwise it fails. After enhancement the audio mix preset (audioMixPreset) handles the final downmix from the post-enhancement layout to the encode's target channelLayout.
Neural (type: dn)
Requires a patched FFmpeg build
type: dn invokes the af_dnenhance FFmpeg filter, which is not part of upstream FFmpeg. The pre-built ghcr.io/svt/encore-* images do not include it, and profiles using type: dn against vanilla FFmpeg fail at encode time with No such filter: 'dnenhance'. The filter source — together with build instructions — lives at svt/ffmpeg-filter-dnenhance.
All filter parameters are optional — omitting them lets the filter pick its own defaults, which is the common case:
For full control:
- type: AudioEncode
bitrate: 128k
suffix: _STEREO_DE
dialogueEnhancement:
type: dn
enabled: true
model: /opt/homebrew/share/libdf/DeepFilterNet3.tar.gz
postFilter: true
attenuationLimit: 100.0
lookahead: 2
sidechainCompress:
ratio: 8
threshold: 0.012
| Field | Default | Description |
|---|---|---|
enabled |
false |
Master switch for the variant |
model |
(filter auto-discovers) | Path to a DeepFilterNet 3 model tarball |
postFilter |
(filter default) | Enable the DFN3 post-filter |
attenuationLimit |
(filter default) | Maximum suppression in dB — caps the model's gain reduction |
lookahead |
(filter default) | Algorithmic lookahead in 480-sample hops |
sidechainCompress.* |
(see Native) | Same fields and defaults as the native variant |
The neural variant works on mono, stereo, and any surround layout with a centre channel. Mono and stereo sources are bridged to a 3.0 layout (mono via equal-power duplication into a stereo background; stereo via a downmix into a synthesised centre) and dnenhance is applied to that centre. Surround sources with an existing centre channel use it directly and the effective layout is unchanged. Surround layouts without a centre channel are not supported — the encode is skipped when optional: true, otherwise it fails. After enhancement the audio mix preset (audioMixPreset) handles the final downmix from the post-enhancement layout to the encode's target channelLayout — the same downstream path the native variant uses, so a single mix preset can drive both.
SimpleAudioEncode¶
A simpler audio encode that preserves the input channel layout without mixing.
| Field | Default | Description |
|---|---|---|
codec |
aac |
FFmpeg audio codec |
bitrate |
(auto) | Output bitrate |
samplerate |
(unchanged) | Sample rate conversion |
suffix |
_<codec> |
Output file suffix |
params |
{} |
Additional FFmpeg parameters |
format |
mp4 |
Output container format |
inputLabel |
main |
Which audio input to use |
optional |
false |
Skip if no matching input |
enabled |
true |
Disable this encode |
ThumbnailEncode¶
Extract thumbnail images at specified times or intervals.
- type: ThumbnailEncode
percentages: [25, 50, 75]
thumbnailWidth: -2
thumbnailHeight: 1080
quality: 5
| Field | Default | Description |
|---|---|---|
percentages |
[25, 50, 75] |
Extract at these percentages of the duration |
intervalSeconds |
(none) | Extract at regular intervals instead of percentages |
thumbnailWidth |
-2 |
Width in pixels (-2 = proportional) |
thumbnailHeight |
1080 |
Height in pixels |
quality |
5 |
JPEG quality (1–31, lower = better) |
suffix |
_thumb |
Output file suffix |
suffixZeroPad |
2 |
Zero-padding for numbered thumbnails |
inputLabel |
main |
Which video input to use |
optional |
false |
Skip if not possible |
enabled |
true |
Disable this encode |
decodeOutput |
(none) | Use a decoded video output as input instead of the original (see Reusing an encoded output as thumbnail source) |
Note
The thumbnailTime field on the job overrides the profile's percentage/interval configuration.
ThumbnailMapEncode¶
Generate a sprite sheet (tile map) of thumbnails, useful for video scrubbing previews.
| Field | Default | Description |
|---|---|---|
tileWidth |
160 |
Width of each tile in pixels |
tileHeight |
90 |
Height of each tile in pixels |
cols |
12 |
Number of columns |
rows |
20 |
Number of rows |
quality |
5 |
JPEG quality (1–31, lower = better) |
suffix |
auto-generated | Output file suffix |
format |
jpg |
Output format |
inputLabel |
main |
Which video input to use |
optional |
true |
Skip if not possible |
enabled |
true |
Disable this encode |
decodeOutput |
(none) | Use a decoded video output as input (see Reusing an encoded output as thumbnail source) |
Reusing an encoded output as thumbnail source¶
Both ThumbnailEncode and ThumbnailMapEncode accept a decodeOutput field. Its value is the zero-based index of an earlier entry in the profile's encodes list — the thumbnail is then generated by decoding that entry's output (via FFmpeg's loopback decoder) instead of re-decoding the original source.
For example, with decodeOutput: 0 and the complete profile below, thumbnails are generated from the decoded frames of the first X264Encode:
encodes:
- type: X264Encode # index 0 — produces the video we'll decode from
suffix: _x264_1080
height: 1080
# …
- type: ThumbnailEncode
decodeOutput: 0 # reuse the decoded frames of the X264 output
This is primarily a workaround for thumbnail issues observed with FFmpeg 7+, and has the useful side effect of only decoding the source once when both a video encode and thumbnails are produced.
SpEL expressions¶
Profiles support Spring Expression Language (SpEL) for dynamic parameterisation. Expressions are delimited by #{ and } by default.
The job's profileParams map is available as context. This allows a single profile to handle variations — different frame rates, bitrate tiers, feature flags — without duplicating the profile file.
A common pattern is to branch on a parameter with a safe default using ?: (Elvis operator) and a ternary ? ::
name: program
encodes:
- type: X264Encode
suffix: "#{(profileParams['fps'] ?: 25) > 30 ? '_x264_3800' : '_x264_3100'}"
height: 1080
twoPass: true
params:
b:v: "#{(profileParams['fps'] ?: 25) > 30 ? '3800k' : '3100k'}"
r: "#{profileParams['fps'] ?: 25}"
fps_mode: cfr
profileParams['fps'] ?: 25 reads the fps param from the job, falling back to 25 if it is absent. The > 30 check selects higher bitrates for 50/60 fps content. A job submitting 50 fps content would include:
{
"profile": "program",
"profileParams": { "fps": 50 },
"outputFolder": "/output",
"baseName": "clip",
"inputs": [{ "type": "AudioVideo", "uri": "/input/source.mp4" }]
}
Multiple inputs¶
Jobs can have multiple inputs with different labels. Encode types reference inputs by their inputLabel field.
Job with multiple inputs:
{
"profile": "composite",
"outputFolder": "/output",
"baseName": "composite_output",
"inputs": [
{
"type": "AudioVideo",
"uri": "/input/main_video.mp4",
"videoLabel": "main",
"audioLabel": "main"
},
{
"type": "Audio",
"uri": "/input/alt_audio.wav",
"audioLabel": "alt"
}
]
}
Profile referencing multiple inputs:
encodes:
- type: AudioEncode
bitrate: 128k
suffix: _STEREO
inputLabel: main
- type: AudioEncode
bitrate: 128k
suffix: _STEREO_ALT
inputLabel: alt
VMAF quality metrics¶
Limitations
VMAF is not supported in segmented encoding mode. Scores will not be meaningful if the encode changes the frame rate of the source — use the same frame rate as the input.
Performance
Calculating VMAF runs libvmaf alongside the encode and adds CPU work to every encoded frame. Depending on hardware, this can noticeably slow the overall transcode.
Memory use on fast encodes
libvmaf runs in the same FFmpeg process as the encode and queues frames for scoring with no upper bound. When the encoder produces frames faster than VMAF can score them, the backlog grows for the whole job and can exhaust memory (OOM) on long inputs. The risk grows with input duration, source resolution (VMAF runs at the source resolution, not the output resolution), and the number of VMAF-enabled outputs in the profile.
Raise subsample so VMAF scores fewer frames and keeps pace with the encoder. Lowering threads makes it worse (VMAF drains more slowly) — subsample is the lever. Slow, encoder-bound profiles are naturally safe: the encode paces the job and VMAF keeps up on its own.
Rule of thumb, keyed on the job's reported encode speed relative to realtime (the whole-profile speed Encore records). Starting points for a 1080p source with threads: 4 and the default model — use a lower threshold for higher-resolution sources, profiles with many VMAF-enabled outputs, or single-pass profiles (where VMAF runs across the whole encode rather than only the second pass):
| Reported encode speed | subsample |
|---|---|
| up to ~1× realtime | not needed |
| ~1–2× realtime | 3 |
| faster than ~2× realtime | 5 |
When in doubt, watch process memory over a long job: flat is fine; steadily climbing means the queue is growing — raise subsample, or disable VMAF for that profile.
Video encodes can optionally calculate VMAF quality scores by comparing the encoded output against the source.
- type: X264Encode
suffix: _x264_720
height: 720
params:
b:v: 2000k
vmaf:
enabled: true
model: version=vmaf_4k_v0.6.1\\:name=vmaf4k|version=vmaf_v0.6.1\\:name=vmaf
feature: name=psnr
threads: 4
The model field accepts a pipe-separated list of VMAF models in FFmpeg's version=...\:name=... format. When multiple models are specified, scores are reported under each model's name (the name= you assign becomes the key under qualityMetrics in the job result). The feature field adds extra metrics — name=psnr enables PSNR scores alongside VMAF.
Why the \\: escaping?
Inside FFmpeg's libvmaf filter, : separates one model's options (e.g. version=...:name=...), and | separates multiple models. The value is passed through FFmpeg's filter-argument parser, which strips one layer of escaping — so a literal : inside a model definition must be written as \\: in the profile. Don't escape the | between models.
| Field | Default | Description |
|---|---|---|
enabled |
false |
Enable VMAF calculation |
model |
(FFmpeg default) | VMAF model(s) in FFmpeg version=...\:name=... format, pipe-separated |
threads |
(auto) | Number of threads for VMAF calculation |
subsample |
(none) | Score every Nth frame (higher = faster, less accurate; bounds memory on fast encodes — see warning above) |
feature |
(none) | Additional feature metrics (e.g. name=psnr) |
refFilters |
[] |
Filters to apply to the reference stream before comparison |
When enabled, VMAF scores are included in the job's qualityMetrics field after encoding completes, keyed by output filename and then by metric name (e.g. vmaf, vmaf4k, psnr_y). The full VMAF log is also saved alongside each output file with .vmaf.json appended to the filename (e.g. my_video_720p.mp4.vmaf.json).
By default, only the vmaf metric is included in the results. Use encore-settings.encoding.include-quality-metrics to control which metrics are stored (see Configuration Reference):
Complete example¶
SVT's production profile for long-form programmes — a five-rung x264 ABR ladder, stereo and surround audio variants with optional dialogue enhancement, and thumbnails. Each video rung enables VMAF with subsample: 5, since a fast x264 ladder on long inputs is exactly the case where unbounded VMAF scoring can exhaust memory (see the warning above):
name: program
description: Program profile
scaling: bicubic
encodes:
- type: X264Encode
suffix: #{(profileParams['fps'] ?: 25) > 30 ? "_x264_3800" : "_x264_3100"}
twoPass: true
width: 1920
height: 1080
vmaf:
enabled: true
threads: 4
subsample: 5
params:
b:v: #{(profileParams['fps'] ?: 25) > 30 ? "3800k" : "3100k"}
maxrate: #{(profileParams['fps'] ?: 25) > 30 ? "5700k" : "4700k"}
bufsize: #{(profileParams['fps'] ?: 25) > 30 ? "9000k" : "7600k"}
r: #{profileParams['fps'] ?: 25}
fps_mode: cfr
pix_fmt: yuv420p
force_key_frames: "expr:not(mod(n,#{profileParams['gop'] ?: 96}))"
profile:v: high
level: #{(profileParams['fps'] ?: 25) > 30 ? "4.2" : "4.1"}
x264-params:
deblock: 0,0
aq-mode: 1
aq-strength: 1.0
b-adapt: 2
bframes: 6
b-bias: 0
b-pyramid: 2
chroma-qp-offset: -2
direct: auto
rc-lookahead: #{(profileParams['fps'] ?: 25) > 30 ? 80 : 60}
keyint: #{(profileParams['gop'] ?: 96) * 2}
keyint_min: #{profileParams['gop'] ?: 96}
me: umh
merange: 24
cabac: 1
partitions: all
ref: 4
scenecut: 40
subme: 9
trellis: 2
weightp: 2
audioEncode:
type: AudioEncode
codec: libfdk_aac
bitrate: 192k
- type: X264Encode
suffix: #{(profileParams['fps'] ?: 25) > 30 ? "_x264_2550" : "_x264_2069"}
twoPass: true
width: 1280
height: 720
vmaf:
enabled: true
threads: 4
subsample: 5
params:
b:v: #{(profileParams['fps'] ?: 25) > 30 ? "2550k" : "2069k"}
maxrate: #{(profileParams['fps'] ?: 25) > 30 ? "3825k" : "3104k"}
bufsize: #{(profileParams['fps'] ?: 25) > 30 ? "5100k" : "4138k"}
r: #{profileParams['fps'] ?: 25}
fps_mode: cfr
pix_fmt: yuv420p
force_key_frames: "expr:not(mod(n,#{profileParams['gop'] ?: 96}))"
profile:v: main
level: #{(profileParams['fps'] ?: 25) > 30 ? "3.2" : "3.1"}
x264-params:
deblock: 0,0
aq-mode: 1
aq-strength: 1.0
b-adapt: 2
bframes: 6
b-bias: 0
b-pyramid: 2
chroma-qp-offset: -2
direct: auto
rc-lookahead: #{(profileParams['fps'] ?: 25) > 30 ? 80 : 60}
keyint: #{(profileParams['gop'] ?: 96) * 2}
keyint_min: #{profileParams['gop'] ?: 96}
me: hex
merange: 16
cabac: 1
partitions: all
ref: 4
scenecut: 40
subme: 9
trellis: 2
weightp: 2
audioEncode:
type: AudioEncode
codec: libfdk_aac
bitrate: 128k
- type: X264Encode
suffix: #{(profileParams['fps'] ?: 25) > 30 ? "_x264_1410" : "_x264_1312"}
twoPass: true
width: 960
height: 540
vmaf:
enabled: true
threads: 4
subsample: 5
params:
b:v: #{(profileParams['fps'] ?: 25) > 30 ? "1410k" : "1312k"}
maxrate: #{(profileParams['fps'] ?: 25) > 30 ? "2115k" : "1968k"}
bufsize: #{(profileParams['fps'] ?: 25) > 30 ? "2820k" : "2624k"}
r: #{profileParams['fps'] ?: 25}
fps_mode: cfr
pix_fmt: yuv420p
force_key_frames: "expr:not(mod(n,#{profileParams['gop'] ?: 96}))"
level: #{(profileParams['fps'] ?: 25) > 30 ? "3.2" : "3.1"}
profile:v: main
x264-params:
deblock: 0,0
aq-mode: 1
aq-strength: 1.0
b-adapt: 2
bframes: 6
b-bias: 0
b-pyramid: 2
chroma-qp-offset: -2
direct: auto
rc-lookahead: #{(profileParams['fps'] ?: 25) > 30 ? 80 : 60}
keyint: #{(profileParams['gop'] ?: 96) * 2}
keyint_min: #{profileParams['gop'] ?: 96}
me: hex
merange: 16
cabac: 1
partitions: all
ref: 4
scenecut: 40
subme: 9
trellis: 2
weightp: 2
audioEncode:
type: AudioEncode
codec: libfdk_aac
bitrate: 96k
- type: X264Encode
suffix: #{(profileParams['fps'] ?: 25) > 30 ? "_x264_910" : "_x264_806"}
twoPass: true
width: 640
height: 360
vmaf:
enabled: true
threads: 4
subsample: 5
params:
b:v: #{(profileParams['fps'] ?: 25) > 30 ? "910412" : "806121"}
maxrate: #{(profileParams['fps'] ?: 25) > 30 ? "1365618" : "1209182"}
bufsize: #{(profileParams['fps'] ?: 25) > 30 ? "1820824" : "1612242"}
r: #{profileParams['fps'] ?: 25}
fps_mode: cfr
pix_fmt: yuv420p
force_key_frames: "expr:not(mod(n,#{profileParams['gop'] ?: 96}))"
profile:v: main
level: #{(profileParams['fps'] ?: 25) > 30 ? "3.2" : "3.1"}
x264-params:
deblock: 0,0
aq-mode: 1
aq-strength: 1.0
b-adapt: 2
bframes: 6
b-bias: 0
b-pyramid: 2
chroma-qp-offset: -2
direct: auto
rc-lookahead: #{(profileParams['fps'] ?: 25) > 30 ? 80 : 60}
keyint: #{(profileParams['gop'] ?: 96) * 2}
keyint_min: #{profileParams['gop'] ?: 96}
me: hex
merange: 16
cabac: 1
partitions: all
ref: 4
scenecut: 40
subme: 9
trellis: 2
weightp: 2
audioEncode:
type: AudioEncode
codec: libfdk_aac
bitrate: 96k
- type: X264Encode
suffix: #{(profileParams['fps'] ?: 25) > 30 ? "_x264_410" : "_x264_320"}
twoPass: true
width: 416
height: 234
vmaf:
enabled: true
threads: 4
subsample: 5
params:
b:v: #{(profileParams['fps'] ?: 25) > 30 ? "410450" : "324051"}
maxrate: #{(profileParams['fps'] ?: 25) > 30 ? "615675" : "486077"}
bufsize: #{(profileParams['fps'] ?: 25) > 30 ? "820900" : "648102"}
r: #{profileParams['fps'] ?: 25}
fps_mode: cfr
pix_fmt: yuv420p
force_key_frames: "expr:not(mod(n,#{profileParams['gop'] ?: 96}))"
profile:v: baseline
level: #{(profileParams['fps'] ?: 25) > 30 ? "3.2" : "3.1"}
x264-params:
deblock: 0,0
aq-mode: 1
aq-strength: 1.0
chroma-qp-offset: -2
rc-lookahead: #{(profileParams['fps'] ?: 25) > 30 ? 40 : 30}
keyint: #{(profileParams['gop'] ?: 96) * 2}
keyint_min: #{profileParams['gop'] ?: 96}
me: hex
merange: 16
cabac: 0
8x8dct: 0
ref: 3
scenecut: 40
subme: 9
trellis: 2
audioEncode:
type: AudioEncode
codec: libfdk_aac
bitrate: 96k
- type: AudioEncode
codec: libfdk_aac
bitrate: 192k
suffix: _STEREO
params:
cutoff: 20000
- type: AudioEncode
codec: libfdk_aac
bitrate: 64k
suffix: _STEREO_LB
params:
profile:a: aac_he
cutoff: 14000
- type: AudioEncode
codec: libfdk_aac
bitrate: 32k
suffix: _STEREO_TB
params:
profile:a: aac_he_v2
cutoff: 14000
- type: AudioEncode
codec: libfdk_aac
bitrate: 192k
suffix: _STEREO_DE
dialogueEnhancement:
enabled: true
dialogueEnhanceStereo:
enabled: #{(profileParams['dialogueEnhancementEnabled'] ?: true)}
audioMixPreset: de-dynamic
optional: true
params:
cutoff: 20000
- type: AudioEncode
codec: libfdk_aac
bitrate: 64k
suffix: _STEREO_LB_DE
dialogueEnhancement:
enabled: true
dialogueEnhanceStereo:
enabled: #{(profileParams['dialogueEnhancementEnabled'] ?: true)}
audioMixPreset: de-dynamic
optional: true
params:
profile:a: aac_he
cutoff: 14000
- type: AudioEncode
codec: libfdk_aac
bitrate: 32k
suffix: _STEREO_TB_DE
dialogueEnhancement:
enabled: true
dialogueEnhanceStereo:
enabled: #{(profileParams['dialogueEnhancementEnabled'] ?: true)}
audioMixPreset: de-dynamic
optional: true
params:
profile:a: aac_he_v2
cutoff: 14000
- type: AudioEncode
codec: ac3
bitrate: 448k
suffix: _SURROUND_DE
dialogueEnhancement:
enabled: true
audioMixPreset: de-dynamic
optional: true
channelLayout: "5.1"
- type: AudioEncode
codec: ac3
bitrate: 448k
suffix: _SURROUND
optional: true
channelLayout: "5.1"
- type: ThumbnailMapEncode
decodeOutput: 0
A few things worth noting about this profile:
decodeOutput: 0 — the thumbnail is decoded from the first video output (the 1080p rung) rather than re-decoding the source. This avoids an extra decode pass. 0 is the zero-based index into the encodes list.
libfdk_aac codec — all AAC encodes here use libfdk_aac, which is not included in the pre-built Docker images (it requires a custom build due to licensing). If you substitute aac, the profile:a: aac_he and profile:a: aac_he_v2 parameters are not supported by the standard AAC encoder and must be removed — the _STEREO_LB and _STEREO_TB outputs will fall back to plain AAC at the specified bitrates.
de-dynamic audio mix preset — the dialogue-enhanced encodes reference a custom de-dynamic preset that must be added to your encore-settings:
encore-settings:
encoding:
audio-mix-presets:
de-dynamic:
fallback-to-auto: false
default-pan:
stereo: "FL<FL+1.5*FC+0.707107*BL+0.707107*SL|FR<FR+1.5*FC+0.707107*BR+0.707107*SR"
pan-mapping:
"[5.1]":
"[5.1]": "c0=c0|c1=c1|c2<1.5*c2|c3=c3|c4=c4|c5=c5"
"[5.1(side)]":
"[5.1]": "c0=c0|c1=c1|c2<1.5*c2|c3=c3|c4=c4|c5=c5"
This preset boosts the centre (dialogue) channel by 1.5× before the dialogue-enhancement filters receive it. The channel layout keys ([5.1]) must be quoted in YAML to avoid being parsed as sequence syntax.