Skip to content

Instantly share code, notes, and snippets.

@fizzyade
Last active February 27, 2024 22:43
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fizzyade/00a4ea6e171b4d1e8c33d9dd8f10784c to your computer and use it in GitHub Desktop.
Save fizzyade/00a4ea6e171b4d1e8c33d9dd8f10784c to your computer and use it in GitHub Desktop.
tvheadend container + nvidia ffmpeg under Unraid

NVIDIA+TVHEADEND+UNRAID+ACCELERATED FFMPEG

I recently had a need to get hardware accelerated ffmpeg running on tvheaded under unraid, I eventually achieved this with a few tricks, here are my notes on what I did to achieve this.

First up, Unraid NVIDIA support

Install the Nvidia plugin under Unraid, this installs a custom kernel complete with the nidia drivers and docker runtime to support thiese.

Next install a hardware accelerated FFMPEG

Create a new docker container named "ffmpeg", we will clone the following repo:

jrottenberg/ffmpeg:4.1-nvidia

I chose this version as it is linked against a version of the nvidia drivers that is compatible with the Unraid Nvidia plugin.

Go into advanced settings on the docker container and set the "Extra Parameters" to the following:

-it --entrypoint bash --runtime=nvidia

The container as default simply runs an instance of ffmpeg and then exits. Modifying the entrypoint allows us to spawn a container containing the FFMPEG binary and keep it running so we don't have to create a container on the fly every time.

Setting the runtime to nvidia is important, without it hardware acceleration won't work.

Now we have a container set up which is capable of running a hardware accelerated FFMPEG.

Modifying the tvheadend container

We need to make some changes to the tvheadend container to allow it to use our ffmpeg, you could make these changes by cloning the docker file and then creating your own modified image, but I have gone with a second option of overlaying some modified files over the existing installation.

In the appdata folder for your tvheadend, create the following files with the following content:

Filename: run (for example /mnt/user/appdata/tvheadend/run)

#!/usr/bin/with-contenv bash

IFS=" " read -r -a RUN_ARRAY <<< "$RUN_OPTS"

apk add docker
chmod o+rw /var/run/docker.sock

exec \
        s6-setuidgid abc /usr/bin/tvheadend -C -c /config "${RUN_ARRAY[@]}"

I have added the lines to install docker and change the permissions on docker.sock. This allows us to access the containers running on the host, the permission change is required as the tvheadend runs as an unprivileged user in the container and with the default permissions cannot access the docker.sock socket.

Ensure the file has execute permissions (chmod +x /mnt/user/appdata/tvheadend/run on the host)

Filename: ffmpeg.hw (for example /mnt/user/appdata/tvheadend/ffmpeg.hw)

#!/bin/sh

docker exec -i ffmpeg /usr/local/bin/ffmpeg $@

(If you called your container something other than ffmpeg then you will need to change the "-i ffmpeg" to match the name of your container.)

Ensure the file has execute permissions (chmod +x /mnt/user/appdata/tvheadend/ffmpeg.hw on the host)

Modifying the tvheadend container

We need to add the following paths to the tvheadend container:

Host Path: /var/run/docker.sock
Container Path: /var/run/docker.sock

Host Path: /mnt/user/appdata/tvheadend/run
Container Path: /etc/services.d/tvheadend/run

Host Path: /mnt/user/appdata/tvheadend/run
Container Path: /etc/services.d/tvheadend/run

Host Path: /mnt/user/appdata/tvheadend/ffmpeg.hw
Container Path: /usr/local/bin/ffmpeg.hw

(I have noticed tvheadend doing some weird things with the run script, sometimes a copy appears in /root, so I have added that as well, no idea if it's actually required, but it doesn't hurt so....)

Configuring tvheadend

Ensure that the ffmpeg container is started and restart the tvheadend container, you should now be able to add a custom stream format in tvheaded with a command like:

Command Line:

/usr/local/bin/ffmpeg.hw -hwaccel cuvid -c:v mpeg2_cuvid -i pipe:0 -c:a copy -c:v h264_nvenc -b:v 5M -f matroska pipe:1

Mime Type:

video/h264

When you select that stream profile you should find that it uses the hardware accelerated ffmpeg, you can check this by running nvidia-smi on the host, you should see ffmpeg running.

@isaacolsen94
Copy link

isaacolsen94 commented Feb 27, 2024

@fizzyade thank you for this awesome write up! Any way you'd be willing to do an updated version? I followed the tutorial for Unraid (I'm on 6.12.8), ffmpeg-4.2 docker and the LSIO tvheaded docker. But it doesn't seem to be working. Maybe a new guide isn't needed and I just may need some guidance on what I'm doing wrong

@isaacolsen94
Copy link

How did you guys implement this with a recording profile? Mine currently seem to fail if I use of one these presets

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment