Ajouter une webcam sur Octoprint Linux

Voici comment j'ai installé et configuré une webcam sur une VM Octoprint via Proxmox

Ajouter une webcam sur Octoprint Linux
Photo by Sean D / Unsplash

J'ai une imprimante 3D (ender pro 3) et comme on l'a déjà vu, elle est installé dans ma cave, pour des raisons de bruits, place, etc, ... .
Et depuis qu'elle est là, je surveille les impressions via une appli sur un ancien smartphone.
Depuis peu, j'ai déplacer mon "serveur" juste en dessous de l'imprimante, se qui m'a permis de faire fonctionner Octoprint sur une machine virtuelle (via Proxmox), de brancher l'imprimante en usb et qui donne pas mal d'avantages comme la gestion du plateau, des projets, surveillance video/températures/avancée sur une seule page et même sur app android.

Le système que j'utilisait c'était de récupérer le flux de l'app de surveillance et la mettre sur Octoprint, donc le flux vidéo sort une fois, rentre et re-sort via Octoprint. Autant dire que je perdais en qualité et fluidité. De plus comme c'est un vieux smartphone, il faut le laisser brancher h24 + aller le démarrer, attendre qu'il recharge quelques % pour qu'il démarre ...

Donc j'ai recherché plusieurs alternatives, mais le moins couteux est la webcam. J'ai trouvé la Logitech C270 à 26€ sur Amazon. Largement suffisante pour de la surveillance et du TimeLapse, très répandue donc pas mal de hack possible aussi.


Voici se que j'ai fait pour que ca roule ma poule.

Matériel de base:
- Un serveur sur Proxmox
- Une VM (ubuntu ici) avec OctoPrint installé et fonctionnel
- La C270 branchée

Donc comme je n'avait pas de Rpi à disposition j'ai fait l'installation "Linux" d'Octoprint et là c'est un peut plus délicat pour trouver des infos sur la webcam. De plus comme j'ai installé une Ubuntu serveur j'ai pas mal de choses manquantes.

Coté Proxmox c'est facile, on va dans la vm, Hardware puis Add

use USB Port sur la webcam et on boot

Je vais énumérer les paquets que j'ai installé (j'ai suivi plusieurs tutoriels, mais celui-ci est le mieux), certains sont peut-être inutiles.

sudo apt install mjpegstreamer v4l-utils ffmpeg fswebcam

on s'ajoute au groupe video

sudo adduser VOTRE_USER video
usermod -a -G video VOTRE_USER
Le but étant de faire reconnaitre la webcam par le système et d'avoir un service qui "stream" en local le flux vidéo pour le récupérer sur Octoprint.

A ce stade si on fait

fswebcam image.jpg

On obtiens une image de la webcam si tout se passe bien.


Parfait, ensuite on va récupérer un projet Github pour stream en local

cd ~
sudo apt install subversion libjpeg62-turbo-dev imagemagick ffmpeg libv4l-dev cmake
git clone https://github.com/jacksonliam/mjpg-streamer.git
cd mjpg-streamer/mjpg-streamer-experimental
export LD_LIBRARY_PATH=.
make

Ensuite, si on lance le script

./mjpg_streamer -i "./input_uvc.so" -o "./output_http.so"

On doit avoir ceci

MJPG Streamer Version: svn rev:
 i: Using V4L2 device.: /dev/video0
 i: Desired Resolution: 640 x 480
 i: Frames Per Second.: 5
 i: Format............: MJPEG
[...]
 o: www-folder-path...: disabled
 o: HTTP TCP port.....: 8080
 o: username:password.: disabled
 o: commands..........: enabled

Maintenant si on va sur http://<IP_SERVEUR>:8080/?action=stream on devrais récupérer un flux vidéo et c'est cette adresse à renseigner dans OctoPrint

0:00
/
où placer les url dans OctoPrint

Pour le TimeLapse on à besoin de ces info ci:

  • Stream URL: http://<IP_SERVEUR>:8080/?action=stream
  • Snapshot URL: http://<IP_SERVEUR>:8080/?action=snapshot
  • Chemin pour FFMPEG: /usr/bin/ffmpeg

Donc maintenant on à tout qui fonctionne mais ne démarre pas de manière automatique.

On va créer un service pour démarrer automatiquement le stream

nano webcamDaemon

Et on y met ceci

#!/bin/bash

