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.