bluenviron / mediamtx

Ready-to-use SRT / WebRTC / RTSP / RTMP / LL-HLS media server and media proxy that allows to read, publish, proxy, record and playback video and audio streams.
MIT License
12.09k stars 1.52k forks source link

Allow to use the Raspberry Pi Camera with Docker #1110

Closed aler9 closed 1 year ago

aler9 commented 2 years ago

Describe the feature

TODO:

cedricve commented 2 years ago

I guess a combo for both could also be possible. Currently we have a work around as described here: https://github.com/kerberos-io/camera-to-rtsp. But having a single Docker container would be much more elegant.

  1. Compile libcamera in the existing dockerfile
  2. Inject /dev/video* into the container
olokos commented 2 years ago

In terms of what is really required to be able to access the Pi camera natively there are 2 things needed:

https://libcamera.org/ -- The core libcamera, which is the main interface between kernel and the OS, enabling communication -- this is not related to any specific camera and also doesn't provide any of the libcamera commands that you might know, since it's a separate team from the Raspberry foundation. The main commands for core libcamera are qcam - test suite for the camera and libcamerasrc which is mostly an output sink for gstreamer and such.

https://github.com/raspberrypi/libcamera-apps - The "apps" for Raspicam, this project is developed by Raspberry foundation and it does in fact contain Raspberry-specific camera code and does provide libcamera-vid / libcamera-still. It's not as low level as libcamera. It's not just a wrapper for libcamera, but it's really really close, especially as libcamera-apps REQUIRE libcamera installed fronm source already or downloading libcamera-dev or similarly named packaged, in order to build itself. It's impossible to compile libcamera-apps (in order to get libcamera-vid/still) without first installing libcamera. Installing libcamera without libcamera-apps will not provide libcamera-vid nor libcamera-still, as those 2 commands are device-specific.

Just leaving this here, as it's not so obvious and it took me some time to get this knowledge, it might be helpful in the future.

kbingham commented 2 years ago

I guess a combo for both could also be possible. Currently we have a work around as described here: https://github.com/kerberos-io/camera-to-rtsp. But having a single Docker container would be much more elegant.

1. Compile libcamera in the existing dockerfile

This will be better than trying to map libraries in from the host. You would have to make sure the host libraries and the container libraries are compatible.

2. Inject /dev/video* into the container

You need /dev/media and /dev/v4l-subdev too.

aler9 commented 1 year ago

Accessing the camera when running the server inside Docker is now fully supported, please take a look at the README in order to use this feature: https://github.com/aler9/rtsp-simple-server#from-a-raspberry-pi-camera

cedricve commented 1 year ago

This is aweeeesomeeee!!!! Going to try this out. Well done @aler9 !!

aler9 commented 1 year ago

from the release notes:

please upgrade libcamera by running apt update && apt upgrade before using this version

cedricve commented 1 year ago

Tried out but got this error, will try again with a blank installation (updated an upgraded)

    root@kerberos:/home/pi# docker run --rm -it --network=host --privileged --tmpfs /dev/shm:exec -v /usr:/usr:ro -v /lib:/lib:ro -v /run/udev:/run/udev:ro -e RTSP_PATHS_CAM_SOURCE=rpiCamera aler9/rtsp-simple-server
    2022/11/04 07:45:20 INF rtsp-simple-server v0.20.2
    2022/11/04 07:45:20 INF [path cam] [rpicamera source] started
    2022/11/04 07:45:20 INF [RTSP] listener opened on :8554 (TCP), :8000 (UDP/RTP), :8001 (UDP/RTCP)
    2022/11/04 07:45:20 INF [RTMP] listener opened on :1935
    /dev/shm/rtspss-embeddedexe-1667547920063415273: error while loading shared libraries: libcamera.so.0.0.1: cannot open shared object file: No such file or directory
    2022/11/04 07:45:20 INF [HLS] listener opened on :8888
    2022/11/04 07:45:20 INF [path cam] [rpicamera source] ERR: process exited unexpectedly
    /dev/shm/rtspss-embeddedexe-1667547925074344869: error while loading shared libraries: libcamera.so.0.0.1: cannot open shared object file: No such file or directory
    2022/11/04 07:45:25 INF [path cam] [rpicamera source] ERR: process exited unexpectedly
    ^C2022/11/04 07:45:25 INF shutting down gracefully
    2022/11/04 07:45:25 INF [path cam] [rpicamera source] stopped
    2022/11/04 07:45:25 INF [RTSP] listener is closing
    2022/11/04 07:45:25 INF [HLS] listener is closing
    2022/11/04 07:45:25 INF [RTMP] listener is closing
    2022/11/04 07:45:25 INF waiting for external commands
cedricve commented 1 year ago

