mviereck / x11docker

Run GUI applications and desktops in docker and podman containers. Focus on security.
MIT License
5.62k stars 378 forks source link

Support for webcam sharing #75

Closed sandrokeil closed 6 years ago

sandrokeil commented 6 years ago

Any idea how to share a webcam to a Docker container? My webcam is working fine on host e.g. via cheese. If I share the device /dev/video0 and /dev/video1 and the webcam usb device, cheese can not find the webcam. I've also tried different things like --sys-admin --cap-default --gpu.

Does simply sharing webcam device work for you like it's mentioned on stackoverflow?

mviereck commented 6 years ago

Does not work here, too. Neither --device /dev/video0 --device /dev/video1 nor --privileged works. The devices have group video, container user does have that, too. --user root does not help either.

Something is missing. I did not try to share USB devices, but that should not be needed.

Searching in the web does not give a hint. --device /dev/video0 and group video (or root in container) should be everything needed.

mviereck commented 6 years ago

Progress! If also installing mesa in image, I can run webcamoid if sharing --device /dev/video0. No further setup needed.

cheese still fails.

sandrokeil commented 6 years ago

It looks like webcamoid recognizes my webcam but I don't have a video from webcam. Video from screen is working. Maybe cheese needs some additional packages?

mviereck commented 6 years ago

This one works here:

FROM debian:stretch
RUN apt-get update
RUN apt-get install -y webcamoid
RUN apt-get install -y mesa-utils
CMD webcamoid

The missing key was mesa-utils here. Capturing screen with webcamoid worked here, but not the webcam, before I've installed mesa-utils. I assume you have an arch based image. How do you set it up? It seems your arch build still misses a package.

Maybe cheese needs some additional packages?

I am not sure. Adding RUN apt-get install -y --no-install-recommends guvcview camorama kamerka kamoso vlc cheese got me a bunch of webcam applications with their dependencies. All of them work fine, except cheese.

sandrokeil commented 6 years ago

I've no luck with the debian dockerfile. Yes, I use an Arch build. Maybe it's related to my host system or webcam. I've shared --device /dev/video0 with chromium and it recognizes the webcam but it can't get access, so no video/audio works.

I will try some mesa packages in the next days.

mviereck commented 6 years ago

Can you show me your arch Dockerfile? IIRC package mesa-demos includes all depenencies for --gpu and may fit for webcam, too. It may also be related to your nvidia card; it may help to install nvidia-driver.

sandrokeil commented 6 years ago

My dockerfile is a bit complicated, because it depends on two other Docker images but it should be (added mesa-demos).

FROM base/archlinux:2018.08.01

RUN pacman-key --init \
    && pacman -Sy --noconfirm archlinux-keyring \
    && pacman -Syu --noconfirm ibus pulseaudio pulseaudio-alsa ttf-dejavu ttf-freefont ttf-bitstream-vera ttf-liberation noto-fonts kbd coreutils fakeroot binutils

RUN echo LANG=en_US.UTF-8 > /etc/locale.conf \
    && sed -i "s/#de_DE/de_DE/g" /etc/locale.gen \
    && sed -i "s/#en_US.UTF/en_US.UTF/g" /etc/locale.gen \
    && locale-gen \
    && echo KEYMAP=de-latin1 > /etc/vconsole.conf \
    && echo FONT=lat9w-16 >> /etc/vconsole.conf

RUN echo "[multilib]" >> /etc/pacman.conf \
    && echo "Include = /etc/pacman.d/mirrorlist" >> /etc/pacman.conf \
    && pacman -Sl multilib \
    && pacman -Sy --noconfirm mesa make \
    && pacman -Scc --noconfirm

RUN pacman -Sy --noconfirm mesa-demos nvidia nvidia-utils cuda nvidia-settings opencl-nvidia ocl-icd

COPY arch-aur-install /usr/bin
RUN pacman -Sy --needed --noconfirm sudo patch \
    && useradd builduser -m \
    && passwd -d builduser \
    && printf 'builduser ALL=(ALL) ALL\n' | tee -a /etc/sudoers \
    && sudo -u builduser bash -c 'cd ~ && mkdir tmp && cd tmp && arch-aur-install https://aur.archlinux.org/cgit/aur.git/snapshot/webcamoid.tar.gz' \
    && userdel -r builduser \
    && pacman -Scc --noconfirm

ENTRYPOINT ["webcamoid"]

This is the arch-aur-install file

