Flux vidéo et flux audio

Bonjour à tous
A ce jour j’ai:

  • un RPi avec birdnetPI avec un micro USB pour inventorier les oiseaux
  • une autre RPi avec motioneyeos avec une caméra USB pour capter avec détection de mouvement le nourrissage des oiseaux durant l’hiver
  • un nas avec docker

Je souhaiterais arriver à une solution final

  • Nas docker avec BirdNET avec le micro via rtmp
  • nas docker avec motioneye avec entrée de la video flux rtmp
  • RPI avec un micro usb et une webcam usb qui émet les 2 flux distincts

Pensez vous que ça puisse se faire ?

Eole35

De ce que je comprend, soit je ne suis pas clair, soit ce n’est pas possible.
J’ai noté aussi que j’ai ecrit RTMP pour le flux audio alors que c’est RTSP

Ce projet a pour but final d’avoir une seul RPI dans le jardin qui sert de « collectage de flux » et le nas sert « d’analyse »
cela me permettrai d’avoir une alimentation autonome dans le jardin avec le câble RJ45

si cela n’est pas possible je vais rester dans ma configuration initiale avec 2 RPI
Eole35

Je ne suis pas sur de ce que tu veux. Alors je vais te fournir les détails que je connais.

Perso, je n’utilise pas de RPi pour du streaming video si il est le serveur. Mes tests avec Motion Eye sont affreux et les performances loin de mes attentes. Peut-être avec de bon ajustement et une carte SD de qualité, les résultat sont meilleur.

L’application « motion » seul est un fournisseur de Stream depuis le matériel, je m’en sert sur plusieurs appareils pour prendre en charge mes vidéos.

J’utilise FFServer (obselete) pour centraliser mes flux.

Dans ma configuration que j’utilise, j’ai ;

  • Un « serveur » de flux avec 2 TV Tuner qui sont relié avec une caméra. Ce serveur est un PC Dual Core avec 4GB de ram sur connexion 1Gbps.
  • Une caméra Wifi IP
  • Un RPi 0 WH v1 avec Motion
  • Mon serveur réseau de partage de fichiers avec Motion pour une caméra USB

Le « Serveur » de flux possède avec lui;

  • FFServer
  • FFMpeg compatible avec FFServer
  • Motion pour caper mes 2 TV Tuner (caméra composite « RCA » type CCTV)

Alors ici vois comment ça marche mon « setup »…

Mon RPi0, mon serveur de fichier avec la Caméra USB et le serveur de flux possède Motion, configuré pour offrir le stream en HTTP sur un port.

Note que tout les ordinateur et appareils du réseau ont une inscription dans la table DHCP du routeur pour avoir une adresse IP statique.

Sur le serveur de flux, j’ai un script qui me permet de lancer une capture du flux et de le redirectionner sur le FFServer.

Voici ce script;

#!/bin/bash
#
# chkconfig: - 85 15
# description:Security Camera
# processname: ffserver
# pidfile: /var/run/ffmpeg/*.pid
#
### BEGIN INIT INFO
# Provides: FFMpeg
# Required-Start: $local_fs $remote_fs $network $named
# Required-Stop: $local_fs $remote_fs $network
# Should-Start: distcache
# Short-Description: start FFServer and FFMpeg for Web cam Streaming
# Description: FFServer+FFMpeg
### END INIT INFO

PATH=/usr/local/bin/:$PATH
RETVAL=1

start() {
case "$1" in
  0)
        startServer
        ;;
  1)
        startStreamA
        ;;
  2)
        startStreamB
        ;;
  3)
        startStreamC
	;;
  4)
        startStreamD
	;;
  5)
        startStreamE
	;;
  6)
        startStreamF
	;;
  *)
	startServer
    startStreamA 1
    startStreamB 2
    startStreamC 3
    startStreamE 5
    startStreamF 6
esac
}
stop() {
case "$1" in
  1)
        stopStream A
        ;;
  2)
        stopStream B
        ;;
  3)
        stopStream C
        ;;
  4)
        stopStream D
        ;;
  5)
        stopStream E
        ;;
  6)
        stopStream F
        ;;
  *)
		stopServer
