fbpixel
Étiquettes : , ,
0
(0)

Nous allons voir dans ce tutoriel, comment envoyer un stream vidéo d’une machine à une autre à l’aide de FFMPEG. Envoyer des données entre deux appareils, quelle qu’elles soient, est un des problèmes majeurs dans les objets connectés (IoT). Si vous souhaitez créer une caméra connectée qui envoie des vidéos à une machine distante, cet article devrait vous intéresser.

Installation de ffmpeg

Sur une machine Linux

sudo apt-get install ffmpeg

Sur une machine Windows, veuillez suivre cette procédure.

N.B.: si besoin sur une machine linux sudo apt-get install v4l-utils

Obtenir les informations nécessaire au streaming Vidéo

Pour créer un flux vidéo d’une machine à une autre, les machines doivent être connectées sur le même réseau (Wifi ou Ethernet)

Dans un premier temps, vous devez obtenir l’adresse IP de la machine cliente (qui reçoit le flux)

Entrez dans un terminal de commande

ifconfig #pour une machine linux
ip addr # si ifconfig n'est pas disponible 

ou

ipconfig #pour une machine windows

Vous devriez obtenir une adresse de la forme 192.168.X.X (dans notre cas 192.168.1.67)

Ensuite récupérer la source vidéo

Pour lister toutes les entrées vidéo sur une machine linux

ls -l /dev/video*
lsusb #list usb devices
v4l2-ctl --list-devices #list video devices

Ces commandes devrait vous aider à identifier la source vidéo. Dans notre cas, /dev/video5

Pour lister les sources vidéo sur une machine Windows, vous pouvez utiliser ffmpeg

ffmpeg -list_devices true -f dshow -i dummy

Dans notre cas, video= »USB2.0 HD UVC WebCam »

Récupérer les options et vérifier les formats et résolutions acceptés par la caméra

sous Linux

v4l2-ctl -d /dev/video0 --list-formats

sous Windows

ffmpeg -f dshow -list_options true -i video="USB2.0 HD UVC WebCam"

Une fois ces données enregistrées, nous allons pouvoir configurer le streaming.

Créer un stream vidéo avec ffmpeg

Pour créer un flux vidéo, il vous faut un émetteur (server) et un récepteur (client) qui seront joués par deux terminaux lancer sur deux ordinateurs différents.

  • côté serveur linux
ffmpeg -re -f v4l2 -i /dev/video5 -r 10 -f mpegts udp://192.168.1.67:8554?pkt_size=1316
  • côté serveur windows
ffmpeg -f dshow -i video="USB2.0 HD UVC WebCam" -r 10 -f mpegts udp://192.168.1.67:8554?pkt_size=1316
  • côté client
ffplay udp://127.0.0.1:8554

N.B.: Vous pouvez tester le streaming sur une seule machine en utilisant l’adresse IP de la machine sur laquelle vous travaillez et en utilisant deux terminaux un pour le serveur et un pour le client

Pour récupérer les statistiques vidéo vous pouvez utiliser la commande ffprobe

ffprobe udp://127.0.0.1:8554

ou, pour plus de détails,

ffprobe -show_format -show_streams udp://127.0.0.1:8554

Réduire le délai de réception du flux vidéo entre deux machines

Nous pouvons observer un délai de 15 secondes environ entre l’émission vidéo et la réception. Il peut être intéressant de réduire ce délai selon les applications.

Côté serveur les paramètre qui jouent sur la vitesse de transmission sont:

  • la taille de l’image (ex: -s 800×600)
  • la conversion de format codec (ex: -c:v libx264)
  • le nombre d’image à la seconde ou framerate (ex: -r 10)

Essayez de jouer avec ces paramètres pour réduire le délai tout en conservant une qualité suffisante.

ffmpeg -re -thread_queue_size 64 -s800x600 -i /dev/video5 -r 5 -f mpegts udp://192.168.1.67:8554?pkt_size=1316

Côté client, il y a différentes options que vous pouvez tester de la documentation repris dans cette discussion.

ffplay -fflags nobuffer -probesize 32 -sync ext -vf setpts=0 udp://127.0.0.1:8554

Ces modifications d’options des commandes ffmpeg et ffplay permet de réduire le délai de 15 à 2 secondes environ le stream video.

Bonus : Afficher le stream vidéo de FFMPEG avec OpenCV

Une fois le flux vidéo établi entre les deux machines, il est possible d’utiliser OpenCV afin de lire et afficher les images provenant du stream UDP.

import cv2

def main(args):

	#cap = cv2.VideoCapture(0) #default camera
	cap = cv2.VideoCapture('udp://127.0.0.1:8554')

	while(True):
		ret, frame = cap.read()
		if ret: #necessary if packet is lost
			frame=cv2.resize(frame, (800, 600)) 
			cv2.imshow('Capturing',frame)
			
		if cv2.waitKey(1) & 0xFF == ord('q'): #click q to stop capturing
			break

	cap.release()
	cv2.destroyAllWindows()
	return 0

if __name__ == '__main__':
    import sys
    sys.exit(main(sys.argv))

Sources

How useful was this post?

Click on a star to rate it!

Average rating 0 / 5. Vote count: 0

No votes so far! Be the first to rate this post.

As you found this post useful...

Follow us on social media!

We are sorry that this post was not useful for you!

Let us improve this post!

Tell us how we can improve this post?