Video Encoding Presets
Video encoding presets define how MediaMoth transcodes your media files. Whether you're converting formats, adjusting quality, or creating complex multi-output workflows, presets give you complete control over FFmpeg and HandBrake encoding parameters.
This guide covers how to create and use encoding presets for the Video Conversion Service.
Overview
MediaMoth supports two video encoding engines:
- FFmpeg - Flexible, supports multiple inputs/outputs, uses custom JSON configuration with template variables
- HandBrake - Standard single-file transcoding, uses HandBrake's native preset files
When creating a video conversion job, you specify which encoder to use and provide a configuration file that defines the encoding parameters.
FFmpeg Configuration
FFmpeg configurations use a custom JSON format with three required fields:
{
"name": "config-identifier",
"description": "Human-readable description",
"template": [
// Array of FFmpeg command-line arguments
]
}Configuration Fields
- name: Unique identifier for this configuration (used for logging and reference)
- description: Human-readable explanation of what this preset does
- template: Array of FFmpeg command-line arguments with template variables
Template Variables
FFmpeg configurations support two types of template variables:
1. File Placeholders
Use these placeholders to reference input and output files:
Inputs:
{{.Input0}},{{.Input1}},{{.Input2}}, etc.- Reference input files by index (0-based)
- Indices must be sequential starting from 0 (no gaps allowed)
- No maximum number of inputs
Outputs:
{{.Output0}},{{.Output1}},{{.Output2}}, etc.- Reference output files by index (0-based)
- Indices must be sequential starting from 0 (no gaps allowed)
- No maximum number of outputs
Example:
[
"-i", "{{.Input0}}",
"-i", "{{.Input1}}",
"{{.Output0}}"
]2. Smart Tags
Smart tags let you pull values from media metadata into your FFmpeg configuration. If your media has tags formatted as type:value, you can reference them using {{tagname}}.
Common smart tag examples:
series:Scooby Doo→ Use{{series}}in template → Resolves to "Scooby Doo"season:1→ Use{{season}}→ Resolves to "1"episode:5→ Use{{episode}}→ Resolves to "5"quality:1080p→ Use{{quality}}→ Resolves to "1080p"
Smart tag notes:
- Tag names are case-insensitive (
{{series}}and{{Series}}are equivalent) - If a referenced tag doesn't exist in media metadata, the job will fail with an error
- Format is always
type:value(single colon)
Example using smart tags:
{
"name": "series-episode-encoder",
"description": "Encode with series/episode in output filename",
"template": [
"-i", "{{.Input0}}",
"-c:v", "libx264",
"-crf", "23",
"/output/{{series}}_S{{season}}E{{episode}}.mp4"
]
}For more about media metadata and smart tags, see Media Metadata.
Example: Simple H.264 Transcoding
A basic configuration that converts any video to H.264 with reasonable quality:
{
"name": "h264-standard",
"description": "Standard H.264 encoding with CRF 23",
"template": [
"-i", "{{.Input0}}",
"-c:v", "libx264",
"-preset", "medium",
"-crf", "23",
"-c:a", "aac",
"-b:a", "128k",
"-movflags", "+faststart",
"{{.Output0}}"
]
}What this does:
- Takes one input file (
{{.Input0}}) - Encodes video with H.264 codec at CRF 23 (balanced quality/size)
- Uses "medium" preset (balanced speed/compression)
- Encodes audio to AAC at 128kbps
- Adds faststart flag for web streaming
- Writes to one output file (
{{.Output0}})
Example: Complex Multi-Input with Audio Sync
The configuration from earlier showing advanced FFmpeg features:
{
"name": "h265-animation-sync",
"description": "H.265 animation encoding with audio sync",
"template": [
"-framerate", "24000/1001",
"-pattern_type", "glob",
"-i", "{{.Input0}}",
"-itsoffset", "-0.501",
"-i", "{{.Input1}}",
"-map", "0:v:0",
"-map", "1:a:0",
"-c:v", "libx265",
"-tag:v", "hvc1",
"-crf", "20",
"-tune", "animation",
"-pix_fmt", "yuv420p",
"-c:a", "copy",
"-r", "24000/1001",
"-shortest",
"-movflags", "+faststart",
"{{.Output0}}"
]
}What this does:
- Takes two inputs: video frames (
{{.Input0}}) and audio ({{.Input1}}) - Applies audio offset for synchronization (
-itsoffset) - Maps video from first input, audio from second input
- Encodes with H.265 (HEVC) optimized for animation
- Uses CRF 20 (higher quality)
- Copies audio without re-encoding
- Outputs to single file
Example: Audio Extraction
Extract audio track from video:
{
"name": "audio-extract",
"description": "Extract audio track to MP3",
"template": [
"-i", "{{.Input0}}",
"-vn",
"-c:a", "libmp3lame",
"-q:a", "2",
"{{.Output0}}"
]
}What this does:
- Takes video input
- Disables video stream (
-vn) - Encodes audio to MP3 with quality level 2 (high quality)
- Outputs audio-only file
HandBrake Configuration
HandBrake uses its native preset format. Instead of creating custom JSON, you export presets directly from the HandBrake application.
Creating HandBrake Presets
- Open HandBrake
- Configure your desired encoding settings
- Go to Presets → Save New Preset
- Export the preset to a JSON file
- Use that file as your configuration in MediaMoth
HandBrake Constraints
Unlike FFmpeg, HandBrake has strict input/output requirements:
- Exactly 1 input file (no multiple inputs)
- Exactly 1 output file (no multiple outputs)
- No template variables (preset is used as-is)
If you need multiple inputs or outputs, use FFmpeg instead.
HandBrake Documentation
For detailed information about HandBrake presets and encoding options, see the official HandBrake documentation:
Using Presets in Jobs
When creating a video conversion job, you specify:
- Converter type:
"ffmpeg"or"handbrake" - Config name: Identifier for the configuration
- Config source: File path to the configuration file
Configuration files can be stored in multiple locations:
- Local filesystem: Direct file paths
- Remote (rsync): Remote servers via rsync
- S3: Amazon S3 or compatible storage
For details about file sources, see File Sources.
Common Patterns and Best Practices
Quality vs. File Size
CRF (Constant Rate Factor) controls quality/size tradeoff:
- CRF 18-20: High quality, larger files (near-lossless)
- CRF 23: Balanced quality/size (recommended default)
- CRF 28+: Lower quality, smaller files
Preset speed affects encoding time and compression:
ultrafast- Fastest encoding, larger filesmedium- Balanced (recommended default)sloworslower- Better compression, slower encoding
Web Streaming Optimization
Always include -movflags +faststart for MP4 files served over web:
[
"-movflags", "+faststart",
"{{.Output0}}"
]This moves metadata to the beginning of the file, enabling progressive streaming.
Sequential Indexing Requirement
Input and output indices must be sequential with no gaps:
Valid:
"{{.Input0}}", "{{.Input1}}", "{{.Input2}}"Invalid (will fail):
"{{.Input0}}", "{{.Input2}}" // Missing Input1Audio Codec Compatibility
For maximum compatibility, use AAC audio:
[
"-c:a", "aac",
"-b:a", "128k" // Or "192k" for higher quality
]Avoid less common codecs unless you have specific requirements.
Handling Multiple Resolutions
To generate multiple output resolutions, use separate output streams:
{
"name": "multi-resolution",
"description": "Generate 1080p and 720p outputs",
"template": [
"-i", "{{.Input0}}",
"-filter_complex", "[0:v]split=2[v1][v2];[v1]scale=1920:1080[v1out];[v2]scale=1280:720[v2out]",
"-map", "[v1out]",
"-c:v", "libx264",
"-crf", "23",
"{{.Output0}}",
"-map", "[v2out]",
"-c:v", "libx264",
"-crf", "23",
"{{.Output1}}"
]
}Next Steps
- Service Nodes - Learn how video conversion fits into pipeline nodes
- Media Metadata - Understanding media tags and smart tags
- File Sources - How to specify input/output/config file locations
- Creating Pipelines - Build workflows using video conversion nodes
- Common Workflows - Example pipeline patterns with video conversion