Running pulseaudio inside docker container to record system audio - docker

I'm trying to set up a Docker container with Selenium that takes a recording of the browser with system audio using ffmpeg. I've got video working using Xvfb. Unfortunately, on the audio side, it seems to be more tricky.
I thought I would set up a virtual pulseaudio sink inside the container, which would allow me to record its monitor:
pacmd load-module module-null-sink sink_name=loopback
pacmd set-default-sink loopback
ffmpeg -f pulse -i loopback.monitor test.wav
This works on my host operating system, but when trying to start the pulseaudio daemon in a container, it fails with the following message:
E: [pulseaudio] module-console-kit.c: Unable to contact D-Bus system bus: org.freedesktop.DBus.Error.FileNotFound: Failed to connect to socket /var/run/dbus/system_bus_socket: No such file or directory
This would seem to be related to a freedesktop service called dbus. I've tried installing it and starting its daemon, but I couldn't seem to get it to work properly.
I couldn't find much information on how to proceed from here. What am I missing for pulseaudio? Perhaps there's an easier way to record the system audio inside a container?
My goal is not to record it from the host operating system, but to play the audio inside the browser and record it all inside the same container.

Following solution from here helped me.
Run following commands as root prior to starting PulseAudio:
mkdir -p /var/run/dbus
dbus-uuidgen > /var/lib/dbus/machine-id
dbus-daemon --config-file=/usr/share/dbus-1/system.conf --print-address

Related

How can I use an ueye camera from IDS with ROS through a docker?

I have a docker container containing ubuntu 20.04 and ROS Noetic and I'm trying to control a Ueye camera from IDS with it. For this, I downloaded the ueye_cam package for ROS:
http://wiki.ros.org/ueye_cam
and the image_pipeline package:
http://wiki.ros.org/image_pipeline
I also downloaded the package corresponding to my camera on the IDS website and followed the tutorial for the installation:
https://www.thorlabs.com/software/THO/ThorCam/Linux/Readme_uEye_Linux_4.90.06.html
When I try to run $ roslaunch ueye_cam rgb8.launch
I get the following error message:
[ERROR] [1626351965.262425900]: No UEye cameras are connected
[ERROR] [1626351965.262560700]: Hint: make sure that the IDS camera daemon (/etc/init.d/ueyeusbdrc) is running
[ERROR] [1626351965.262743000]: Failed to initialize [camera]
I ran:
$ /usr/bin/ueyeusbd start
and got :
IDS ueyeusbd 4.94.1557 64bit build Apr 30 2021 08:04:32 ( cmdl cap scq )
and ran :
$ /etc/init.d/ueyeusbdrc start
and got the error:
Starting ueyeusbd... IDS ueyeusbd 4.94.1557 64bit build Apr 30 2021 08:04:32 ( cmdl cap scq )
ueyeusbd is not running.
I tried following this solution:
How can I run a service inside a docker container to get feed from a IDS uEye camera using gstreamer?
but it doesn't work because I don't have /var on my windows host.
I also tried:
systemctl start ueyeusbdrc
but I got this error:
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down
Does anyone know if it is possible to control an ueye camera from IDS, connected to a windows host, through a docker containing ROS1?
If not, do you know if it is possible to control an ueye camera with a ROS2 package because I already have the corresponding ROS2 drivers?
The Solution that did work for me is the following
Add a few options to the docker command.
Adding these arguments to the docker command solved the issue:
...
--privileged -v /dev/bus/usb:/dev/bus/usb
--ipc=host
--pid=host
-v /var/run:/var/run
-v /usr:/usr
...
The other key part is to install the IDS software on the host machine.
and make sure the system service for the IDS uEye camera is running in the host
(sudo systemctl start ueyeusbdrc)
and enable the docker feature via the IDS-manager software on the host
Part of the solution was inspired from this post
How can I run a service inside a docker container to get feed from a IDS uEye camera using gstreamer?
Hope this will help
Btw tested this solution only with ROS(1)

How can I run a service inside a docker container to get feed from a IDS uEye camera using gstreamer?