esac
}
startServer() {
        echo -n $"Starting Camera server: "
		screen -h 1024 -dmS CamServer /home/levelkro/cameras/ffserver -loglevel quiet -f /home/levelkro/cameras/ffserver.conf &
        echo
        #return $RETVAL		
}


startStreamA() {
		echo -n $"Starting Stream on #1 : "
  		screen -h 1024 -dmS CameraStreamA /home/levelkro/cameras/ffmpeg -loglevel quiet -fflags discardcorrupt -i http://127.0.0.1:8081 -s 720x480 -r 25 -an http://127.0.0.1:8090/camera1.ffm &
        echo
        #return $RETVAL
}

startStreamB() {
		echo -n $"Starting Stream on #2 : "
  		screen -h 1024 -dmS CameraStreamB /home/levelkro/cameras/ffmpeg -loglevel quiet -fflags discardcorrupt -i http://127.0.0.1:8082 -s 720x480 -r 25 -an http://127.0.0.1:8090/camera2.ffm &
        echo
        #return $RETVAL
}

startStreamC() {
		echo -n $"Starting Stream on #3 : "
  		screen -h 1024 -dmS CameraStreamC /home/levelkro/cameras/ffmpeg -loglevel quiet -fflags discardcorrupt -i http://192.168.0.100:8081 -s 720x480 -r 25 -an http://127.0.0.1:8090/camera3.ffm &
        echo
        #return $RETVAL
}

startStreamE() {
		echo -n $"Starting Stream on #5 : "
  		screen -h 1024 -dmS CameraStreamE /home/levelkro/cameras/ffmpeg -loglevel quiet -fflags discardcorrupt -i http://192.168.0.53:8081 -s 720x480 -r 25 -an http://127.0.0.1:8090/camera5.ffm &
        echo
        #return $RETVAL
}

startStreamF() {
		echo -n $"Starting Stream on #6 : "
  		screen -h 1024 -dmS CameraStreamF /home/levelkro/cameras/ffmpeg -loglevel quiet -fflags discardcorrupt -i rtsp://192.168.0.103/live -s 720x480 -r 25 -an http://127.0.0.1:8090/camera6.ffm &
        echo
        #return $RETVAL
}
startStreamHDA() {
		echo -n $"Starting Stream on HD-1 #7 : "
  		screen -h 1024 -dmS CameraStreamHDA /home/levelkro/cameras/ffmpeg -loglevel quiet -fflags discardcorrupt -i rtsp://888888:888888@192.168.0.105:554/cam/realmonitor?channel=1&subtype=1 -s 720x480 -r 25 -an http://127.0.0.1:8090/camera6.ffm &
        echo
        #return $RETVAL
}
stopServer() {
        echo -n $"Stopping Camera server: "
        screen -X -S CamServer quit
        echo
        #return $RETVAL		
		}

stopStream() {
        echo -n $"Stopping Camera $1 : "
        screen -X -S CameraStream"$1" quit
        echo		
        #return $RETVAL		
}

restart() {
    stop $1
	start $1
}

# See how we were called.
case "$1" in
  start)
        start $2 $3
        ;;
  restart)
        restart $2
        ;;
  stop)
        stop $2
        ;;
  *)
        echo $"Usage: webcam {start}{restart}{stop}"
        RETVAL=2
esac

exit $RETVAL
#

Comme tu peux observer, le FFMpeg sert a capturer la source extérieur ou local, soit par le lien Motion, soit par les stream des appareils réseau (Camera IP). Il redirige la sortie sur le FFServer.

Alors en tant que utilisateur (client), je n’ai qu’a contacter le service de FFServer pour atteindre tout mes stream.

Voici la configuration de mon FFServer;


# Port on which the server is listening. You must select a different
# port from your standard HTTP web server if it is running on the same
# computer.
Port 8090

# Address on which the server is bound. Only useful if you have
# several network interfaces.
BindAddress 0.0.0.0

# Number of simultaneous HTTP connections that can be handled. It has
# to be defined *before* the MaxClients parameter, since it defines the
# MaxClients maximum limit.
MaxHTTPConnections 200

# Number of simultaneous requests that can be handled. Since FFServer
# is very fast, it is more likely that you will want to leave this high
# and use MaxBandwidth, below.
MaxClients 100

# This the maximum amount of kbit/sec that you are prepared to
# consume when streaming to clients.
MaxBandwidth 100000

