Server & 3rd-party tools

FFmpeg

Media conversion, FFprobe checks, and optional static builds

FFmpeg is the media-conversion engine RKHM uses to make sure whatever a listener uploads actually plays back in a browser, regardless of the format it arrived in. This article covers server setup, exactly how the conversion decision is made, resource usage, and the failures that come up in practice — most FFmpeg problems are server environment issues, not RKHM configuration issues, so this article leans heavily on how to tell the two apart.

What FFmpeg is used for

  • Converting an uploaded audio file that isn't already MP3 into MP3, using the fastest method the source file allows (see “How the conversion decision works” below).
  • Generating the lower-quality rendition ladder used for adaptive playback and bandwidth-limited plans.
  • Encrypted HLS output (segmented, AES-128) for premium/protected playback.
  • Converting subtitle files to WebVTT, including automatic character-encoding detection and repair for subtitle files that weren't saved as clean UTF-8.
What FFmpeg does NOT do here
Waveform generation is a separate tool with its own binary and its own Admin → Settings entry (Audio Waveform) — it is not part of FFmpeg and enabling FFmpeg does not enable it. RKHM also does not extract video thumbnails/cover frames or burn subtitles into the video picture — subtitles are always kept as a separate track, never baked into the video.

Server requirements

  • PHP's proc_open() and exec() functions must be enabled. Some managed/shared hosts disable these by default — if they're disabled, every conversion fails silently rather than with a clear error (see Troubleshooting).
  • An FFmpeg binary the web server user can execute — either installed on the server and referenced by absolute path, or RKHM's bundled static build.
  • FFprobe (normally installed alongside FFmpeg) is optional but strongly recommended — without it, RKHM cannot tell whether an uploaded file is already compatible, so it always fully re-encodes every video, which is far slower and heavier on the server than it needs to be.
  • Write access for the web server user to the upload directory (temporary files are written next to the source during conversion) and to wherever HLS output is stored.
  • Enough free disk space for the source file, its temporary output, and — while a quality ladder or HLS is being generated — several renditions coexisting briefly. There is no pre-flight disk-space check; a full disk shows up as a conversion failure, not a clear “disk full” message.

Enabling FFmpeg

Under Setting → General → External Tools, there are two separate groups: FFmpeg and FFprobe (the FFprobe group was added in v2.1.04). Each has its own enable switch, its own absolute path field, and its own Test button — enable and test both. The Test button runs a real conversion of a bundled sample file and reports the exact command it ran, which is the fastest way to tell a path problem from a permissions problem from a missing-binary problem.

  • Use the server's own FFmpeg — point the path field at the server's installed binary (e.g. /usr/bin/ffmpeg).
  • Use the bundled static build — a self-contained FFmpeg/FFprobe pair shipped with RKHM, for servers where you can't install packages yourself. Tick Use 'FFmpeg Static Builds' instead of setting a path. It is a 64-bit Linux (x86_64) build, so it doesn't run on Windows, macOS or ARM servers; install FFmpeg there instead.
Enable FFprobe too, not just FFmpeg
FFmpeg alone still gives you conversion, HLS and the quality ladder — but with FFprobe off, every single video is fully re-encoded even if it was already in a perfectly compatible format. Enabling FFprobe is what lets already-compatible uploads skip re-encoding entirely (see below), which is usually the single biggest speed and server-load improvement available.

Two more settings live in the same FFmpeg group (both added in v2.1.04): Hardware encoder (NVIDIA NVENC or Intel QuickSync, if the server has a supported GPU — much faster than encoding on the CPU when it works) and Encoding priority (Speed / Balanced / Smaller size — trades server time for output file size). A GPU encoder that fails on a specific job — a concurrent-session limit, a driver update, a busy device — automatically retries once on the CPU rather than failing the upload outright, so an occasional job silently taking longer than expected is often a hardware encoder falling back, not a new problem.

How the conversion decision works

