如何从主机上的Chromium和docker容器中的Chromium共享来自/ dev/videoX设备的WebRTC流

zab*_*mba 21 chromium webrtc docker ubuntu-14.04 dockerfile

环境

  • 主机运行Ubuntu 14.04.5 LTS
  • Docker版本17.09.0-ce,构建afdb6d4
  • 铬62.0.3202.89
  • 2个摄像头:/dev/video0,/dev/video1

相机

# 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
Run Code Online (Sandbox Code Playgroud)

我需要将Ubuntu 14.04 主机上的网络摄像头共享到Ubuntu 16.04 docker容器,并且能够getUserMedia从主机和容器上运行的每个铬实例上的每个摄像头或两个独立的docker容器上获取视频流(WebRTC ).

为了测试getUserMedia,我正在浏览


如何重现

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/"]
Run Code Online (Sandbox Code Playgroud)

码头工人组成

$ 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
Run Code Online (Sandbox Code Playgroud)

额外尝试

command: ["https://appear.in/hello"]
Run Code Online (Sandbox Code Playgroud)

command: ["https://test.webrtc.org/"]
Run Code Online (Sandbox Code Playgroud)

导致同样的事情,一旦一个凸轮开始流动,另一个不能

在docker容器中启动Chromium

export DISPLAY=:0.0 
docker-compose up
Run Code Online (Sandbox Code Playgroud)

结果

使用https://webrtc.github.io/samples/src/content/getusermedia/gum/ => FAILS

https://webrtc.github.io/samples/src/content/getusermedia/gum/失败:(

如果我关闭chromium_video1,则chromium_video0在浏览器刷新后流式传输视频(?).

getUserMedia从Web控制台尝试:

 navigator.mediaDevices.getUserMedia({audio: true, video: true})
Run Code Online (Sandbox Code Playgroud)

GUM Not Readable错误

但在关闭铬流后/dev/video1,现在/dev/video0是可读的.该getUserMedia命令解析,摄像机从中传输视频/dev/video0

关闭流式Chromium后,GUM解决了

口香糖解决了

他们没有访问同一设备.我签到了chrome://media-internals

铬://媒体内部

使用https://www.onlinemictest.com/webcam-test/ WORKS !!!!!?!?!?!

当使用https://www.onlinemictest.com/webcam-test/时,它可以工作,我们可以看到两个摄像头的流.我相信特定网站仍在使用URL.createObjectURL.

https://www.onlinemictest.com/webcam-test/ WORKS ?!

图片

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
Run Code Online (Sandbox Code Playgroud)

将Chromium浏览器打开到主机上的相同URL

:(我收到错误消息

NotReadableError

有关如何配置我的docker容器以允许将一个cam分配给主机而另一个专用于docker容器的任何指针?

有趣的线程

  • NotReadableError:无法分配可能发生这种情况的视频源点,因为相机已被其他应用程序使用.

  • 有趣的是,当我在主机上打开2个Chromium实例(这次没有容器)指向相同的相机测试页面(getUserMedia)时,它确实设法将相同的视频流传送到2个Chromium实例.那是我尝试从容器中访问它冲突的时候.它可以播放一个或另一个,但不能同时播放.所以它可能是在docker容器上配置的东西.仍然,要明白为什么会这样.

UPDATE

码头日志

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
Run Code Online (Sandbox Code Playgroud)

解决了这个读这个帖子的问题

试图devices按照以下评论中的建议分享,但无济于事

- /dev/video1:/dev/video1:rm 
- /dev/video1:/dev/video1:r  
- /dev/video1:/dev/video1:rw
Run Code Online (Sandbox Code Playgroud)

问题

  • 当摄像头被访问并开始流式传输时会发生什么?有没有创建锁文件在哪里?但请注意,我没有访问相同的相机.

在我分享的卷部分

- /tmp/.X11-unix:/tmp/.X11-unix
- ~/.Xauthority:/.Xauthority:ro
- /var/run/dbus/system_bus_socket:/var/run/dbus/system_bus_socket
Run Code Online (Sandbox Code Playgroud)

我不认为这些文件是问题,但仍在调查中

dag*_*elf 1

如果您只想单独的 Chrome 会话,您可以简单地启动它:

chromium-browser --user-data-dir=/tmp/chrome1 
Run Code Online (Sandbox Code Playgroud)

另一个例子是

chromium-browser --user-data-dir=/tmp/chrome2
Run Code Online (Sandbox Code Playgroud)

Docker 只是一种记录和重复设置特定环境的方法。它添加的额外安全层最少,尤其是您传递的额外权限,尤其是与 Chrome 经过严格测试的安全性相比。

如果您需要更多隔离,您可以创建单独的用户:

 # run these lines individualy, just press Enter for everything, don't set passwords for them, they won't be able to log in. 
 sudo adduser chrome1
 sudo adduser chrome2 

 # if you want to give each access to only one of the cams you can try this
 sudo chown chrome1:chrome1 /dev/video0 
 sudo chown chrome2:chrome2 /dev/video1
 # keeping in mind unplugging and replugging the camera might reset the permissions unless you update the relevant /etc files

 # to allow anyone to use your X
 xhost +

 # run the two separate browsers
 sudo su - chrome1 -c chromium-browser & 
 sudo su - chrome2 -c chromium-browser &
Run Code Online (Sandbox Code Playgroud)