elberth
elberth

Reputation: 191

Access camera inside docker container

I'm not sure that this is even possible, but is there a way to access my camera inside docker container? I'm not using external camera but built-in in my mac.

Upvotes: 19

Views: 37952

Answers (3)

Auzias
Auzias

Reputation: 3798

I'm not sure that the flag volume (-v) is the best practice to do so.

According to the github of jfrazelle, docker engineer who wrote many Dockerfile and docker run for many graphical app such as chromium, skype, spotify, and so on, the flag and argument you should use is --device /dev/video0.

For quick test(tested on ubuntu), below code should give supported frame resolution of cameras:-

docker run --rm -it --entrypoint /bin/bash --device /dev/video0 jrottenberg/ffmpeg
ffmpeg -f video4linux2 -list_formats all -i /dev/video0

Upvotes: 26

Louis GRIGNON
Louis GRIGNON

Reputation: 729

On MacOS, it can be a bit tricky:

  1. Install legacy docker virtualization engine for Docker Desktop on Mac (which uses Oracle Virtual Box)

    • Install Virtual Box
    • Install Virtual Box Extension pack
    • Install Docker Toolbox (reading this is strongly recommended & backuping your /usr/local/bin/docker* before is also recommended)
      • Ensure that /usr/local/bin/docker and /usr/local/bin/docker-compose link to Docker Desktop binaries (/Applications/Docker.app/Contents/Resources), and not Docker Toolbox
      • Test everything is still working: docker ps -a and docker images should display what you already had in Docker Desktop, docker-machine ls should not raise an error
  2. brew install socat

  3. brew install xquartz

  4. Setting: XQuartz Preferences > Security > check allow all (Allow connections from network clients)

  5. defaults write org.macosforge.xquartz.X11 enable_iglx -bool true

  6. IP=$(ifconfig en0 | grep inet | awk '$1=="inet" {print $2}')

  7. xhost + $IP

  8. docker-machine create -d virtualbox --virtualbox-cpu-count=4 --virtualbox-memory=4096 --virtualbox-disk-size=1000000 --virtualbox-boot2docker-url https://github.com/gzupark/boot2docker-webcam-mac/releases/download/18.06.1-ce-usb/boot2docker.iso default

  9. docker-machine stop default

  10. Open Virtual Box app & configure the VirtualBox VM that has just been created with docker-machine

    1. Display > Video memory (max)
    2. Display > Acceleration > Enable 3D acceleration (check)
    3. Ports > USB > Enable USB controller (check) > USB 2.0 (select)
    4. Shared folders > Add > Folder Path = / & Folder name = host-root
  11. Reboot macOS

  12. Open a terminal (T1), and type

    1. open -a XQuartz
    2. If it does not open another terminal, focus XQuartz app, and Applications > Terminal
    3. Now a new terminal is opened (T2)
    4. On T2: socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:\"$DISPLAY\"
      • if it complains about "Address already in use", check with lsof -i tcp:6000 that owning process is X11.bin, otherwise kill owning process and try running socat again (always on T2)
  13. On T1 again

    • IP=$(ifconfig en0 | grep inet | awk '$1=="inet" {print $2}')
    • xhost + $IP
    • docker-machine start default
    • eval $(docker-machine env default)
    • vboxmanage list webcams
      • Identify in the list your webcam (eg mine was .1)
    • vboxmanage controlvm default webcam attach .1
  14. (You may need to open VirtualBox again, double click on your VM, which will open a view of your system, and then Devices > Webcam > <select your camera>)

You should now be able to access your camera in a container.

Test XQuartz with

docker run --rm -it -e DISPLAY=$IP:0 gns3/xeyes

Test camera with

docker run --rm -it -e DISPLAY=$IP:0 --device=/dev/video0:/dev/video0 -v /tmp/.X11-unix:/tmp/.X11-unix ubuntu
apt update && apt install -y streamer
streamer -f jpeg -o image.jpeg

Tip

Shutdown your greedy VM process with: VBoxManage controlvm thevm acpipowerbutton

Big thanks to:

Additional notes:

Upvotes: 1

Hardik Juneja
Hardik Juneja

Reputation: 387

You can try to forward your webcam device using -v flag

Something like

sudo docker run -d -p 55555:22 --privileged -v /dev/video0:/dev/video0 testimage

To list all devices attached to USB use lsusb ; to list all devices attached to PCI use lspci

Upvotes: 2

Related Questions