I have a docker container that uses a gstreamer plugin to capture the input of a camera. It runs fine with a Bastler camera but now I need to use an IDS uEye camera. To be able to use this camera I need to have the ueyeusbdrc service running. The IDS documentation says that to start it I can run sudo systemctl start ueyeusbdrc or sudo /etc/init.d/ueyeusbdrc start. The problem is that when the docker container runs, that service is not running and I get a Failed to initialize camera error, which is the same error I get if I run gst-launch-1.0 -v idsueyesrc ! videoconvert ! autovideosink and the ueyeusbdrc service is not running outside the container in my PC. So this tells me that the issue is that the ueyeusbdrc service is not running inside the container.
How can I run the ueyeusbdrc inside the docker container? I tried to run /etc/init.d/ueyeusbdrc start in the .sh script that launches the application (which is called using ENTRYPOINT ["<.sh file>"] in the Dockerfile), but it fails. Also if I try to use sudo, it tells me that the command doesn't exist. If I run systemctl it also tells me the command doesn't exist. BTW, I am running the docker with privileged: true (at least that's what is set in the docker-compose.yml file).
I am using Ubuntu 18.04.
Update:
I mapped /run/ueyed and /var/run/ueyed to the container and that changed the error from Failed to initialize camera to Failed to initialize video capture. It may be that I can run the daemon in the host and there is a way to hook it to the container. Any suggestions on how to do that?
Finally got this working. I had to add a few options to the docker command (in my case to the docker-compose yml file). I based my solution on the settings found here: https://github.com/chalmers-revere/opendlv-device-camera-ueye
Adding these arguments to the docker command solved the issue: --ipc=host --pid=host -v /var/run:/var/run. With these options there is no need to run the service inside the container.
The other key part is to install the IDS software inside the docker container. This can be easily done by downloading, extracting and running the installer (the git repo mentioned above has an outdated version, but the most recent version can be found in the IDS web page).
Also, make sure the system service for the IDS uEye camera is running in the host (sudo systemctl start ueyeusbdrc).

Gstreamer Camera Usage within Docker Containers

I'm currently working on running DL algorithms inside docker containers and I've been successful. However, I can only get it running by passing --net=host flag to docker run command which makes container use host computer's network interface. If I don't pass that flag it throws the following error:
No EGL Display
nvbufsurftransform: Could not get EGL display connection
No protocol specified
nvbuf_utils: Could not get EGL display connection
When I do
echo $DISPLAY
it outputs :0 which is correct.
But I don't understand what Gstreamer, X11 or EGL has to do with full network feature. Is there any explanation for this or any workaround except --net=host flag? Because of this reason I can't map different ports for various containers.
I also have created a topic on this on NVIDIA DevTalk Forum but it still is a dark spot for me. I didn't satisfied with the answers I got.
But it is OK to use --net=host flag to solve this problem anyways.
Quick heads up: Gstreamer is not working over X11-Forwarding natively, you better have to use VNC solution, or have access to the physical machine.
Troubleshooting
is gstreamer installed? apt install -y gstreamer1.0-plugins-base
what does xrandr returns?
what does xauth list returns?
what does gst-launch-1.0 nvarguscamerasrc ! nvoverlaysink returns?
For example:
On my setup because I do not use a dockerfile I copy the xauth list cookie then paste it in docker
xauth add user/unix:11 MIT-MAGIC-COOKIE cccccccccccccccccccccccccc
After this I can test display with xterm&.
Besides, once this is done I have an output with xrandr
Getting more verbose
Also I connect to the docker by an ssh connection with verbose (to host / or / guest we don't care) ssh -X -v user#192.168.123.123
therefore the EGL error is wrapped by debug details.
stream stuff
This is related to Deepstream and Gstreamer customization from nVidia.
Some nvidia threads point that EGL needs a "sink" but no X11 display.
If there is some server running on the host at a designed port, running docker with --net=host will allow a client to connect within the docker.
According to the the doc, there are some servers used by the Gpu.
Doc
$DISPLAY
According to nVidia threads: unset DISPLAY provides better results.
On my setup, without display, the EGL error is gone. Then the stream cannot be seen.

Unable to connect to docker hub from China

I'm getting the same thing every time trying to run busybox either with docker on fedora 20 or running boot2docker in VirtualBox:
[me#localhost ~]$ docker run -it busybox Unable to find image
'busybox:latest' locally Pulling repository busybox FATA[0105] Get
https://index.docker.io/v1/repositories/library/busybox/images: read
tcp 162.242.195.84:443: i/o timeout
I can open https://index.docker.io/v1/repositories/library/busybox/images in a browser and sometimes without using a vpn tunnel so tried to set a proxy in the network settings to the proxy provided by Astrill when using VPN sharing but it will always time out.
Currently in China where there basically is no Internet due to the firewall, npm, git and wget seem to use the Astrill proxy in the terminal (when setting it in network setting of Fedora 20) but somehow I either can't get the docker daemon to use it or something else is wrong.
It seems the answer was not so complicated according to the following documentation (had read it before but thought setting proxy in network settings ui would take care of it)
So added the following to /etc/systemd/system/docker.service.d/http-proxy.conf (after creating the docker.service.d directory and conf file):
[Service]
Environment="HTTP_PROXY=http://localhost:3213/"
Environment="HTTPS_PROXY=http://localhost:3213/"
In the Astrill app (I'm sure other provider application provide something similar) there is an option for vpn sharing which will create a proxy; it can be found under settings => vpn sharing.
For git, npm and wget setting the proxy in the ui (gnome-control-center => Network => network proxy) is enough but when doing a sudo it's better to do a sudo su, set the env and then run the command needing a proxy, for example:
sudo su
export http_proxy=http://localhost:3213/
export ftp_proxy=http://localhost:3213/
export all_proxy=socks://localhost:3213/
export https_proxy=http://localhost:3213/
export no_proxy=localhost,127.0.0.0/8,::1
export NO_PROXY="/var/run/docker.sock"
npm install -g ...
I'd like to update the solution for people who still encounter this issue today
I don't know the details, but when using the wireguard protocol on Astrill, docker build and docker run will use the VPN. If for some reason it doesn't work, try restarting the docker service sudo service docker restart while the VPN is active
Hope it helps, I just wasted one hour trying to figure out why it stopped working

Running ffmpeg from a windows service on same machine encounters permissions issue

I had been running a Windows Service, form my machine (which has full read/write access to a network drive).
The command for ffmpeg was something like this:
-i \filestore\test.avi -b 500000 -s 640x360 -ar 22050 -copyts -y -vcodec libx264 -acodec ac3 -y \filestore\mp4\test.mp4
Running it from cmd works perfectly. Running it from a windows service, from the same machine, would yield a File Not found type error. Updating to the latest ffmpeg stable changed that to "Permission denied".
I am running the service it as 'Local Account'. I was intending to run this on another server, so I need to get a grip on this!
Does running a service on your machine run as a different user to you when you choose 'Local Account'?
Assuming that ffmpeg running from Windows Service needs to access files on a network server, you need to be sure that the service user account has sufficient network permissions.
If both computers are in the same Windows domain, then you can run the services under a domain account and add permissions to access the network share from this account.
Alternatively, you can allow Everyone to access the network share and edit Local Security Policy to enable Network Access: Let Everyone permissions apply to anonymous users.

Resources