After doing an upgrade, it works like a charm. It's recommended to do a clean install of raspbian.

    root@kerberos:/home/pi# docker run --rm -it --network=host --privileged --tmpfs /dev/shm:exec -v /usr:/usr:ro -v /lib:/lib:ro -v /run/udev:/run/udev:ro -e RTSP_PATHS_CAM_SOURCE=rpiCamera -e RTSP_PATHS_CAM_RPICAMERAVFLIP=true -d --restart-always aler9/rtsp-simple-server

Returns following output

    2022/11/04 08:14:45 INF rtsp-simple-server v0.20.2
    2022/11/04 08:14:45 INF [path cam] [rpicamera source] started
    2022/11/04 08:14:45 INF [RTSP] listener opened on :8554 (TCP), :8000 (UDP/RTP), :8001 (UDP/RTCP)
    2022/11/04 08:14:45 INF [RTMP] listener opened on :1935
    2022/11/04 08:14:45 INF [HLS] listener opened on :8888
    [0:04:37.105280125] [14]  INFO Camera camera_manager.cpp:293 libcamera v0.0.1+21-7c855784
    [0:04:37.221490659] [17]  INFO RPI raspberrypi.cpp:1414 Registered camera /base/soc/i2c0mux/i2c@1/ov5647@36 to Unicam device /dev/media3 and ISP device /dev/media0
    [0:04:37.225045487] [14]  INFO Camera camera.cpp:1026 configuring streams: (0) 1920x1080-YUV420
    [0:04:37.227222996] [17]  INFO RPI raspberrypi.cpp:800 Sensor: /base/soc/i2c0mux/i2c@1/ov5647@36 - Selected sensor format: 1920x1080-SRGGB10_1X10 - Selected unicam format: 1920x1080-pRAA
    2022/11/04 08:14:46 INF [path cam] [rpicamera source] ready: 1 track (H264)
    2022/11/04 08:14:50 INF [RTSP] [conn 192.168.1.12:54963] opened
    2022/11/04 08:14:50 INF [RTSP] [session 540803280] created by 192.168.1.12:54963
    2022/11/04 08:14:50 INF [RTSP] [session 540803280] is reading from path 'cam', with UDP, 1 track (H264)
    2022/11/04 08:15:04 INF [RTSP] [session 540803280] destroyed (teared down by 192.168.1.12:54963)
    2022/11/04 08:15:04 INF [RTSP] [conn 192.168.1.12:54963] closed (EOF)
    ^C2022/11/04 08:15:05 INF shutting down gracefully
    2022/11/04 08:15:05 INF [path cam] [rpicamera source] stopped
    2022/11/04 08:15:05 INF [RTSP] listener is closing
    2022/11/04 08:15:05 INF [HLS] listener is closing
    2022/11/04 08:15:05 INF [RTMP] listener is closing
    2022/11/04 08:15:05 INF waiting for external commands
cedricve commented 1 year ago

Thanks man works like a charm with the https://github.com/kerberos-io/agent project!

Screenshot 2022-11-04 at 09 26 29

cedricve commented 1 year ago

@aler9 I'm working on building a fully supported container, without the need for injecting host resources. As services such as Balena don't allow to make bindings. Any thoughts on what should be done extra?

aler9 commented 1 year ago

@cedricve the issue here is that i don't know whether libcamera runs entirely in the user space (and in this case, it's possible to ship it inside a container and remove the injection of host resources) or if it has components that run in kernel space - in the latter case, it's impossible to containerize it since there would be a missing part.

kbingham commented 1 year ago

libcamera is fully userspace, but it uses kernel devices, and interacts with the kernel interfaces. It requires access to /dev/media /dev/video /dev/v4l-subdev* as a minimum.

It also expects to be able to receive udev events. Or alternatively, it needs access to /sys/dev/

And finally, to be able to handle memory allocations, I believe it needs /dev/dma_heap/*

aler9 commented 1 year ago

@kbingham thanks for clarifying this, i added some additional Docker images that include both the server and libcamera, and i tested them in different enviroments:

Everything works and there's no need to inject host libraries anymore.

The new images are

aler9/rtsp-simple-server:latest-arm64-rpi
aler9/rtsp-simple-server:latest-arm64-rpi
aler9/rtsp-simple-server:latest-arm64-rpi

The current suggested way to run server inside Docker on a Raspberry Pi is:

docker run --rm -it \
--network=host \
--privileged \
--tmpfs /dev/shm:exec \
-v /run/udev:/run/udev:ro \
-e RTSP_PATHS_CAM_SOURCE=rpiCamera \
aler9/rtsp-simple-server:latest-arm64-rpi
github-actions[bot] commented 1 year ago

This issue is being locked automatically because it has been closed for more than 6 months. Please open a new issue in case you encounter a similar problem.