Environment
- Host running Ubuntu 14.04.5 LTS
- Docker version 17.09.0-ce, build afdb6d4
- Chromium 62.0.3202.89
- 2 webcams:
/dev/video0
,/dev/video1
Cameras
# v4l2-ctl --list-devices
Venus USB2.0 Camera (usb-0000:00:1a.0-1.2.2):
/dev/video1
USB 2.0 Camera (usb-0000:00:1a.0-1.3):
/dev/video0
I need to share the webcams on Ubuntu 14.04
host to the Ubuntu 16.04
docker container and be able to get the video streams (WebRTC getUserMedia
) from each camera on each chromium instance respectively running on the host and the container or on 2 separate docker containers.
To test the getUserMedia
, I am browsing to
- https://www.onlinemictest.com/webcam-test/ and
- https://webrtc.github.io/samples/src/content/getusermedia/gum/
How to reproduce
Dockerfile
FROM ubuntu:16.04
# Install chromium
RUN apt-get update \
&& apt-get install sudo chromium-browser alsa-base alsa-utils alsa-oss -y \
&& rm -rf /var/lib/apt/lists/*
# Create a normal user to run chromium as
RUN useradd --create-home browser \
&& adduser browser video \
&& adduser browser audio \
&& usermod -aG sudo browser
USER browser
WORKDIR /home/browser
ENTRYPOINT ["/usr/bin/chromium-browser", "--use-fake-ui-for-media-stream", "--disable-infobars", "--allow-running-insecure-content", "--ignore-certificate-errors"]
CMD ["https://www.stackoverflow.com/"]
docker-compose up
$ more docker-compose.yml
version: '3'
services:
chromium_video1:
build:
context: .
dockerfile: Dockerfile
image: ubuntu-cr:0.1
# privileged: true # then you don't need the devices section
# Pass the URL as an argument (CMD) to ENTRYPOINT in the Dockerfile
#command: ["https://www.onlinemictest.com/webcam-test/"] # WORKS
command: ["https://webrtc.github.io/samples/src/content/getusermedia/gum/"] # FAILS
environment:
#DISPLAY: $DISPLAY
DISPLAY:
XAUTHORITY: /.Xauthority
devices:
- /dev/video1
- /dev/dri
# - /dev/snd
volumes:
- /tmp/.X11-unix:/tmp/.X11-unix
- ~/.Xauthority:/.Xauthority:ro
- /var/run/dbus/system_bus_socket:/var/run/dbus/system_bus_socket
cap_add:
- SYS_ADMIN
chromium_video0:
build:
context: .
dockerfile: Dockerfile
image: ubuntu-cr:0.1
# privileged: true
# Pass the URL as an argument (CMD) to ENTRYPOINT in the Dockerfile
#command: ["https://www.onlinemictest.com/webcam-test/"]
command: ["https://webrtc.github.io/samples/src/content/getusermedia/gum/"]
environment:
DISPLAY:
XAUTHORITY: /.Xauthority
devices:
- /dev/video0
- /dev/dri
# - /dev/snd
volumes:
- /tmp/.X11-unix:/tmp/.X11-unix
- ~/.Xauthority:/.Xauthority:ro
- /var/run/dbus/system_bus_socket:/var/run/dbus/system_bus_socket
cap_add:
- SYS_ADMIN
Additional tries with
command: ["https://appear.in/hello"]
and
command: ["https://test.webrtc.org/"]
leads to the same thing, once one cam starts streaming the other can't
Start Chromium in docker containers
export DISPLAY=:0.0
docker-compose up
RESULTS
Using https://webrtc.github.io/samples/src/content/getusermedia/gum/ => FAILS
if I close chromium_video1
, then chromium_video0
streams video after a browser refresh (?).
Tried getUserMedia
from the web console:
navigator.mediaDevices.getUserMedia({audio: true, video: true})
but after closing chromium streaming /dev/video1
, now /dev/video0
is readable. The getUserMedia
command resolves and the camera streams video from /dev/video0
They are not accessing the same device. I checked in chrome://media-internals
Using https://www.onlinemictest.com/webcam-test/ WORKS!!!!!?!?!?!
When using https://www.onlinemictest.com/webcam-test/ instead, it works, we can see streams for both cams. I believe that particular site is still using URL.createObjectURL
.
images
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu-cr 0.1 a61f5506b1f9 9 minutes ago 764MB
ubuntu 16.04 747cb2d60bbe 2 months ago 122MB
Open a Chromium browser to the same URL on the host
:( I get the ERROR message
NotReadableError
Any pointers on how to configure my docker container to allow one cam to be assigned to the host while the other is dedicated to the docker container?
Interesting threads
NotReadableError: Failed to allocate videosource points that this may be happening because the camera is used by another application.
Interestingly, when I open 2 Chromium instances on the host (no container this time) pointing to the same camera test page (
getUserMedia
), it does manage to get the same video stream to the 2 Chromium instances. That's when I try to access from a container that it conflicts. It can play either one or the other, but not at the same time. So it could be something to configure on the docker container. Still, tring to understand why this is happening.
UPDATE
docker logs
chromium_video1 | libGL error: failed to open drm device: No such file or directory
chromium_video1 | libGL error: failed to load driver: i965
chromium_video0 | libGL error: failed to open drm device: No such file or directory
chromium_video0 | libGL error: failed to load driver: i965
Resolved this one reading this thread
Tried to share devices
as suggested in the comments below, to no avail
- /dev/video1:/dev/video1:rm
- /dev/video1:/dev/video1:r
- /dev/video1:/dev/video1:rw
Questions
- What happens when a camera gets accessed and starts streaming? is there a lock file created and where? Note however that I am not accessing the same camera.
On the volumes sections I am sharing
- /tmp/.X11-unix:/tmp/.X11-unix
- ~/.Xauthority:/.Xauthority:ro
- /var/run/dbus/system_bus_socket:/var/run/dbus/system_bus_socket
I don't think these files are the problem, but still investigating