#!/usr/bin/env bash
URL="$1"
shift

curl -L ${URL} | tar xzf - --strip-components=1 -C $(pwd) && makepkg -si --noconfirm $@

I get also some strange errors from the logs:

QObject::connect: No such signal MediaSource::oStream(const AkPacket &)
QObject::connect: No such signal MediaSource::error(const QString &)
QObject::connect: No such signal MediaSource::maxPacketQueueSizeChanged(qint64)
QObject::connect: No such signal MediaSource::showLogChanged(bool)
QObject::connect: No such signal MediaSource::loopChanged(bool)
QObject::connect: No such signal MediaSource::mediasChanged(const QStringList &)
QObject::connect: No such signal MediaSource::mediaChanged(const QString &)
QObject::connect: No such signal MediaSource::streamsChanged(const QList<int> &)
qrc:/Webcamoid/share/qml/RecordConfig.qml:121:5: QML Text: Detected anchors on an item that is managed by a layout. This is undefined behavior; use Layout.alignment instead.
qrc:/Webcamoid/share/qml/OutputConfig.qml:39:5: QML GroupBox: Binding loop detected for property "implicitWidth"
qrc:/Webcamoid/share/qml/OutputConfig.qml:39:5: QML GroupBox: Binding loop detected for property "implicitWidth"
qrc:/Webcamoid/share/qml/OutputConfig.qml:39:5: QML GroupBox: Binding loop detected for property "implicitHeight"
qrc:/Webcamoid/share/qml/OutputConfig.qml:39:5: QML GroupBox: Binding loop detected for property "implicitHeight"
qrc:/Webcamoid/share/qml/OutputConfig.qml:39:5: QML GroupBox: Binding loop detected for property "implicitWidth"
VideoCapture: Can't set format: "MJPG"
Object 0x5623df8294a0 destroyed while one of its QML signal handlers is in progress.
Most likely the object was deleted synchronously (use QObject::deleteLater() instead), or the application is running a nested event loop.
This behavior is NOT supported!
qrc:/Webcamoid/share/qml/OutputConfig.qml:33: function() { [code] }

There exists different webcamoid packages.

mviereck commented 6 years ago

I've tried your Dockerfile, but the build fails. (I've added missing gcc package and removed nvidia related packages). After several warning of type:

Warning: Failed to resolve include "build/Qt5.11.1/gcc/release/moc/moc_predefs.h" for moc file src/akqml.h

it fails with error message:

moc acapsconvert.h
acapsconvert.h:28: Error: Undefined interface
make[4]: *** [Makefile:372: build/Qt5.11.1/gcc/release/moc/moc_acapsconvert.cpp] Error 1
make[4]: Leaving directory '/home/builduser/tmp/src/webcamoid-8.1.0/libAvKys/Plugins/ACapsConvert/src'
make[3]: *** [Makefile:45: sub-src-make_first-ordered] Error 2
make[3]: Leaving directory '/home/builduser/tmp/src/webcamoid-8.1.0/libAvKys/Plugins/ACapsConvert'
make[2]: *** [Makefile:104: sub-ACapsConvert-make_first-ordered] Error 2
make[2]: Leaving directory '/home/builduser/tmp/src/webcamoid-8.1.0/libAvKys/Plugins'
make[1]: *** [Makefile:133: sub-Plugins-make_first-ordered] Error 2
make[1]: Leaving directory '/home/builduser/tmp/src/webcamoid-8.1.0/libAvKys'
make: *** [Makefile:46: sub-libAvKys-make_first-ordered] Error 2
==> ERROR: A failure occurred in build().
    Aborting...
mviereck commented 6 years ago

This arch based guvcview image works. It also needs option --alsa:

FROM base/archlinux:2018.08.01

RUN pacman-key --init \
    && pacman -Sy --noconfirm archlinux-keyring \
    && pacman -Syu --noconfirm ibus pulseaudio pulseaudio-alsa ttf-dejavu ttf-freefont ttf-bitstream-vera ttf-liberation noto-fonts kbd coreutils fakeroot binutils

RUN echo LANG=en_US.UTF-8 > /etc/locale.conf \
    && sed -i "s/#de_DE/de_DE/g" /etc/locale.gen \
    && sed -i "s/#en_US.UTF/en_US.UTF/g" /etc/locale.gen \
    && locale-gen \
    && echo KEYMAP=de-latin1 > /etc/vconsole.conf \
    && echo FONT=lat9w-16 >> /etc/vconsole.conf

