Hardware-Transcoding in Peertube (Docker)

I didn’t receive any notifications about your answer, sorry about the delay.

I didn’t know the plugin was doing something else beyond --let’s say-- just « handling » the transcoding to ffmpeg with some flags added. I’ll try it and report to you my findings.

I’m only using HW transcoding for live streaming, because I need my « server » to be able to hand at least two streamings at the same time. So I have a question about it: which of the parameters inside main.ts should I change to tweak speed/quality? I was testing with the presets ffmeg allows (fast, faster, etc), but my tests were not very conclusive.

Finally, I would really appreciate if changing the preset (or whatever changes transcoding quality/speed settings) could be done through the web interface.

I stream with 1080p and 4mb bitrate, it is possible for live to keep the resolution and bitrate with which the stream is streamed without conversion, and to activate only 720p. That means in the end I will have 2 resolutions: 1080p without conversion and 720p with conversion. So if I already stream with 1080p, why should I convert this resolution?

Because streaming needs a specific format (HLS) to be delivered to clients.

If you want to change the visual quality you can override the getTargetBitrate function (here), higher value will give you bigger file/stream but better quality. For the speed I just realized rereading the documentation that the -preset option I used has no effect for hardware encode, I should use -compression_level which controls the tradeoff between speed and compression.

The -compression_level option controls the local speed/quality tradeoff in the encoder (that is, the amount of effort expended on trying to get the best results from local choices like motion estimation and mode decision), using a nebulous per-device scale. The argument is a small integer, from 1 up to some limit dependent on the device (not more than 7) - higher values are faster / lower stream quality.

You can replace the -preset option (here) by -compression_level and tweak the value to your liking.

When I have time I’ll see how to add options that can be set using the web interface.

1 « J'aime »

I finally got a chance to try the newer version of the plugin (0.2.3) and it installs fine. But transcodes still fail. I’ll try to start from scratch (yet another time) and report back with everything fresh.

btw, I’m not able to hardware transcode with the Nextcloud Memories app either. I’m starting to suspect the dummy behind the keyboard…
Or, maybe it’s that most of my intel hardware is Gen 7. I’ve tried with a 7700K and a Xeon 1245 v6.
I have a Gen 6 processor in a machine somewhere. I’ll have to try it with that machine at some point.

It is not correct, here is a live stream without transcoding, that is, it is in the format in which I make the stream, 1080p and 4Mb bitrate.

And here is the example for which, in order to have the 720p and 1080p versions, I have to transcode both. Why, if above is the same stream, I also get the 1080p version with which the stream is made without transcoding.

Logically, it should be possible to keep the resolution and bitrate with which the live stream is made (ie 1080p) without transcoding (copy) and for the 720p and 360p resolution there should already be transcoding to save CPU resources.

Maybe someone knows how to change the bitrate during transcoding, if I do a live stream with 3.5Mb and 1080p resolution, why does it convert to 5.5Mb bitrate when transcoding to 1080p? This is the default x264 transcoding.

Intel QuickSync HW transcoding works since 2nd generation core CPUs (i3, i5, etc). I don’t know about Xeon CPUs.

Are you running with docker? If so, and if you didn’t use the dockerfile @gdsn provided, every time you you restart the container you’d need to reinstall manually all the dependencies needed.

You need to do two things to make it work: install the necessary drivers AND ensure peertube has access to the devices inside /dev/dri (I assume you’re running peertube on linux).

1 « J'aime »

I’m sorry, but I couldn’t understand clearly what you mean.

Are you from Brazil? I’m asking because your username looks like Sergio, which is a name we have here. If so, we could chat in Portuguese.

I just pushed a new version 0.2.4 which adds a settings page for:

  • compression level
  • hardware decode (slight performance increase but reduced input file compatibility)
  • target bitrate for each resolution

As usual, it works on my machine but I can only test on this one so let me know if you have errors.

2 « J'aime »

I’ll see what I can do when I have more time. For now, I added a check to lower target bitrate to the min between input bitrate and the target computed (or set by the user).

Yes, my testing has been with the example Dockerfile that @gdsn has provided.

That said, I just tried to rebuild with the V8 hardware driver just to see what happens and I’m finding that the only version of the plugin that shows up when I search within the admin configuration GUI is v0.1.0. I expected to see v-0.2.4.

update: I installed v0.2.5 manually in the manner that @gdsn suggested earlier in this thread. I had to take the container down and back up before vaapi showed up as an option in the VOD tab. I’m still uploading a test video so I don’t know yet if it’s working or not with the newer Intel driver.

