Using StereoPi with OctoPi:How to launch 2nd MJPG-Streamer instance?

Hello, Octoprint forums! I'm unable to figure out what's the first step to initializing the second RPi camera I have into OctoPi. I do understand the problem though.

Taking it from the top, I had to figure out why the second camera was outright not detected. I ended up figuring out that OctoPi doesn't have the correct "dt-blob.bin" to recognize that there is a second camera port attached and enabled, unlike in their pre-provided image. Making a new SD card with OctoPi, adding the dt-blob.bin (overwriting the previous one), and then adding my network settings allowed me to test the output of the 2nd camera using raspivid. Success!

Now, the problem is: How do I create a second instance of MJPG-Streamer for the 2nd camera that plugs into the OctoPrint Web UI? I learned of a plugin that seems critical for this task called MultiCam that accepts camera streams by IP addresses. Using a loopback address, it's theoretically possible to simply make a secondary instance of MJPG-Streamer at a different port than the default, and then simply point MultiCam at it.

@foosel made an article describing available MJPG-Streamer configuration options (Edit: found the Github repo link for the MJPG-Streamer fork! https://github.com/jacksonliam/mjpg-streamer/) but there is no option specifying what video input device it's using, or the port the data is being sent to, which is somewhat strange. Is there a place where it assumes these parameters by default, because most Pis only have one hardware camera port?

TL;DR: How can I make a second MJPG-Streamer instance that points to the secondary Pi camera that runs on startup?

No logs yet, as there's technically no error. Short of the dt-blob.bin, the software setup is bog standard, sans Multicam, and a plugin for the MMU2S on my MK3S.

Printer: PRUSA i3 MK3S MMU2S
RPi model: Raspberry Pi Compute Module 3+ Lite (on StereoPi Carrier Board) https://stereopi.com/
Camera model: Raspberry Pi Camera v1.3 (x2)
OctoPi version: 0.17.0
OctoPrint version: 1.4.2
Einsy RAMBo version: 3.9.1 (Prusa official, fork of Marlin)
Connection established to RAMBo through RPi hardware UART port (ttyAMA0, 115200 baud rate, with 5v/GND/RX/TX pins connected from PRUSA's Pi Zero guide. GPIOs 23,24 are not plugged in)

I'm not sure he ever got it to work with octoprint directly, but used my WebcamIframe plugin to load stereopi from another pi on the network.

I appreciate the comment! Unfortunately, I'd like it to function as the OctoPi instance's brain, as the dual cameras are not for 3D imaging. Instead, I plan to implement one camera to monitor the printhead, and with the other camera I plan to attach to a robot arm inside my enclosure. I could have two Pis handle this, but I want it to be one neat package.

On topic, am I thinking of the solution in the correct manner, in terms of theoretically running two verisons of MJPG-Streamer, one for each camera, on different ports?

In theory that would work if the two cameras are addressable as separate /dev/video devices.

"ls /dev/" reveals 5 video devices. A bit unexpected, but interesting nonetheless.
Theoretically, the other camera would be video1, assuming the default camera the software uses is video0.
I noticed under the Github fork for OctoPi, I didn't see an option to specify a capture device. Unless that's specified upon launch? https://github.com/jacksonliam/mjpg-streamer
Results are:
video0
video1
video10
video11
video12

I'd try to follow this guide maybe.

I'll give it a shot tomorrow. We'll see!

I gave it my best shot, but the cloned webcamd2.service is still attempting to using /dev/video0 instead of dev/video1 as specified. Output from sudo service webcamd2.service start:
webcamd2.service - the OctoPi webcam daemon with the user specified config
Loaded: loaded (/etc/systemd/system/webcamd2.service; enabled; vendor preset: enabled)
Active: activating (start) since Mon 2020-10-05 21:29:49 EDT; 256ms ago
Cntrl PID: 12388 (webcamd2)
Tasks: 2 (limit: 2077)
Memory: 1.0M
CGroup: /system.slice/webcamd2.service
β”œβ”€12388 /bin/bash /root/bin/webcamd2
└─12410 sleep 1

Oct 05 21:29:49 Maestro mjpg_streamer[12409]: MJPG-streamer [12409]: Using V4L2 device.: /dev/video0
Oct 05 21:29:49 Maestro webcamd2[12388]: libv4l2: error setting pixformat: Device or resource busy
Oct 05 21:29:49 Maestro webcamd2[12388]: Unable to set format: 1196444237 res: 640x480
Oct 05 21:29:49 Maestro webcamd2[12388]: Init v4L2 failed !! exit fatal
Oct 05 21:29:49 Maestro webcamd2[12388]: i: init_VideoIn failed
Oct 05 21:29:49 Maestro mjpg_streamer[12409]: MJPG-streamer [12409]: Desired Resolution: 640 x 480
Oct 05 21:29:49 Maestro mjpg_streamer[12409]: MJPG-streamer [12409]: Frames Per Second.: 10
Oct 05 21:29:49 Maestro mjpg_streamer[12409]: MJPG-streamer [12409]: Format............: JPEG
Oct 05 21:29:49 Maestro mjpg_streamer[12409]: MJPG-streamer [12409]: TV-Norm...........: DEFAULT
Oct 05 21:29:49 Maestro mjpg_streamer[12409]: MJPG-streamer [12409]: init_VideoIn failed

I'm stumped. In several different places in the file, I've indicated that it should use /dev/video1 instead of /dev/video0. Can I directly attach config files to posts?

yeah, you can drag certain file types in a comment here to upload.

webcam service configs.zip (6.5 KB)

There. Webcamd2 is no longer an exact copy of Webcamd because I attempted to get it to work by specifying -d /dev/video1 in more than a couple of places. Only other change of note is that I attempted to disable /boot/octopi.txt by fully commenting it out, and by also doing the thing mentioned in the video with these files. Port number for webcamd2 was also changed to 8081.

Ideas? I didn't do that haproxy thing it mentions in the latter half of the video, but before proceeding to that step, he mentions the service should run successfully.

I did skip the very first part of the video where he renames his video devices, because I've confirmed the other camera is /dev/video1 with this very blurry, out of focus image of my wall:


My other camera is aimed at my printer, so it can't be that one.

I'd see if you could get the standard mjpgstreamer command line to function without the complexity of the service initially.

I think what you're going to struggle with is that isn't this device a raspicam connection? You might have to force USB mode to be able to supply the device in the command line.

That's the thing, I think it's already in USB mode. When calling the service to start, it defaults to 640x480 at 10 FPS; those are the options specified by default in the USB UVC lines of the webcamd config files. Additionally, calling up the status of the first camera's functioning webcamd outputs the following:

webcamd.service - the OctoPi webcam daemon with the user specified config
Loaded: loaded (/etc/systemd/system/webcamd.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2020-10-05 21:48:01 EDT; 38min ago
Process: 340 ExecStart=/root/bin/webcamd (code=exited, status=0/SUCCESS)
Main PID: 436 (mjpg_streamer)
Tasks: 4 (limit: 2077)
Memory: 2.8M
CGroup: /system.slice/webcamd.service
└─436 ./mjpg_streamer -o output_http.so -w ./www-octopi -p 8080 -i input_uvc.so -r 640x480 -f 10

Oct 05 21:48:00 Maestro webcamd[340]: o: commands.............: enabled
Oct 05 21:48:00 Maestro mjpg_streamer[436]: MJPG-streamer [436]: HTTP TCP port........: 8080
Oct 05 21:48:00 Maestro mjpg_streamer[436]: MJPG-streamer [436]: HTTP Listen Address..: (null)
Oct 05 21:48:00 Maestro mjpg_streamer[436]: MJPG-streamer [436]: username:password....: disabled
Oct 05 21:48:00 Maestro mjpg_streamer[436]: MJPG-streamer [436]: commands.............: enabled
Oct 05 21:48:00 Maestro mjpg_streamer[436]: MJPG-streamer [436]: starting input plugin input_uvc.so
Oct 05 21:48:00 Maestro mjpg_streamer[436]: MJPG-streamer [436]: starting output plugin: output_http.so (ID: 00)
Oct 05 21:48:01 Maestro webcamd[340]: Done bring up all configured video device
Oct 05 21:48:01 Maestro webcamd[340]: Goodbye...
Oct 05 21:48:01 Maestro systemd[1]: Started the OctoPi webcam daemon with the user specified config.

It explicitly says it's using input_uvc.so as the input plugin, not input_raspicam.

EDIT: Found part of the problem! Changed camera=auto to camera=raspi specifically inside of webcamd instead of through boot/octopi.txt, just in case. Restarting webcamd for the original still says it's using input_uvc.so, though. On the other hand, restarting webcamd2 with this change and asking for status yields the following:

webcamd2.service - the OctoPi webcam daemon with the user specified config
Loaded: loaded (/etc/systemd/system/webcamd2.service; enabled; vendor preset: enabled)
Active: activating (start) since Mon 2020-10-05 22:31:11 EDT; 32s ago
Cntrl PID: 1487 (webcamd2)
Tasks: 2 (limit: 2077)
Memory: 948.0K
CGroup: /system.slice/webcamd2.service
β”œβ”€1487 /bin/bash /root/bin/webcamd2
└─1502 sleep 120

Oct 05 22:31:11 Maestro webcamd2[1487]: http options: -w ./www-octopi -p 8081
Oct 05 22:31:11 Maestro webcamd2[1487]: Explicitly USB device: /dev/video1
Oct 05 22:31:11 Maestro webcamd2[1487]: -----------------------------------------------
Oct 05 22:31:11 Maestro webcamd2[1487]: Found video devices:
Oct 05 22:31:11 Maestro webcamd2[1487]: /dev/video0
Oct 05 22:31:11 Maestro webcamd2[1487]: /dev/video1
Oct 05 22:31:11 Maestro webcamd2[1487]: /dev/video10
Oct 05 22:31:11 Maestro webcamd2[1487]: /dev/video11
Oct 05 22:31:11 Maestro webcamd2[1487]: /dev/video12
Oct 05 22:31:11 Maestro webcamd2[1487]: Scan again in two minutes

It's worth noting that the SSH shell got stuck with this command and I ended up having to CRTL-C my way out. What up with this log?

Nevermind, this times out after a short period. It's almost like despite the file recognizing that I've defined /dev/video1 specifically, it refuses to select it from a list. It even displays a list with /dev/video1 as part of the list, and then it says scan again in two minutes. Why?

EDIT 2: At the very beginning of the webcamd config, there's a config_dir variable:
config_dir="/boot/octopi.conf.d"
I tried cding into this directory but it doesn't seem to exist. It doesn't seem to affect the operation of cam 1, but what now?

More news. Actually figured out that specifying camera=raspi causes this problematic log here:

webcamd2.service - the OctoPi webcam daemon with the user specified config
Loaded: loaded (/etc/systemd/system/webcamd2.service; enabled; vendor preset: enabled)
Active: activating (start) since Mon 2020-10-05 22:31:11 EDT; 32s ago
Cntrl PID: 1487 (webcamd2)
Tasks: 2 (limit: 2077)
Memory: 948.0K
CGroup: /system.slice/webcamd2.service
β”œβ”€1487 /bin/bash /root/bin/webcamd2
└─1502 sleep 120

Oct 05 22:31:11 Maestro webcamd2[1487]: http options: -w ./www-octopi -p 8081
Oct 05 22:31:11 Maestro webcamd2[1487]: Explicitly USB device: /dev/video1
Oct 05 22:31:11 Maestro webcamd2[1487]: -----------------------------------------------
Oct 05 22:31:11 Maestro webcamd2[1487]: Found video devices:
Oct 05 22:31:11 Maestro webcamd2[1487]: /dev/video0
Oct 05 22:31:11 Maestro webcamd2[1487]: /dev/video1
Oct 05 22:31:11 Maestro webcamd2[1487]: /dev/video10
Oct 05 22:31:11 Maestro webcamd2[1487]: /dev/video11
Oct 05 22:31:11 Maestro webcamd2[1487]: /dev/video12
Oct 05 22:31:11 Maestro webcamd2[1487]: Scan again in two minutes

Specifying camera=raspi for webcamd and then restarting it (forgot to do that in the previous post) caused the same log to appear for webcamd just like in webcamd2. Fixed that and queried status again:

webcamd2.service - the OctoPi webcam daemon with the user specified config
Loaded: loaded (/etc/systemd/system/webcamd2.service; enabled; vendor preset: enabled)
Active: failed (Result: start-limit-hit) since Mon 2020-10-05 22:57:08 EDT; 2s ago
Process: 3046 ExecStart=/root/bin/webcamd2 (code=exited, status=0/SUCCESS)

Oct 05 22:57:08 Maestro systemd[1]: webcamd2.service: Service RestartSec=100ms expired, scheduling restart.
Oct 05 22:57:08 Maestro systemd[1]: webcamd2.service: Scheduled restart job, restart counter is at 5.
Oct 05 22:57:08 Maestro systemd[1]: Stopped the OctoPi webcam daemon with the user specified config.
Oct 05 22:57:08 Maestro systemd[1]: webcamd2.service: Start request repeated too quickly.
Oct 05 22:57:08 Maestro systemd[1]: webcamd2.service: Failed with result 'start-limit-hit'.
Oct 05 22:57:08 Maestro systemd[1]: Failed to start the OctoPi webcam daemon with the user specified config.

Not exactly square 1, but not far from it. Any ideas?

I'm not sure of your exact config, but I got a PiCam2 and a Microsoft USB camera both working on my OctoPrint setup. I did "document" it, but it's not super detailed and honestly, I'm not sure it'll help your particular situation. If you're running 2 PiCams off one Pi, I'd love to know how you did that.

In any case, here's my "docs": (Sorry about the formatting, it's a direct copy/paste from a text file.)

# This is a very "high altitude" view of the stuff I did to make it all work.  It is very rough
# but should be doable for anyone with a bit of Linux knowledge.  Some extra reading will likely be 
# required and I make ZERO guarantees that any of this will work.  You've been warned.  :)

# Look at /var/log/messages to ID where USB camera is mapped.  /dev/videox where x = 0,1,2,3....
# Reboot the Pi before you look so the list isn't so long.
cat /var/log/messages

# Alternately you can unplug the USB camera and watch the messages "live" to see what changes when
# the USB camera is plugged back in:
tail /var/log/messages

# COMMAND LINE
# Command line starting of 2nd instance of mjpg-streamer for USB camera on /dev/video1
# Execute these from the mjpg-streamer directory - /home/pi/mjpg-streamer
# Change /dev/video1 to where YOUR camera maps.  You may have to change resolution and framerate options
# Commands will NOT persist and you will NOT be returned to the command prompt.  CTRL-C to exit to prompt

LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./;./mjpg_streamer -i "input_uvc.so -d /dev/video1 -y 1280x720 -f 10" -o "output_http.so -w ./www -p 8081"

# If there are errors, you may be prompted to restart the daemons, especially if you try to start
# your 2nd instance of mjpg-streamer referencing the /dev the PiCam is on - probably /dev/video0

# Use this command from anywhere and in your .service file.
/home/pi/mjpg-streamer/mjpg_streamer -i "input_uvc.so -d /dev/video1 -y 1280x720 -f 10" -o "output_http.so -w /home/pi/mjpg-streamer/www -p 8081"
# END COMMAND LINE

# To verify streams are working, use this URL for the USB Camera:  This will also be the URL you use for # Octoprint's stream from the USB camera

http://[your Pi IP]:8081/?action=stream

# And your PiCam stream - you should not have to modify the Octoprint stream URL for the PiCam feed.
http://[your Pi IP]:8000/?action=stream

# Once the stream is working, create a System file in /etc/systemd/system to launch 2nd instance of 
# mjpg-streamer for USB cam:
sudo nano [your.service]

# Contents of that file are as follows (This is a very simplifed example, but it works)
# It will wait until after the network stack is initialized and the multi-user environment is up.
# System services are in /lib/systemd/system if you want to use other dependencies for startup.

# Contents of my /etc/systemd/system/mjpg-streamer.usbcam.service:



[Unit]
Description=Service to launch mjpg-streamer for USB Camera
After=network-online.target
Wants=network-online.target multi-user.target

[Service]
ExecStart=/home/pi/mjpg-streamer/mjpg_streamer -i "input_uvc.so -d /dev/video1 -y 1280x720 -f 10" -o
 "output_http.so -w /home/pi/mjpg-streamer/www -p 8081"
WorkingDirectory=/home/pi/mjpg-streamer
StandardOutput=inherit
StandardError=inherit
Restart=always
User=pi

[Install]
WantedBy=multi-user.target



# END Contents of my /etc/systemd/system/mjpg-streamer.usbcam.service

# To test your .service file: (There will be no notifications unless there's an error.)
sudo systemctl start [your.service]

# Verify video streams are working.  If so, you need to enable the service so it loads at boot time.
sudo systemctl enable [your.service]

# Set authorization to the 'pi' user.  Any other authorization requests also need to be set to 'pi'
# Reboot the Pi:
sudo reboot now

# Once the Pi has rebooted, check your video streams with the URLs above.  If they are working, you're
# done.  Log in to your Octoprint instances, go into settings, then Webcam and Timelapse and
# enter the appropriate URLs for streaming.  If they are not, check the service status:
sudo ststemctl status [your.service]

# If the status is "Working", but it's also "Inactice (dead)" you'll need to enable the service again
# or there's an issue with your .service file.  Start from the top and verify everything
# fits YOUR system.

You can fix the formatting by the use of </> in the menu bar on top of the edit window.

Hey everyone! I managed to figure it out with inspiration from the Chris's Basement video!
I need to go ahead an set it up with a fresh OctoPi install to prove that it works, but once I confirm that it does, I'll make a guide for it. It should be noted that this method seems to work with both RPi and USB cameras, because the dt-blob.bin StereoPi provides (for some reason) isn't recognized by MJPG-Streamer/WebcamD as a Pi camera, but a USB one. Theoretically, it should be possible to perform this operation for as many cameras as you have attached to the Compute Module, but I've no USB webcams to test adding more cameras with.

1 Like