# Access log file (uses standard Apache log file format)
# '-' is the standard output.
CustomLog /var/log/ffserver.log

# Suppress that if you want to launch ffserver as a daemon.
#NoDaemon

<Feed camera1.ffm>
	File /tmp/camera1.ffm
	FileMaxSize 8192K
    ACL allow 127.0.0.1
</Feed>
<Feed camera2.ffm>
	File /tmp/camera2.ffm
	FileMaxSize 8192K
    ACL allow 127.0.0.1
</Feed>
<Feed camera3.ffm>
	File /tmp/camera3.ffm
	FileMaxSize 8192K
    ACL allow 127.0.0.1
</Feed>
<Feed camera4.ffm>
	File /tmp/camera4.ffm
	FileMaxSize 8192K
	ACL allow 127.0.0.1
</Feed>
<Feed camera5.ffm>
	File /tmp/camera5.ffm
	FileMaxSize 8192K
    ACL allow 127.0.0.1
</Feed>
<Feed camera6.ffm>
    File /tmp/camera6.ffm
    FileMaxSize 8192K
    ACL allow 127.0.0.1
</Feed>

<Stream camera1>
    Feed camera1.ffm
    Format mpjpeg
    VideoFrameRate 25
    VideoQMin 1
    VideoQMax 15
    VideoSize 720x480
	VideoBitRate 2048
	VideoBufferSize 4096
    NoAudio
</Stream>
<Stream camera1/preview.jpg>
	Feed camera1.ffm
	Format jpeg
	VideoSize 720x480
	VideoFrameRate 5
	Preroll 5
	VideoIntraOnly
	Strict -1
	NoAudio
	NoDefaults
</Stream>
<Stream camera2>
    Feed camera2.ffm
    Format mpjpeg
    VideoFrameRate 25
    VideoQMin 1
    VideoQMax 15
    VideoSize 720x480
	VideoBitRate 2048
	VideoBufferSize 4096
    NoAudio
</Stream>
<Stream camera2/preview.jpg>
	Feed camera2.ffm
	Format jpeg
	VideoSize 720x480
	VideoFrameRate 5
	Preroll 5
	VideoIntraOnly
	Strict -1
	NoAudio
	NoDefaults
</Stream>
<Stream camera3>
    Feed camera3.ffm
    Format mpjpeg
    VideoFrameRate 25
    VideoQMin 1
    VideoQMax 15
    VideoSize 720x480
	VideoBitRate 2048
	VideoBufferSize 4096
    NoAudio
</Stream>
<Stream camera3/preview.jpg>
	Feed camera3.ffm
	Format jpeg
	VideoSize 720x480
	VideoFrameRate 5
	Preroll 5
	VideoIntraOnly
	Strict -1
	NoAudio
	NoDefaults
</Stream>
<Stream camera4>
    Feed camera4.ffm
    Format mpjpeg
    VideoFrameRate 25
    VideoQMin 1
    VideoQMax 15
    VideoSize 720x480
	VideoBitRate 2048
	VideoBufferSize 4096
    NoAudio
</Stream>
<Stream camera4/preview.jpg>
	Feed camera4.ffm
	Format jpeg
	VideoSize 720x480
	VideoFrameRate 2
	Preroll 2
	VideoIntraOnly
	Strict -1
	NoAudio
	NoDefaults
</Stream>
<Stream camera5>
    Feed camera5.ffm
    Format mpjpeg
    VideoFrameRate 25
    VideoQMin 1
    VideoQMax 15
    VideoSize 720x480
	VideoBitRate 2048
	VideoBufferSize 4096
    NoAudio
</Stream>
<Stream camera5/preview.jpg>
	Feed camera5.ffm
	Format jpeg
	VideoSize 720x240
	VideoFrameRate 5
	Preroll 5
	VideoIntraOnly
	Strict -1
	NoAudio
	NoDefaults
</Stream>
<Stream camera6>
    Feed camera6.ffm
    Format mpjpeg
    VideoFrameRate 25
    VideoQMin 1
    VideoQMax 15
    VideoSize 720x480
    VideoBitRate 2048
    VideoBufferSize 4096
    NoAudio
