title: How to share & WebRTC stream from /dev/videoX device from a Chromium on host and Chromium in a docker container
body: <h1>Environment</h1>
  
  <ul>
  <li>Host running Ubuntu 14.04.5 LTS</li>
  <li>Docker version 17.09.0-ce, build afdb6d4</li>
  <li>Chromium 62.0.3202.89</li>
  <li>2 webcams: <code>/dev/video0</code>, <code>/dev/video1</code></li>
  </ul>
  
  <h2>Cameras</h2>
  
  <pre><code># 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
  </code></pre>
  
  <p>I need to share the webcams on <code>Ubuntu 14.04</code> <strong>host</strong> to the <code>Ubuntu 16.04</code> <strong>docker container</strong> and be able to get the video streams (WebRTC <code>getUserMedia</code>) from each camera on each chromium instance respectively running on the host and the container or on 2 separate docker containers.</p>
  
  <p>To test the <code>getUserMedia</code>, I am browsing to </p>
  
  <ul>
  <li><a href="https://www.onlinemictest.com/webcam-test/" rel="noreferrer">https://www.onlinemictest.com/webcam-test/</a>
  and</li>
  <li><a href="https://webrtc.github.io/samples/src/content/getusermedia/gum/" rel="noreferrer">https://webrtc.github.io/samples/src/content/getusermedia/gum/</a></li>
  </ul>
  
  <hr>
  
  <h1>How to reproduce</h1>
  
  <h2>Dockerfile</h2>
  
  <pre><code>FROM ubuntu:16.04
  
  # Install chromium
  RUN apt-get update \
      &amp;&amp; apt-get install sudo chromium-browser alsa-base alsa-utils alsa-oss -y \
      &amp;&amp; rm -rf /var/lib/apt/lists/*
  
  # Create a normal user to run chromium as
  RUN useradd --create-home browser \
      &amp;&amp; adduser browser video \
      &amp;&amp; adduser browser audio \
      &amp;&amp; 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/"]
  </code></pre>
  
  <h2>docker-compose up</h2>
  
  <pre><code>$ 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
  </code></pre>
  
  <h3>Additional tries with</h3>
  
  <pre><code>command: ["https://appear.in/hello"]
  </code></pre>
  
  <p>and </p>
  
  <pre><code>command: ["https://test.webrtc.org/"]
  </code></pre>
  
  <p>leads to the same thing, once one cam starts streaming the other can't</p>
  
  <h2>Start Chromium in docker containers</h2>
  
  <pre><code>export DISPLAY=:0.0 
  docker-compose up
  </code></pre>
  
  <h3>RESULTS</h3>
  
  <h3>Using <a href="https://webrtc.github.io/samples/src/content/getusermedia/gum/" rel="noreferrer">https://webrtc.github.io/samples/src/content/getusermedia/gum/</a> => FAILS</h3>
  
  <p><a href="https://i.stack.imgur.com/C6Fdr.png" rel="noreferrer"><img src="https://i.stack.imgur.com/C6Fdr.png" alt="https://webrtc.github.io/samples/src/content/getusermedia/gum/ FAILS:("></a></p>
  
  <p>if I close <code>chromium_video1</code>, then <code>chromium_video0</code> streams video after a browser refresh (?).  </p>
  
  <p>Tried <code>getUserMedia</code> from the web console:</p>
  
  <pre><code> navigator.mediaDevices.getUserMedia({audio: true, video: true})
  </code></pre>
  
  <p><a href="https://i.stack.imgur.com/NuXLp.png" rel="noreferrer"><img src="https://i.stack.imgur.com/NuXLp.png" alt="GUM Not Readable error"></a></p>
  
  <p>but after closing chromium streaming <code>/dev/video1</code>, now <code>/dev/video0</code> is readable. The <code>getUserMedia</code> command resolves and the camera streams video from <code>/dev/video0</code></p>
  
  <p><a href="https://i.stack.imgur.com/0ywKE.png" rel="noreferrer"><img src="https://i.stack.imgur.com/0ywKE.png" alt="GUM resolved after closing the streaming Chromium"></a></p>
  
  <p><a href="https://i.stack.imgur.com/C8gPS.jpg" rel="noreferrer"><img src="https://i.stack.imgur.com/C8gPS.jpg" alt="GUM resolved"></a></p>
  
  <p>They are not accessing the same device. I checked in <code>chrome://media-internals</code></p>
  
  <p><a href="https://i.stack.imgur.com/4Bzto.png" rel="noreferrer"><img src="https://i.stack.imgur.com/4Bzto.png" alt="chrome://media-internals"></a></p>
  
  <h3>Using <a href="https://www.onlinemictest.com/webcam-test/" rel="noreferrer">https://www.onlinemictest.com/webcam-test/</a> WORKS!!!!!?!?!?!</h3>
  
  <p>When using <a href="https://www.onlinemictest.com/webcam-test/" rel="noreferrer">https://www.onlinemictest.com/webcam-test/</a> instead, it works, we can see streams for both cams. I believe that particular site is still using <code>URL.createObjectURL</code>.</p>
  
  <p><a href="https://i.stack.imgur.com/n3BYU.jpg" rel="noreferrer"><img src="https://i.stack.imgur.com/n3BYU.jpg" alt="https://www.onlinemictest.com/webcam-test/ WORKS?!"></a></p>
  
  <h3>images</h3>
  
  <pre><code>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
  </code></pre>
  
  <h3>Open a Chromium browser to the same URL on the <strong>host</strong></h3>
  
  <p>:( I get the ERROR message</p>
  
  <p><code>NotReadableError</code></p>
  
  <p>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?</p>
  
  <h1>Interesting threads</h1>
  
  <ul>
  <li><p><a href="https://stackoverflow.com/questions/42568498/notreadableerror-failed-to-allocate-videosource">NotReadableError: Failed to allocate videosource</a> points that this may be happening because the camera is used by another application.</p></li>
  <li><p>Interestingly, when I open 2 Chromium instances on the host (no container this time) pointing to the same camera test page (<code>getUserMedia</code>), 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.</p></li>
  </ul>
  
  <h1>UPDATE</h1>
  
  <h2>docker logs</h2>
  
  <pre><code>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
  </code></pre>
  
  <p>Resolved this one reading this <a href="https://stackoverflow.com/questions/42438619/run-chromium-inside-container-libgl-error">thread</a></p>
  
  <p>Tried to share <code>devices</code> as suggested in the comments below, to no avail</p>
  
  <pre><code>- /dev/video1:/dev/video1:rm 
  - /dev/video1:/dev/video1:r  
  - /dev/video1:/dev/video1:rw
  </code></pre>
  
  <h1>Questions</h1>
  
  <ul>
  <li>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.</li>
  </ul>
  
  <p>On the volumes sections I am sharing</p>
  
  <pre><code>- /tmp/.X11-unix:/tmp/.X11-unix
  - ~/.Xauthority:/.Xauthority:ro
  - /var/run/dbus/system_bus_socket:/var/run/dbus/system_bus_socket
  </code></pre>
  
  <ul>
  <li><a href="https://askubuntu.com/questions/300682/what-is-the-xauthority-file">what-is-the-xauthority-file</a></li>
  <li><a href="https://unix.stackexchange.com/questions/196677/what-is-tmp-x11-unix">what-is-tmp-x11-unix</a></li>
  </ul>
  
  <p>I don't think these files are the problem, but still investigating</p>