This is the part worth understanding, because it explains both why most uploads convert almost instantly and why a small number take much longer. With FFprobe enabled, every uploaded video is inspected before any conversion is attempted, and checked against every one of these rules in order:

  1. Video codec must be H.264
  2. H.264 profile must be Baseline, Constrained Baseline, Main or High
  3. Pixel format must be yuv420p (standard 8-bit colour)
  4. H.264 level must be 4.2 or lower
  5. Width and height must both be even numbers
  6. The video must be progressive, not interlaced
  7. Audio must be AAC (LC, HE-AAC or HE-AACv2), 8 channels or fewer
ResultWhat happensWhy
Every check passesNothing is sent to FFmpeg at allThe file is already exactly what a browser needs
Only the audio check failsVideo stream is copied as-is; only audio is re-encoded to AACFast — no video re-encoding needed
Any video check failsThe file is fully re-encodedThe video itself isn't compatible and has to be converted
FFprobe is disabled or unavailableThe file is always fully re-encodedRKHM has no way to check compatibility without it

This is also exactly what the Stats → System → Media processing panel (added in v2.1.04) reports: files that needed no work at all, files that were copied rather than encoded, and files that had to be fully converted — along with which specific check sent each one to a full encode. Checking that panel after a batch of uploads is the quickest way to see whether your content library is mostly compatible already or mostly needing conversion.

Resource usage and the most common cause of a stuck upload

Choose how upload processing runs
Under Setting → Files → Upload Setting → Background Processing, you can let the cron runner process uploaded media after submission. When background processing is off, conversion can run during the upload request, so PHP, PHP-FPM, web-server, and proxy timeouts may stop large uploads. When it is on, make sure your cron runner is configured and check Setting → Cronjob → Run logs if a file stays unprocessed. Both modes still need enough CPU, memory, and disk space for FFmpeg.

Video re-encoding can be demanding. Enable FFprobe so compatible uploads can take the faster copy path, and use hardware encoding only when your server has a supported GPU. If you process files during upload, set request timeouts for your largest expected file. If you use background processing, monitor cron execution and allow time for the file to finish processing before testing playback. Several simultaneous conversions can compete for CPU, GPU, and disk I/O.

Common failures and how to tell them apart

SymptomLikely causeWhat to check
Every conversion fails immediately, no useful errorThe FFmpeg path is wrong, or the binary isn't executable by the web server userRun the Test button — it shows the exact command and its output
Everything fails with no error at all, even the Test button behaves oddlyThe host has disabled proc_open/execAsk your host to enable them; there is no workaround inside RKHM for this
Large or long videos fail partway throughA request timeout (PHP, PHP-FPM, or the web server/proxy) is shorter than the conversion needsRaise max_execution_time, PHP-FPM's request_terminate_timeout, and any reverse-proxy read timeout together
A hardware-encoded job is much slower than expected, or CPU usage is high despite hardware encoding being onThe GPU encoder failed for that job and silently fell back to software encodingCheck Statistics → System → Media processing, filtered by encoder, for jobs that used libx264 despite hardware encoding being enabled
Conversion fails on a specific file onlyThe source file itself is corrupt or uses a codec/container FFprobe can't readRe-export or re-upload the source file; this isn't a server configuration issue
“Part of the file is missing” after conversion, or duration looks wrongUsually a disk-space or timeout issue that truncated the output mid-conversionCheck available disk space and the timeout settings above
HLS playback fails specifically for files whose audio was MP3Handled automatically — MP3 audio is always re-encoded to AAC for HLS, since browsers can't play MP3 inside that formatNot a fault; if playback still fails, the issue is elsewhere in HLS delivery, not this conversion step

To turn FFmpeg-dependent processing off entirely, disable it under Setting → General → External Tools → FFmpeg, and review the related toggles under Setting → Files → Upload Setting to decide what happens to uploads that would otherwise have needed conversion.