jrottenberg / ffmpeg

Docker build for FFmpeg on Ubuntu / Alpine / Centos / Scratch / nvidia / vaapi
https://hub.docker.com/r/jrottenberg/ffmpeg/
Apache License 2.0
1.44k stars 461 forks source link

Outputting files as another user (www-data) #124

Open dseeker opened 6 years ago

dseeker commented 6 years ago

I'm using the vaapi enabled docker via node.js spawn shell, it's working perfectly with HW acceleration. However the output encoded files are output as root:root, and so I cannot continue modifying the output with other applications that are running as www-data:www-data instead of root.

Upon using the user option the vaapi docker loses the privilege to access the vaapi device, here's the terminal log

docker run --device /dev/dri:/dev/dri -v /home/autoingest/:/autoingest --user 33:33 jrottenberg/ffmpeg:4.0-vaapi -stats -vaapi_device /dev/dri/renderD128 -hwaccel vaapi -hwaccel_output_format vaapi -hide_banner -t 30 -i "/autoingest/films/source.mov" -y -filter_complex 'format=nv12|vaapi.....

[AVHWDeviceContext @ 0x55b407756400] No VA display found for device: /dev/dri/renderD128.
Device creation failed: -22.
Failed to set value '/dev/dri/renderD128' for option 'vaapi_device': Invalid argument
Error parsing global options: Invalid argument

Is there any other way I can force ffmpeg to output as a specific user?

jrottenberg commented 6 years ago

Not tested but I think if you add more capabilities to your run, you should be able to use the gpu while keeping www-data as writer.

--cap-add=SYS_ADMIN, so your command becomes

docker run --cap-add=SYS_ADMIN --device /dev/dri:/dev/dri -v /home/autoingest/:/autoingest --user 33:33 jrottenberg/ffmpeg:4.0-vaapi -stats -vaapi_device /dev/dri/renderD128 -hwaccel vaapi -hwaccel_output_format vaapi -hide_banner -t 30 -i "/autoingest/films/source.mov" -y -filter_complex 'format=nv12|vaapi.....

Let me know if that does the trick, I'll add it to the readme.

thirstyraven commented 4 years ago

@jrottenberg I tried adding --cap-add=SYS_ADMIN like you suggested, I tried adding both --cap-add=SYS_ADMIN and --cap-add= SYS_PTRACE like the Intel docs asked me to, and I tried --privileged=true.

None of them worked, I still have the same error

[AVHWDeviceContext @ 0x559ca5f18480] No VA display found for device: .
Device creation failed: -22.
[h264 @ 0x559ca5f28440] No device available for decoder: device type vaapi needed for codec h264.
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> h264 (h264_vaapi))
  Stream #0:1 -> #0:1 (eac3 (native) -> aac (native))
Device setup failed for decoder on input stream #0:0 : Invalid argument

What now?

lowne commented 4 years ago

It's likely a permission issue on the device. I should preface that I'm using my own Dockerfile with libmfx (no vaapi), but I had a similar problem, which I solved by adding - inside the container, so in the Dockerfile - the user to the group owning the device:

RUN groupadd -g ${PGID} ffmpeg \
 && groupadd -g ${render_gid} render \
 && useradd -u ${PUID} -g ffmpeg -G video,render ffmpeg

where render_gid is the group id owning the render device on the host (likely /dev/dri/renderD128):

render_gid=$(stat -c '%g' /dev/dri/renderD128)

Then you can just docker run --user ${PUID} --device ..., no need for --privileged or --cap-add.

Note that you shouldn't pass a group id to docker run, or it'll override the other group(s) defined in the Dockerfile and you'll get the same issue again.

Hope this helps.