Je travaille régulièrement avec des flux HTTP provenant de caméras IP. La plupart des traitements que j’effectue se font en live. Cependant, dans certains cas, il est nécessaire d’enregistrer le flux vidéo pour pouvoir faire un traitement a posteriori.

Le programme que nous allons créer, fait suite à l’article sur l’enregistrement de vidéos, où nous avions vu la base de l’enregistrement de vidéos. Nous allons ici permettre l’utilisation d’une commande prenant comme entrée un flux HTTP, la durée de la vidéo que nous voulons extraire ainsi que la spécification du fichier de sortie. Bien que ce programme traite des flux vidéo, il est possible de spécifier un fichier vidéo en entrée et en extraire les x premières secondes.

Étape 1: récupérer les variables

Nous commençons donc par créer un fichier enregistrement.py, où nous débutons par importer deux bibliothèques (lignes 1-2). La librairie OpenCV, dont vous avez pris l’habitude d’intégrer à chacun de vos programmes 🙂 et la librairie argparse qui permet de définir les arguments en entrée de notre programme.

import cv2
import argparse

ap = argparse.ArgumentParser()
ap.add_argument("-u", "--url", required = True, help = "URL of the http video stream")
ap.add_argument("-t", "--temps",type=int, required = True,help = "Recording time in seconds")
ap.add_argument("-o", "--output", help="Name of output file", default= "out.avi")
args = vars(ap.parse_args())
path=args["url"]
time=args["temps"]
file=args["output"]

Nous déclarons un objet ArgumentParser (l.4), que nous appelons ap, qui va contenir les informations de nos arguments. Nous ajoutons ensuite les arguments nécessaires (lignes 5-7). Il s’agit du flux vidéo, du temps d’extraction et du fichier de sortie. Pour le premier argument, nous pouvons le rentrer lors de l’appel de notre fonction, après les symboles « -u » ou « –url ». C’est un argument qui est nécessaire à notre programme, c’est pourquoi nous spécifions l’option « required=True ». Enfin nous ajoutons un texte d’aide (help= »… ») dans le cas où une personne ne connaît pas les options à rentrer.

Les options pour le temps sont pratiquement identiques à part que nous spécifions que le type de donnée que l’on va récupérer est de type int. En effet de base, lorsque nous récupérons un argument via argparse, il est de type string, ce qui est problématique dans le cas où nous devons faire des calculs.

Notre dernier argument est le fichier de sortie. Nous rendons cet argument optionnel en ne spécifiant pas qu’il est requis et nous mettons une valeur par défaut (default= « out.avi »). Ainsi, si aucun argument sur le fichier de sortie n’est donné, le fichier « out.avi » sera généré.

Nous analysons ensuite les données de notre objet ArgumentParser à la ligne 8 et nous les stockons dans le dictionnaire « args », grâce à la fonction « vars ». Il ne nous reste plus qu’à récupérer les valeurs des arguments aux lignes 9-11 et à les stocker dans les variables path, time et file.

Étape 2: enregistrer du flux vidéo

Pour enregistrer le flux vidéo, nous avons bien évidemment besoin de le lire (ligne 13) ! Dans le cas où le flux ne peut être lu, nous affichons une alerte afin d’avertir l’utilisateur (l.  15-17).

cap=cv2.VideoCapture(path)
ret,frame=cap.read()
if ret==False:
	print('Erreur de lecture du flux HTTP')
	cap.release()

Si la lecture ne se fait sans problème, nous pouvons continuer ! Il est maintenant nécessaire de déterminer le nombre de trame à enregistrer, ainsi que de déclarer l’objet  VideoWriter .

else:
	fps=cap.get(cv2.CAP_PROP_FPS)
	nb_trames=time*fps
	fourcc = cv2.VideoWriter_fourcc(*'XVID')
	out = cv2.VideoWriter(file, fourcc,fps,(int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)),int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))))
	while (int(cap.get(cv2.CAP_PROP_POS_FRAMES)) != nb_trames ):
		_ret,frame=cap.read()
		out.write(frame)
	print("done")
	cap.release()
	out.release()

Nous récupérons le fps du flux vidéo à la ligne 20 afin de pouvoir calculer le nombre de trame à enregistrer (ligne 21). Le nombre de trame est simplement égal au nombre de secondes que l’on veut enregistrer multiplié par le nombre de trames par seconde (fps).

Il ne reste plus qu’à déclarer l’enregistreur (l. 22-23) et d’enregistrer les trames jusqu’à ce qu’on atteigne le nombre de trame voulu (l. 24-26). Lorsque l’on arrive à la fin, nous affichons le message « done » et nous fermons les objets cap et out (l. 27-29).

C’est tout, nous pouvons maintenant utiliser notre programme !

Utilisation du programme

Afin d’enregistrer une séquence vidéo issue d’un flux http, il nous suffit de taper la commande suivante:

python3 enregistrement.py -u &url_flux_http -t &temps -o &fichier

Nous aurons donc en sortie un fichier &fichier d’une durée de &temps secondes provenant du flux vidéo &url_flux_http.

Sachez enfin qu’il est possible de streamer un fichier vidéo via http sur votre réseau local grâce au logiciel  VLC . La commande sera par exemple:

python3 enregistrement.py -u http://localhost:8080/ -t 30 -o test.avi

Permettant ainsi d’enregistrer le flux envoyé par VLC pendant 30 secondes et enregistré dans le fichier test.avi .

Il nous est dorénavant possible de capturer une vidéo d’une caméra distante afin de pouvoir l’exploiter par la suite.


2 commentaires

Francois · 12 mars 2019 à 21 h 40 min

Bonjour,

comment faire si la caméra attend une authentification par login/mdp ?

Merci.

    Florent · 13 mars 2019 à 8 h 41 min

    Bonjour Francois,

    Tout dépend de votre modèle de caméra.

    Pour certaines caméras, il est possible de fournir l’authentification dans l’URL. (ex: http://@/)

    Quel est votre modèle de caméra ?

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.