Video transcoding
Frameleaf keeps every original video untouched, and makes a playback copy when the original won’t play well everywhere, for example because of its codec, container or resolution. Playback copies are stored in UPLOAD_LOCATION/encoded-video and can always be made again. They’re created by the Playback videos job queue.
Edits you render in the editor and Studio exports use the same transcoding settings, including hardware acceleration where it’s safe. When an edit needs filters that only run on the processor, rendering switches to software by itself.
Settings
Section titled “Settings”Find these in Administration, then Settings, then Video Transcoding Settings.
Transcode policy
Section titled “Transcode policy”The policy decides which videos get a playback copy. HDR videos and videos with a pixel format other than YUV 4:2:0 are always transcoded, unless transcoding is turned off.
| Policy | Transcodes |
|---|---|
| All videos | Every video |
| Optimal | Videos above the target resolution, or not in an accepted format |
| Bitrate | Videos above the maximum bitrate, or not in an accepted format |
| Required (default) | Only videos not in an accepted format |
| Disabled | No videos. Playback may break on some devices |
Encoding options
Section titled “Encoding options”| Setting | What it does | Default |
|---|---|---|
| Video codec | H.264 is widely compatible and quick, but makes much larger files. HEVC and VP9 are more efficient; VP9 plays better on the web but takes longer. AV1 is the most efficient but isn’t supported on older devices | H.264 |
| Audio codec | AAC, MP3 or Opus. Opus is the highest quality but less compatible with old devices | AAC |
| Accepted video codecs | Codecs that don’t need transcoding (for the policies that use them) | H.264 |
| Accepted audio codecs | Audio codecs that don’t need transcoding | AAC, MP3, Opus |
| Accepted containers | Containers that don’t need remuxing to MP4 | MOV, OGG, WebM |
| Target resolution | Higher keeps more detail but takes longer, makes larger files and can make the apps less responsive | 720p |
| Constant rate factor (-crf) | Quality level; lower is better but larger. Typical values: 23 for H.264, 28 for HEVC, 31 for VP9, 35 for AV1 | 23 |
| Maximum bitrate | Makes file sizes more predictable at a small cost to quality. 0 turns it off. At 720p, typical values are 2600 kbit/s for VP9 or HEVC and 4500 kbit/s for H.264. 5000, 5000k and 5M mean the same |
0 |
| Preset (-preset) | Compression speed. Slower presets make smaller files and improve quality at a given bitrate. VP9 ignores speeds above faster |
ultrafast |
| Threads | More threads encode faster but leave less room for other work. Don’t set more than your CPU cores; 0 uses everything |
0 |
| Tone-mapping | Keeps HDR videos looking right when converted to SDR. Hable preserves detail, Mobius colour and Reinhard brightness | Hable |
| Two-pass encoding | Encodes twice for a better result. With H.264 and HEVC it needs a maximum bitrate and ignores CRF. Only NVENC supports it among the hardware options | Off |
The advanced options (maximum B-frames, reference frames, maximum keyframe interval, temporal AQ, constant quality mode, preferred hardware device) are best left alone unless you know you need them. Temporal AQ applies only to NVENC; the preferred hardware device applies only to VAAPI and Quick Sync and picks the /dev/dri node to use.
Real-time transcoding
Section titled “Real-time transcoding”Real-time Transcoding is experimental. It transcodes while a video streams, which lets the player switch quality, but can add latency and stuttering if your server can’t keep up. It’s off by default. When on, it offers H.264 and HEVC at 480p, 720p and 1080p; choose only codecs your accelerator can encode if you use one.
Hardware transcoding
Section titled “Hardware transcoding”A GPU can take most of the transcoding work off the processor.
Supported hardware
Section titled “Supported hardware”| Option | Hardware | Compose service |
|---|---|---|
| NVENC | NVIDIA GPUs | nvenc |
| Quick Sync | Intel CPUs with integrated graphics, 7th generation or later | quicksync |
| RKMPP | Rockchip SoCs | rkmpp |
| VAAPI | AMD, NVIDIA and Intel | vaapi (vaapi-wsl on WSL2) |
Not supported: Raspberry Pi, and Quick Sync under WSL2. VAAPI works on NVIDIA and Intel too, but the specific options are better optimised for their own hardware.
Codec support depends on the hardware. H.264 and HEVC usually work; NVIDIA and AMD GPUs can’t encode VP9. Newer devices tend to give better quality.
Before you start
Section titled “Before you start”NVENC
- The official NVIDIA driver.
- On Linux (not WSL2), the NVIDIA Container Toolkit.
Quick Sync
- VP9 needs a 9th generation Intel CPU or newer.
- 11th generation and older CPUs may need low-power encoding turned on in the host’s graphics driver for VP9.
- An 11th generation CPU on kernel 5.15 (as shipped with Ubuntu 22.04 LTS) needs a newer kernel.
RKMPP
- A supported Rockchip SoC. Only RK3588 does tone-mapping in hardware; others tone-map in software but still encode in hardware.
- Hardware tone-mapping needs
/usr/lib/aarch64-linux-gnu/libmali.so.1on the host. Install thelibmalirelease for your Mali GPU (libmali-valhall-g610-g13p0-gbmon RK3588), then inhwaccel.transcoding.yml, underrkmpp, uncomment these three lines:
- /dev/mali0:/dev/mali0- /etc/OpenCL:/etc/OpenCL:ro- /usr/lib/aarch64-linux-gnu/libmali.so.1:/usr/lib/aarch64-linux-gnu/libmali.so.1:roSet it up
Section titled “Set it up”- Download
hwaccel.transcoding.ymlinto the same folder asdocker-compose.yml. - In
docker-compose.yml, underimmich-server, uncomment theextendssection and changecputonvenc,quicksync,rkmpp,vaapiorvaapi-wsl. - Redeploy the server container.
- In Video Transcoding Settings, under Hardware Acceleration, set Acceleration API to the same option and save. On Jasper Lake and Elkhart Lake CPUs, also set Constant quality mode to
CQP. - Check Hardware decoding. It’s on by default, which accelerates decoding as well as encoding; turn it off if some videos fail to transcode.
immich-server: container_name: frameleaf_server image: ghcr.io/frameleaf/frameleaf-server:${FRAMELEAF_VERSION:-${IMMICH_VERSION:-release}} extends: file: hwaccel.transcoding.yml service: quicksyncIf you use a config file, set accel (for example qsv for Intel or nvenc for NVIDIA) and accelDecode:
{ "ffmpeg": { "accel": "qsv", "accelDecode": true }}You don’t need to redo any transcoding jobs afterwards. Jobs that run after you turn it on use the GPU.
To confirm it’s working, run Settings, then Compute & jobs, then Hardware & GPU and its benchmark (see Hardware acceleration), or watch GPU use with nvtop (NVIDIA) or intel_gpu_top (Intel) while a video transcodes. No errors in the logs while transcoding is also a good sign.
Unraid, Portainer and single Compose files
Section titled “Unraid, Portainer and single Compose files”Some platforms can’t use more than one Compose file. Copy the relevant section of hwaccel.transcoding.yml into the immich-server service instead of using extends. For Quick Sync, that’s just:
immich-server: container_name: frameleaf_server image: ghcr.io/frameleaf/frameleaf-server:${FRAMELEAF_VERSION:-${IMMICH_VERSION:-release}} # No extends section devices: - /dev/dri:/dev/driThen continue from step 3 above.
On Unraid, with the all-in-one container:
- Quick Sync: stop and edit the Frameleaf container, choose Add another Path, Port, Variable, Label or Device, and add a
Devicewith any name and the value/dev/dri. - NVENC: add the variable
NVIDIA_VISIBLE_DEVICESwith the valueall, switch the container to Advanced Mode, add--runtime=nvidiato Extra Parameters, and restart it.
Then continue from step 4 above.
- Choose a slower preset than you would for software transcoding, to keep quality and file size in check.
- Prefer the specific option for your hardware (NVENC, Quick Sync) over VAAPI.