RUN pacman -Sy --noconfirm mesa-demos ocl-icd

RUN pacman -Sy --noconfirm guvcview
CMD guvcview
sandrokeil commented 6 years ago

Interesting, guvcview works out of the box with my arch nvidia image. I use x11docker --hostdisplay --silent --stderr --stdout --gpu --pulseaudio -- --device=/dev/video0 --runtime=nvidia -- sandrokeil/archlinux-nvidia:guvcview. Sound and video is recorded.

Do you have also a /dev/video1 device if you plugin your USB webcam? But sharing of this is not required. Does your webcam work in a browser like chromium if you share the device?

mviereck commented 6 years ago

Interesting, guvcview works out of the box with my arch nvidia image.

Glad to hear that. :-)

Does it fail without nvidia driver in image? I would assume that it works with software rendering of free MESA if you don't use --gpu. (Aside from that, are you aware that x11docker can install nvidia driver from host on the fly in running containers?)

Strange that you succeed with --pulseaudio, it fails here, guvcview crashes. Only --alsa works.

Do you have also a /dev/video1 device if you plugin your USB webcam?

I have /dev/video1, but no second webcam. Not sure what this is. In fact, I've never used my build-in webcam before, this thread was the first impulse to try it.

Does your webcam work in a browser like chromium if you share the device?

Would need to test it - how do I use the webcam in chromium or firefox?

mviereck commented 6 years ago

I've added a new option --webcam.

Aside from that, I did some deep changes in the code to improve handling of environment variables, shared volumes and capabilities. I hope it does not break anything.

sandrokeil commented 6 years ago

Does it fail without nvidia driver in image?

Yes, maybe some dependencies are missing. Yes, I'm aware of auto installing NVIDIA drivers. But I use many Docker images and a base image ensures same driver versions on host/container.

Strange that you succeed with --pulseaudio, it fails here, guvcview crashes

I've got some alsa errors, but I guess it's not needed because the webcam records audio/video? I can not confirm that I have audio output.

I have /dev/video1, but no second webcam. Not sure what this is.

Same here, it appears (video0 and video1) if I connect my webcam via USB.

Would need to test it - how do I use the webcam in chromium or firefox?

You can open a free video conference here appear.in/x11docker. The browser should ask to get access to the webcam/microphone. If it works, you should see you :D

sandrokeil commented 6 years ago

I've added a new option --webcam. Aside from that, I did some deep changes in the code to improve handling of environment variables, shared volumes and capabilities. I hope it does not break anything.

No worries, I will open an issue. :D

mviereck commented 6 years ago

If it works, you should see you :D

ok, I can see myself in containered firefox ;-)

sandrokeil commented 6 years ago

Awesome :+1: It works for me in browser too, sometimes. Connection to webcam can not be always initialized. This is weird. I will investigate it further, but it looks like sharing --device=/dev/video0 is enough.

mviereck commented 6 years ago

Connection to webcam can not be always initialized. This is weird.

I have similar issues with --alsa. Only one application at a time can access sound hardware, others are blocked. Is it possible that another application accesses /dev/video0?

it looks like sharing --device=/dev/video0 is enough.

Option --webcam shares all /dev/video*.

I did some further trials with cheese, providing lspci, lsusb, --systemd, --dbus in container, but it fails. No idea what is missing.

mviereck commented 6 years ago

I got cheese to work! But with an unreasonable effort:

sandrokeil commented 6 years ago

Cheese is something special, it hangs if I use systemd with the additional packages. But it works now in my browser. It looks like, that if something crashes or does not release the webcam correctly, it does not work until replug / reboot.

Thank you for the --webcam flag. :+1:

mviereck commented 6 years ago

Cheese is something special, it hangs if I use systemd with the additional packages.

I did a fix for --systemd, it starts much faster now. Cheese should not hang anymore.

It looks like, that if something crashes or does not release the webcam correctly, it does not work until replug / reboot.

Do you think it is not released especially by applications in x11docker, or may it be a general issue on your system?

Thank you for the --webcam flag. +1

You are welcome. :-) Thanks for asking for it, it is a nice feature. I never thought of it because I don't use a webcam myself.

Two new shortcut options in last update, you may find them useful, too:

mviereck commented 5 years ago

Good news! cheese now runs without a privileged setup.

I found in #86 that cheese and gnome-ring need access to /run/udev/data. I've updated the --webcam option accordingly. (Additionally they need --systemd for other reasons).