diff --git a/Hardware-accelerated-transcoding.md b/Hardware-accelerated-transcoding.md new file mode 100644 index 0000000..450125d --- /dev/null +++ b/Hardware-accelerated-transcoding.md @@ -0,0 +1,142 @@ +yt-dlp can re-encode downloads with ffmpeg (via `postprocessor_args`), and on a +machine with an Intel iGPU that encoding can run on the GPU instead of the CPU. +The MeTube image already ships ffmpeg, but not the VAAPI driver, and the +container has no access to the GPU by default. This page covers the three +things you need to add. + +Contributed by [@kamaeff](https://github.com/kamaeff) in +[discussion #1045](https://github.com/alexta69/metube/discussions/1045), tested +on Debian 13 with an Intel N150. + +### 1. Install the VAAPI driver in the image + +The MeTube image is based on `python:3.13-slim` (Debian), so you can layer the +Intel media stack on top of it with a small Dockerfile of your own: + +```dockerfile +FROM ghcr.io/alexta69/metube:latest + +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + intel-media-va-driver \ + libvpl2 \ + libmfx-gen1.2 && \ + rm -rf /var/lib/apt/lists/* +``` + +Add `vainfo` to that list if you want to be able to check the driver from +inside the container (see [Verifying](#verifying) below). + +The host needs the Intel media drivers installed too, and `/dev/dri/card0` and +`/dev/dri/renderD128` must exist there. + +### 2. Give the container access to `/dev/dri` + +Pass the devices through, and run MeTube with the host's `render` group so it's +allowed to open them. Find the GID first: + +``` +getent group render | cut -d: -f3 +``` + +Then, in your compose file: + +```yaml + metube: + build: ./metube # the Dockerfile from step 1 + environment: + - "PGID=993" # <- the render GID from above + devices: + - /dev/dri:/dev/dri +``` + +Note that `PGID` is also the group MeTube's downloaded files end up owned by, +since the entrypoint chowns the download directories to `PUID:PGID`. If you'd +rather keep your own group for the files, set `user:` in compose instead — that +makes the entrypoint skip its `gosu` step and keep whatever groups Docker gave +the container, so a supplementary group works: + +```yaml + user: "1000:1000" + group_add: + - "993" # the render GID +``` + +### 3. Tell ffmpeg to use the GPU + +Encoding options go in `postprocessor_args`. The example below is a preset (via +`YTDL_OPTIONS_PRESETS_FILE`) that decodes on the GPU, scales to 720p, and +encodes to HEVC — all in hardware: + +```json +{ + "hevc-720p-vaapi": { + "format": "bv*[height<=1440]+ba/b", + "merge_output_format": "mp4", + "postprocessors": [ + { "key": "FFmpegCopyStream" } + ], + "postprocessor_args": { + "copystream+ffmpeg_i": [ + "-vaapi_device", "/dev/dri/renderD128", + "-hwaccel", "vaapi", + "-hwaccel_output_format", "vaapi" + ], + "copystream+ffmpeg_o": [ + "-vf", "scale_vaapi=w=-2:h=720,fps=24", + "-vcodec", "hevc_vaapi", + "-qp", "26", + "-tag:v", "hvc1", + + "-acodec", "aac", + "-ac", "1", + "-b:a", "64k", + + "-f", "mp4", + "-movflags", "+faststart" + ] + } + } +} +``` + +What the pieces do: + +* `-hwaccel vaapi` + `-hwaccel_output_format vaapi` — decode on the GPU and + keep the decoded frames in GPU memory, so no copying back and forth. +* `scale_vaapi` — resize on the GPU. Use this rather than `scale`; the regular + filter can't operate on VAAPI surfaces. +* `-vcodec hevc_vaapi` — encode with the hardware HEVC encoder (`h264_vaapi` + for H.264). +* The `copystream+ffmpeg_i` / `copystream+ffmpeg_o` keys attach the arguments + to the `FFmpegCopyStream` postprocessor's ffmpeg invocation, `_i` before the + input and `_o` before the output. Both matter here: `-hwaccel` is an input + option and the filter/encoder settings are output options. + +The same setup can be defined globally via `YTDL_OPTIONS` instead of as a +preset, but a preset lets you pick hardware transcoding per download in the UI. + +### Verifying + +With `vainfo` installed in your image: + +``` +docker exec metube vainfo --display drm --device /dev/dri/renderD128 +``` + +It should list the driver and a set of `VAProfile...` entries including +`VAEntrypointEncSlice` for the codecs your GPU can encode. Also useful: + +``` +docker exec metube ffmpeg -hide_banner -encoders | grep vaapi +``` + +If ffmpeg fails with a permission error on `/dev/dri/renderD128`, the group in +step 2 is wrong or wasn't applied — check with `docker exec metube id`. + +### Other GPUs + +The device passthrough and group setup in step 2 are the same for AMD; swap the +driver package in step 1 for `mesa-va-drivers`. NVIDIA doesn't use VAAPI — it +needs the NVIDIA Container Toolkit and NVENC encoder names (`hevc_nvenc`, +`h264_nvenc`) instead. diff --git a/Home.md b/Home.md index 80709ea..8c115bf 100644 --- a/Home.md +++ b/Home.md @@ -10,6 +10,7 @@ Welcome to the MeTube wiki — the companion to the [README](https://github.com/ ### Guides * [Subscriptions](Subscriptions) — auto-download new uploads from channels and playlists. +* [Hardware-accelerated transcoding](Hardware-accelerated-transcoding) — re-encode downloads on an Intel/AMD GPU. * [Troubleshooting FAQ](Troubleshooting-FAQ) — common issues and how to diagnose them. ---