update2: Still fails transcoding. One item of interest; I bashed into the peertube container to look for the render group and it wasn’t there despite the groupadd line in the docker compose file. Adding the render group manually (with the gid of the host render group) did not fix the issue either, although I may have the wrong intel driver now. So I’ll try another rebuild.

I’ve tried a fresh install on a machine with a 6th Gen Intel CPU/GPU on Linux Mint with the Dockerfile prescribed and I still get the same result - Failed Transcoding.

I’m a bit confused about permissions (for the D128 device for instance) since some of the discussion about on demand transcoding with other packages like Jellyfin and Nextcloud memories talk about issues with users priviledges in the container and out. I’ve tried adding the render group in the container and adding the peertube user to the render group in the container. But that doesn’t seem to help.

If hardware transcoding is not possible, is it possible to transcode with software, i.e. with libx264? It doesn’t work for me if it’s not hardware. Or to do as with bitrate, the possibility to choose libx264, h264_nvenc, h264_qsv.

It is not possible with the current transcode profile plugin API to detect that (or at least not easily). The better way would be directly change peertube to retry failed transcode jobs with a safe profile.

This could be done, however it’s a bit outside the scope of the plugin for now. If it’s not too complicated I may do it but I promise nothing.

I personally use this plugin on a 6th gen intel CPU so I know it works on this.
After looking this is my setup on a debian machine:

My docker-compose.yml:

version: "2"

services:

  peertube:
    build:
      context: .
      args:
        VERSION: v5.1.0
    user: peertube
    env_file:
      - .env
    networks:
      - default
      - web
    ports:
     - "1935:1935" # If you don't want to use the live feature, you can comment this line
    #  - "9000:9000" # If you provide your own webserver and reverse-proxy, otherwise not suitable for production
    volumes:
      - /mnt/hdd/peertube/data:/data
      - /mnt/hdd/peertube/config:/config
    group_add:
      - "107"   # find the render group id for your machine with cat /etc/group | grep render | cut -d: -f3
    devices:
      # VAAPI Devices
      - /dev/dri:/dev/dri
    depends_on:
      - postgres
      - redis
    restart: "always"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.peertube.rule=Host(`peertube.example.com`)"
      - "traefik.http.routers.peertube.service=peertube"
      - "traefik.http.services.peertube.loadbalancer.server.port=9000"

  postgres:
    image: postgres:13-alpine
    env_file:
      - .env
    volumes:
      - /mnt/hdd/peertube/postgres:/var/lib/postgresql/data
    restart: "always"

  redis:
    image: redis:6-alpine
    volumes:
      - /mnt/hdd/peertube/redis:/data
    restart: "always"



networks:
  web:
    external:
      name: traefik_web

The Dockerfile in the same folder:

ARG VERSION=v4.2.0
from chocobozzz/peertube:${VERSION}-bullseye


# install dependencies for vaapi
RUN 	   apt update \
	&& apt install -y --no-install-recommends wget apt-transport-https \
	&& echo "deb http://deb.debian.org/debian/ $( awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release ) non-free" | tee /etc/apt/sources.list.d/non-free.list \
	&& apt update \
	&& apt install -y --no-install-recommends vainfo i965-va-driver-shaders \
	&& apt install -y --no-install-recommends python3 \
	&& rm /var/lib/apt/lists/* -fR

On the host, I have a peertube user which is in the render group (not sure if it is still useful or just a relic from older tests) and the render group has id 107.
I also have i965-va-driver-shaders driver installed both in host and the container.

Finally, I noticed a bug in the code I pushed. It looks like I pass a bad value for compression level by default. A simple fix is to manually change it in the settings each time you restart the server. I pushed a new version that should fix the issue.

Aha! You did create a peertube user on the host. That may be the key…

But when I try your file with the user set to peertube, I get errors that it can’t create the appropriate folders in the data and logs folders. There is a permission problem, I believe. Of course, I changed the volume mapping to simply put those folders within my docker compose directory because I don’t have the locations that you used on your machine.
I’m wondering if I have an issue mapping to the UID of the peertube user on the host.

If I comment the user line, I can get Peertube up but I can’t install the v0.2.8 plugin. I tried both in the gui and by executing in the container.

ReferenceError: structuredClone is not defined
at Object. (/data/plugins/node_modules/peertube-plugin-hardware-transcode-vaapi/dist/main.js:21:18)

I pushed a new version 0.2.9 which should fix that.

I tried to modify this plugin for transcoding the live stream with the Nvidia video card and somehow it doesn’t work. Does anyone know a method how I can do this with the Nvidia video card and not with the CPU?

I modified the plugin and already encode with nvidia. Here is the cpu load for encoding 2 live streams in 3 formats each (480,720,1080).


Can someone show cpu load when encoding with intel quick sync?