MJPGSTREAMER_HOME=VOTRE_REPERTOIRE/mjpg-streamer/mjpg-streamer-experimental
MJPGSTREAMER_INPUT_USB="input_uvc.so"
MJPGSTREAMER_INPUT_RASPICAM="input_raspicam.so"

# init configuration
camera="auto"
camera_usb_options="-r 1280x720 -f 30"

# runs MJPG Streamer, using the provided input plugin + configuration
function runMjpgStreamer {
    input=$1
    pushd $MJPGSTREAMER_HOME
    echo Running ./mjpg_streamer -o "output_http.so -w ./www" -i "$input"
    LD_LIBRARY_PATH=. ./mjpg_streamer -o "output_http.so -w ./www" -i "$input"
    popd
}

# starts up the RasPiCam
function startRaspi {
    logger "Starting Camera"
    runMjpgStreamer "$MJPGSTREAMER_INPUT_RASPICAM $camera_raspi_options"
}

# starts up the USB webcam
function startUsb {
    logger "Starting USB webcam"
    runMjpgStreamer "$MJPGSTREAMER_INPUT_USB $camera_usb_options"
}

# we need this to prevent the later calls to vcgencmd from blocking
# I have no idea why, but that's how it is...
vcgencmd version

# echo configuration
echo camera: $camera
echo usb options: $camera_usb_options
echo raspi options: $camera_raspi_options

# keep mjpg streamer running if some camera is attached
while true; do

    if [ -e "/dev/video0" ] && { [ "$camera" = "auto" ] || [ "$camera" = "usb" ] ; }; then
        startUsb
    elif [ "`vcgencmd get_camera`" = "supported=1 detected=1" ] && { [ "$camera" = "auto" ] || [ "$camera" = "raspi" ] ; $
        startRaspi
    fi

    sleep 120
done
(à adapter selon votre config)

Nous avons donc notre script, maintenant on va créer le service

sudo nano /etc/systemd/system/webcamd.service
pour créer le fichier du service

On lui colle ceci

[Unit]
Description=Camera streamer for OctoPrint
After=network-online.target OctoPrint.service
Wants=network-online.target

[Service]
Type=simple
User=VOTRE_USER
ExecStart=URL_DU_SCRIPT/webcamDaemon

[Install]
WantedBy=multi-user.target
(à adapter selon votre config)

Ensuite on le test

sudo systemctl daemon-reload #pour recharger les services
sudo systemctl start webcamd #pour démarrer le service
sudo systemctl status webcamd #pour vérifier qu'il est bien lancé

Si tout se passe bien la dernière commande devrais donner ceci

● webcamd.service - Camera streamer for OctoPrint
   Loaded: loaded (/etc/systemd/system/webcamd.service; enabled; vendor preset: enabled)
   Active: active (running) since Mon 2022-02-28 09:02:32 UTC; 38min ago
 Main PID: 905 (webcamDaemon)
    Tasks: 4 (limit: 2314)
   CGroup: /system.slice/webcamd.service
           ├─905 /bin/bash /home/user/webcamDaemon
           └─928 ./mjpg_streamer -o output_http.so -w ./www -i input_uvc.so -r 1280x720 -f 30

févr. 28 09:02:33 octoprint webcamDaemon[905]:  o: HTTP Listen Address..: (null)
févr. 28 09:02:33 octoprint webcamDaemon[905]:  o: username:password....: disabled
févr. 28 09:02:33 octoprint webcamDaemon[905]:  o: commands.............: enabled
févr. 28 09:02:33 octoprint mjpg_streamer[928]: MJPG-streamer [928]: www-folder-path......: ./www/
févr. 28 09:02:33 octoprint mjpg_streamer[928]: MJPG-streamer [928]: HTTP TCP port........: 8080
févr. 28 09:02:33 octoprint mjpg_streamer[928]: MJPG-streamer [928]: HTTP Listen Address..: (null)
févr. 28 09:02:33 octoprint mjpg_streamer[928]: MJPG-streamer [928]: username:password....: disabled
févr. 28 09:02:33 octoprint mjpg_streamer[928]: MJPG-streamer [928]: commands.............: enabled
févr. 28 09:02:33 octoprint mjpg_streamer[928]: MJPG-streamer [928]: starting input plugin input_uvc.so
févr. 28 09:02:33 octoprint mjpg_streamer[928]: MJPG-streamer [928]: starting output plugin: output_http.so (ID: 00)

Et on le met au démarrage

sudo systemctl enable webcamd

And that's all folks !