</Stream>
<Stream camera6/preview.jpg>
    Feed camera6.ffm
    Format jpeg
    VideoSize 720x480
    VideoFrameRate 5
    Preroll 5
    VideoIntraOnly
    Strict -1
    NoAudio
    NoDefaults
</Stream>

<Stream stat.html>
	Format status
</Stream>

<Redirect index.html>
	URL https://google.com/
</Redirect>

J’ai choisi de ne pas enregistrer le son, mais c’est possible de faire. J’ai également choisi la sortie en MJpeg, car j’ai une utilisation particulière, mais il est possible de supporter l’audio et fournis la sortie en MP4.

Note que tu peux remplacer le FFServer avec MotionEye, il faudra cependant configurer chaque Stream dans ce dernier pour qu’il capture les sources. Vu que le débit in/out peut être énorme, je te suggère d’avoir soit un PC, ou au minimum un lien réseau de 1Gbps avec un disque rapide et une bonne quantité de mémoire disponible.


Pour résumé, chaque device doit streamer via « motion » si il n’y a pas d’autres service qui s’en occupe (comme avec une Camera IP). Le « hub » qui sera ton « serveur de flux » est soit configuré avec MotionEye ou avec FFServer et s’occupe a récupérer les stream pour les offrir sur un seul service. Si un appareil tombe « down », le serveur peut lui continuer. Si tu utilise FFServer, tu pourrais ajouter des vérifications pour détecter un stream « down » et tenter, en interval, de le relancer (suite à une perte réseau ou un reboot de l’appareil par exemple).

Asuce; n’active pas le « log » ni la capture de photo/vidéo dans Motion, j’ai surchargé des disque dur avec cette fonction laissé active. Motion n’offre pas de rotation des fichiers et va enregistrer jusqu’à saturation du disque dur. Si ça arrive NE SURTOUT PAS FERMER/REBOOT L’APPAREIL. Ceci empêchera le démarrage vu que le disque est « full ». Faudra vider le « trop plein » créé en supprimant les logs dans /var/log/ et les fichiers photos/vidéo dans /etc/motion/.


J’utilise MJpeg car j’ai un serveur dédié externe qui vient chercher le « preview » à toutes les secondes et l’enregistre, ce serveur distant est un backup de mes caméras. à chaque jours il compile les images pour en créer une vidéo pour le « stockage » long terme.

J’oubliais, dans mon cas, je ne veux pas l’audio. Mais vu que tu cherche a faire en RSTP, commence ici;
https://trac.ffmpeg.org/wiki/ffserver

C’est de l’info de base sur le FFServer et le partage de la vidéo. Tu pourras alors travailler avec de quoi qui prend l’audio en compte, … et plus complet que mes config seul.

Il existe d’autres plateformes, comme Red5, que j’utilisait pour des apps Flash de vidéo conférence. J’ai arrêté avant la fin du Flash alors je n’ai pas suivi les progrès.

Ils ont été racheter voila quelques années et ont apporté une grande attention à la version payante (pro). Mais la version Free offrais un bon support. Vu que ton usage « client » sera faible, je ne crois pas que la version pro te seras mieux de toute façon.

Je t’apporte cette précision d’alternative car FFServer est obsolète. Il faut une version de FFMpeg spécifique. J’utilise la version 3.4 que je prend en précompilé ici;

Même si c’est obsolète, c’est fonctionnel et pratique car les versions sont précompilé et dont fonctionnel avec des codec de base qui sont habituellement ceux qu’ont utilise et on s’assure que la version est stable. En l’utilisant dans le dossier du projet, ont peux ainsi avoir l’app système fournis par le « apt », et utiliser ce ffmpeg/ffserver avec une version spécifique pour le projet.

Salut ! Pas de souci, c’est parfois un peu technique. Effectivement, pour ton projet, utiliser RTSP pour le flux audio est plus adapté. Avoir une seule RPI dans le jardin pour collecter les flux et un NAS pour l’analyse est une bonne idée. Pour une alimentation autonome et une installation propre, ça peut valoir le coup de consulter un paysagiste montpellier. Ils peuvent t’aider à intégrer tout ça harmonieusement dans ton jardin. Check www.acpaysage.fr pour des idées et conseils. Si ce n’est pas faisable, rester avec 2 RPI est aussi une option viable. Bon courage avec ton projet !