| README.md | ||
| rffmpeg.py | ||
| rffmpeg.yml.sample | ||
rffmpeg
rffmpeg is a remote FFmpeg wrapper used to execute FFmpeg commands on a remote server via SSH. It is most useful in situations involving media servers such as Jellyfin (our reference user), where one might want to perform transcoding actions with FFmpeg on a remote machine or set of machines to better handle the load.
Usage
-
Install the required Python 3 dependencies:
yamlandsubprocess. -
Create the directory
/etc/rffmpeg. -
Copy the
rffmpeg.yml.samplefile to/etc/rffmpeg/rffmpeg.ymland edit it to suit your needs. -
Install
rffmpeg.pysomewhere useful, for instance at/usr/local/bin/rffmpeg.py. -
Create symlinks for the command names
ffmpegandffprobetorffmpeg.py, for instance/usr/local/bin/ffmpeg -> /usr/local/bin/rffmpeg.pyand/usr/local/bin/ffprobe -> /usr/local/bin/rffmpeg.py. -
Edit your media program to use the
rffmpeg.pybinary (via the symlink names) instead of the standardffmpegbinary. -
Profit!
Full setup
This example setup is the one I use for rffmpeg, involving a Jellyfin server (jf1) and a remote transcode server (gpu1).
-
Prepare the remote transcode server. This involves the following steps:
-
Install any required tools or programs to make use of hardware transcoding. This is optional if you only plan to use software (i.e. CPU) transcoding.
-
Create a temporary transcoding directory somewhere on the system. Ideally, this should be fast scratch storage with no persistence required. In my case I use a pair of RAID-0 SSDs, though you could use a ramdisk if you have sufficient RAM. For my purposes, I put this directory at
/var/transcodeand mount my SSD RAID there. -
Create a user to accept SSH connections in and run the FFmpeg commands. I use a user called
jellyfinwith a home directory of/var/lib/jellyfin, identical to the user that is created by the Jellyfin server itself - this is important for the directory layout to work. For maximum compatibility, ensure this user has the exact same Unix UID as the Jellyfin user on your Jellyfin host. -
Ensure the temporary transcoding directory is owned by the new user.
-
Create a symlink from the user's home directory to the temporary transcoding directory. This much match the Jellyfin file layout to preserve paths. For insance, if your
transcoding-tempdirectory on the Jellyfin server is at/var/lib/jellyfin/transcoding-temp, the symlink must exist at the same location on the transcode server. -
Similarly to the transcoding directory, ensure your media volume is mounted on the transcode server at the same location as on the Jellyfin server.
-
Install an FFmpeg binary, in my case the
jellyfin-ffmpegpackage, on the transcode server. -
Install the NFS kernel server, and set up an export of your temporary transcoding directory such that the Jellyfin server can mount it.
-
-
On your Jellyfin server, create a new SSH private keypair owned by the Jellyfin service user.
-
Install the public key of the new SSH private keypair under the remote user on the transcode server.
-
Verify that SSH is successful from the Jellyfin server (as the Jellyfin user) to the transcode server as expected. Running
sudo -u <jellyfin-user> rffmpeg.pyonce with no arguments will accomplish this test. This also ensures that the SSH host key of the remote server is saved before Jellyfin attempts to run the command. -
Install the NFS client, and mount the temporary transcoding directory from the remote server to your
transcoding-tempdirectory as set in Jellyfin. -
Install the
rffmpegprogram as detailed above. -
In Jellyfin, set the
rffmpeg.pybinary, via itsffmpegsymlink, as your "FFmpeg path". The symlinks are important for Jellyfin to properly call theffprobecommand as well. -
Try running a transcode and verifying that the
rffmpegprogram works as expected. The flow should be:-
Jelyfin calls
rffmpeg.pywith the expected arguments. -
FFmpeg begins running on the transcode server; the file paths should all be valid there as they would be on the Jellyfin machine.
-
The FFmpeg process writes the output files to the NFS-exported temporary transcoding directory.
-
Jelyfin reads the output files from the NFS-mounted temporary transcoding directory and plays back normally.
-
rffmpeg options
Remote hosts
rffmpeg supports setting multiple hosts. It keeps state in /run/shm/rffmpeg, of all running processes. These state files are used during rffmpeg's initialization in order to determine the optimal target host. rffmpeg will run through these hosts sequentially, choosing the one with the fewest running rffmpeg jobs. This helps distribute the transcoding load across multiple servers.
Note however that this setup is NOT compatible with the simple NFS-based export mentioned above. For this to work properly, ALL the involved hosts must share the same temporary storage, for instance exported from another machine to the source and transcode hosts.