ffmpeg_live_streaming
Différences
Ci-dessous, les différences entre deux révisions de la page.
Prochaine révision | Révision précédente | ||
ffmpeg_live_streaming [2025/04/22 19:17] – créée luc | ffmpeg_live_streaming [2025/04/23 20:29] (Version actuelle) – luc | ||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
====== Webcam streaming (avec ffmpeg) ====== | ====== Webcam streaming (avec ffmpeg) ====== | ||
- | Dans mon travail, on utilise souvent de vieux équipements basés sur des OS qui ne sont plus maintenus (coucou Windows XP!), et qu'il serait dangereux de connecter à internet. Pourtant, nous avons besoin de savoir ce qu'il se passe sur l' | + | Dans mon travail, on utilise souvent de vieux équipements basés sur des OS qui ne sont plus maintenus (coucou Windows XP!), et qu'il serait dangereux de connecter à internet. Pourtant, nous avons besoin de savoir ce qu'il se passe sur l' |
- | La première solution que nous avons employée est | + | La première solution que nous avons employée est [[https:// |
+ | ça fait 5 ans qu'on l' | ||
+ | Mais, il y a un mais, ça ne fonctionne pas toujours. Et on ne sait pas pourquoi. Boot, marche pas, reboot marche pas, reboot marche pas, reboot marche. | ||
+ | |||
+ | On s'est donc penché sur une autre solution, basé sur du streaming de vraies vidéos. L' | ||
+ | Qui dit stream vidéo, dit ffmpeg (surtout sur une base linux). En vrai, ça n'a pas été si facile que ça, mais au final ça marche et la solution est assez élégante.\\ | ||
+ | Allez, je vous montre comment on a fait. | ||
+ | |||
+ | ===== Matériel ===== | ||
+ | |||
+ | * Un raspberry pi sous Raspberry pi OS (on vise la compatibilité avec le hardware et la dispo des softwares) | ||
+ | * Une webcam branchée en USB | ||
+ | * Une connexion ethernet (le cuivre, y'a que ça de vrai) | ||
+ | * (facultatif) un serveur web pour centraliser plusieurs Rpi+webcam | ||
+ | |||
+ | |||
+ | ===== Principe ===== | ||
+ | |||
+ | Dans les grandes lignes, on va demander à ffmpeg de capturer le flux vidéo depuis la webcam et de l' | ||
+ | On notera que ffmpeg ne peut diffuser que s'il y a un récepteur actif, c'est le serveur nginx qui joue ce rôle, même si aucun client n'est connecté. | ||
+ | |||
+ | |||
+ | ===== Installation du Raspberry Pi ===== | ||
+ | |||
+ | On aura un usage headless, or les versions " | ||
+ | |||
+ | |||
+ | ===== Serveur RTMP (nginx) ===== | ||
+ | |||
+ | Installation : '' | ||
+ | |||
+ | === Configuration en relais RTMP === | ||
+ | |||
+ | On configure nginx, le bloc rtmp doit être à la racine, il ne doit pas être inclus dans le bloc http comme le son les vhost : | ||
+ | < | ||
+ | # nginx.conf | ||
+ | # Configuration de nginx en relais rtmp | ||
+ | rtmp { | ||
+ | server { | ||
+ | listen 1935; # Listen on standard RTMP port | ||
+ | chunk_size 4096; # les paquets feront 4096 octets, le standard | ||
+ | |||
+ | application live { | ||
+ | live on; | ||
+ | record off; | ||
+ | } | ||
+ | |||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | On peut envoyer un flux vers le serveur en indiquant son ip `rtmp:// | ||
+ | Le port est facultatif, car nous avons utilisé 1935 qui est le standard. | ||
+ | Le choix de " | ||
+ | Le terme " | ||
+ | |||
+ | On pourrait ensuite se connecter au serveur avec un client comme VLC en indiquant l' | ||
+ | |||
+ | C'est bien, mais on ne peut pas accéder au flux RTMP dans le navigateur (peut-être certains lecteurs media en JS le peuvent, mais je ne les ai pas trouvés) | ||
+ | |||
+ | === Configuration pour servir en HLS === | ||
+ | On va diffuser jusqu' | ||
+ | < | ||
+ | # nginx.conf | ||
+ | # Configuration pour servir le flux en HLS | ||
+ | rtmp { | ||
+ | server { | ||
+ | listen 1935; # Listen on standard RTMP port | ||
+ | chunk_size 4096; # les paquets feront 4096 octets, le standard | ||
+ | |||
+ | application live { | ||
+ | live on; | ||
+ | record off; | ||
+ | |||
+ | # Turn on HLS | ||
+ | hls on; | ||
+ | hls_path / | ||
+ | hls_fragment 3; | ||
+ | hls_playlist_length 60; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | On notera que nous avons choisi de mettre les fichiers écrits par HLS dans un dossier dans la RAM (/dev/shm, pour être plus rapide que sur la carte SD et éviter d'user celle-ci), il convient que ce dossier existe et soit accessible en écriture à l'user du serveur web (www-data ou nginx, selon la config). | ||
+ | |||
+ | Il faut ensuite gérer 2 vhost : un pour le flux HLS, l' | ||
+ | < | ||
+ | # Servir le flux HLS (de simples fichiers, mais avec les headers qui vont bien) | ||
+ | # mon_vhost.conf ou inclus dans le bloc http | ||
+ | server { | ||
+ | listen 8080; | ||
+ | |||
+ | location /hls { | ||
+ | # Disable cache | ||
+ | add_header ' | ||
+ | |||
+ | # CORS setup | ||
+ | add_header Access-Control-Allow-Origin *; | ||
+ | add_header ' | ||
+ | add_header ' | ||
+ | |||
+ | # allow CORS preflight requests | ||
+ | if ($request_method = ' | ||
+ | add_header ' | ||
+ | add_header ' | ||
+ | add_header ' | ||
+ | add_header ' | ||
+ | return 204; | ||
+ | } | ||
+ | |||
+ | types { | ||
+ | |||
+ | application/ | ||
+ | video/mp2t ts; | ||
+ | } | ||
+ | |||
+ | root /dev/shm; | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | On notera l' | ||
+ | On notera les directives pour autoriser les flux qui viennent d' | ||
+ | |||
+ | < | ||
+ | # Servir le site web qui contiendra le player (simple fichier html) | ||
+ | # mon_vhost.conf ou autre ou inclus dans le bloc http | ||
+ | |||
+ | # dans un bloc server { }, on peut juste servir le fichier | ||
+ | |||
+ | root / | ||
+ | |||
+ | location / { | ||
+ | add_header Access-Control-Allow-Origin *; | ||
+ | if ($request_method = ' | ||
+ | add_header ' | ||
+ | add_header ' | ||
+ | } | ||
+ | |||
+ | # First attempt to serve request as file, then | ||
+ | # as directory, then fall back to displaying a 404. | ||
+ | try_files $uri $uri/ =404; | ||
+ | } | ||
+ | </ | ||
+ | On notera les entêtes pour les autorisations de CORS (Cross Origins) bla bla... | ||
+ | |||
+ | === Page web avec le lecteur === | ||
+ | On va s' | ||
+ | ``` | ||
+ | < | ||
+ | <html lang=" | ||
+ | < | ||
+ | <meta charset=" | ||
+ | < | ||
+ | <link href="// | ||
+ | </ | ||
+ | < | ||
+ | < | ||
+ | |||
+ | <video | ||
+ | class=" | ||
+ | controls | ||
+ | preload=" | ||
+ | width=" | ||
+ | height=" | ||
+ | data-setup=" | ||
+ | > | ||
+ | <source src=" | ||
+ | <p class=" | ||
+ | To view this video please enable JavaScript, and consider upgrading to a | ||
+ | web browser that | ||
+ | <a href=" | ||
+ | > | ||
+ | > | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | <script src=" | ||
+ | |||
+ | </ | ||
+ | </ | ||
+ | ``` | ||
+ | On notera l'url vers le flux HLS configuré précédemment. | ||
+ | |||
+ | |||
+ | Voilà, on a ce qu'il faut pour consommer le flux video, il faut maintenant le capturer, c'est le travail de ffmpeg. | ||
+ | |||
+ | |||
+ | ===== Vérification des caméras connectées ===== | ||
+ | |||
+ | On utilise le paquet '' | ||
+ | Il fournit la commande '' | ||
+ | <code bash> | ||
+ | user@raspberrypi: | ||
+ | bcm2835-codec-decode (platform: | ||
+ | / | ||
+ | / | ||
+ | [...] | ||
+ | / | ||
+ | |||
+ | bcm2835-isp (platform: | ||
+ | / | ||
+ | / | ||
+ | [...] | ||
+ | / | ||
+ | / | ||
+ | |||
+ | # et si la caméra webcam est branchée | ||
+ | Microsoft® LifeCam Studio(TM): (usb-3f980000.usb-1.1.3): | ||
+ | / | ||
+ | / | ||
+ | / | ||
+ | </ | ||
+ | |||
+ | Les bcm2835 ne nous intéressent pas, il s'agit probablement de la gestion de la caméra par le connecteur CSI (nappe). La webcam que nous avons est bien de marque Microsoft, et elle est branchée en USB. C'est donc ce dernier bloc qui nous intéresse.\\ | ||
+ | => On apprend qu' | ||
+ | |||
+ | |||
+ | |||
+ | ===== ffmpeg pour la capture ===== | ||
+ | |||
+ | [[https:// | ||
+ | |||
+ | ffmpeg permet la capture de video depuis la webcam. C'est un outil qui se lance en ligne de commande, et qui nécessite un certain nombre de paramètres pour bien définir et optimiser le flux. Il n'est pas rare de passer 1h (voir beaucoup plus) à peaufiner les paramètres de cette mono-ligne de commande quand on est débutant sur ffmpeg. Mais quelle jouissance quand ça fonctionne :) | ||
+ | |||
+ | === Installation === | ||
+ | Sur mon Raspberry Pi OS, l' | ||
+ | |||
+ | === Formats disponibles === | ||
+ | On peut voir quels sont les formats | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ===== Amélioration WebRTC ===== | ||
+ | |||
+ | On peut lire un peu partout que WebRTC est un protocole moderne (post-covid) qui gère la transmission de flux vidéo avec des latences sub-seconde, | ||
+ | Ce serait donc une solution intéressante pour améliorer notre solution qui souffre d'une latence entre 5 et 10 secondes, et qui nécessite une librairie JS côté client. | ||
+ | |||
+ | Liens (pas testés): | ||
+ | * https:// | ||
+ | |||
+ | |||
+ | ===== Autre solution : le streaming d' | ||
+ | |||
+ | Je note ici en vrac des pistes que nous avons abordées, puis écartées ou pas creusées.\\ | ||
+ | Elles ont toutes le point commun du mode opératoire en 2 temps : capture d' | ||
+ | |||
+ | === fswebcam === | ||
+ | On l' | ||
+ | |||
+ | <code bash> | ||
+ | fswebcam : generate images for a webcam | ||
+ | options interessantes : | ||
+ | -d / | ||
+ | -r 1920x1080 | ||
+ | --timestamp " | ||
+ | --loop X # mettre le programme en boucle, toutes les X secondes | ||
+ | /!\ pas de conditions de fin, loop jusqu' | ||
+ | --save pic%Y-%m-%d_%H: | ||
+ | -b # run in background, n'a pas l'air de fonctionner | ||
+ | </ | ||
+ | 3 usages : | ||
+ | - faire une seule image | ||
+ | - faire des captures en boucle, sur le même nom de fichier (pour un streaming par exemple) | ||
+ | - avec des noms de fichiers qui s' | ||
+ | |||
+ | Il convient ensuite de créer un serveur web qui diffuse les images. | ||
+ | |||
+ | Idées : | ||
+ | * mettre les images dans ''/ | ||
+ | * côté client, utiliser une lib JS comme [[https:// | ||
+ | * Rajouter des subprocess python/cli pour vérifier si la caméra est connectée (entre le serveur central et le rpi+webcam, ping ?) | ||
+ | |||
+ | === rpicam === | ||
+ | '' | ||
+ | Pourtant v4l2-ctl en trouve | ||
+ | => rpicam ne fonctionne pas avec les caméras USB (fonctionne qu' | ||
+ | |||
+ | === picamera2 === | ||
+ | L' | ||
+ | L' | ||
+ | Cette solution n'a pas été testée. | ||
+ | Voici des liens qui en parle : | ||
+ | https:// | ||
+ | https:// |
ffmpeg_live_streaming.1745349430.txt.gz · Dernière modification : 2025/04/22 19:17 de luc