2017-08-29 5 views
0

Ce que je voudrais faire est la suivante:Comment passer la sortie d'un programme (ffmpeg) en script python?

ffmpeg -i udp://224.10.10.10:15004 -qscale:v 2 sttest%04d.jpg 

Et puis passer les chemins d'image de sortie de ce à un script python, qui prend individuellement dans les images et les manipule, comme ffmpeg est en cours d'exécution (éventuellement je vais utilisez ffmpy pour appeler le ffmpeg plutôt que d'utiliser l'outil de ligne de commande, mais pour les tests, je commence ici). Je suppose qu'un moyen de faire cela serait de regarder dans le répertoire de la sortie ffmpeg chaque fois que j'ai traité une image pour voir s'il y en a un nouveau, et de le charger ensuite dans python (en utilisant OpenCV) - -et en attendant un certain intervalle de temps s'il n'y a pas de nouvelles images à traiter.

Mais y a-t-il une meilleure façon de procéder, comme envoyer les chemins des images directement à une sorte de file d'attente que le script python peut ensuite traiter un par un?

Répondre

0

Pour tous les curieux, voici ma solution. Il utilisait OpenCV. Je n'étais pas au courant de cela au moment où j'ai posé la question, mais OpenCV a certaines fonctionnalités qui utilisent ffmpeg dans les coulisses. Et puisque mon programme utilisait déjà OpenCV, que je mentionnais seulement au passage dans la question (comme je pensais que ce n'était pas important), il n'était pas très difficile d'utiliser les fonctionnalités intégrées à OpenCV pour faire ce que je voulais. Voici le code:

cap = cv2.VideoCapture("video.mpg") 
count = 0 
frame_q = queue.Queue() 

while cap.grab(): 
    success, frame = cap.read() 

    if count % 5 == 0 and success: 
      frame_alpha = np.insert(frame, 3, 255, axis=2) 
      frame_q.put(frame_alpha) 

    count += 1 

Comme vous pouvez le voir, je suis en train de mettre tous les cinq dans un cadre Queue de cadres. Le noyau de ce sont ces trois lignes:

cap = cv2.VideoCapture("video.mpg") 
while cap.grab(): 
    success, frame = cap.read() 

La première ligne ouvre la capture, les contrôles de la clause while s'il y a des plus cadres à l'aide cap.grab() (retour True s'il y a une trame suivante), puis je lis que encadrer dans un tableau numpy en utilisant cap.read().success est un booléen qui indique si l'opération a réussi. Plus tard, j'ajoute un canal alpha au frame et le place dans le frame_q.

Ensuite, un autre thread du programme get s trame sur Queue. De cette façon, je n'ai pas du tout à faire avec le système de fichiers - comme l'a dit Marcus, je les intègre directement dans le programme.

Note: pour cv2.VideoCapture() travailler les opencv_ffmpeg.dll besoins d'être dans le chemin système ou dans le répertoire racine de l'installation selon des Python que vous utilisez. Vous devrez peut-être le renommer opencv_ffmpegXYZ.dll où XYZ est le numéro de version OpenCV moins les points décimaux. Donc pour moi, c'est opencv_ffmpeg330.dll parce que j'ai la version 3.3.0. Il peut également être appelé opencv_ffmpeg330_64.dll sur un système x64.

L'emplacement de opencv_ffmpeg.dll dépend de la façon dont vous avez installé OpenCV, je voudrais simplement rechercher dans le répertoire OpenCV pour opencv_ffmpeg et voir où il se présente. Avant de le copier dans le répertoire Python, assurez-vous de vérifier s'il existe déjà. Il pourrait être, en fonction de la façon dont vous avez installé OpenCV.

1

Comme FFmpeg n'a pas de sortie qui diffuse les "noms de fichiers que j'ai générés", votre seule option est d'utiliser le système de fichiers dont vous disposez.

En fonction de votre système d'exploitation, il peut y avoir un moyen d'être averti lorsqu'un nouveau fichier est touché dans un répertoire. Je ne sais pas si cela fonctionne pour linux, windows, os x, mais ça vaut la peine d'y jeter un coup d'œil.

En fait, cela semble assez simple que vous ne avoir de le faire en appelant ffmpeg externe. ffmpeg est essentiellement une interface utilisateur pour libavcodec, une bibliothèque conçue pour le décodage et l'encodage vidéo, audio, etc.

Donc, vous pouvez simplement utiliser libavcodec dans votre application. En fait, je pense que ce que vous essayez de faire serait beaucoup plus facile si vous utilisiez une architecture de streaming multimédia. GStreamer serait probablement votre outil de prédilection, et vous pouvez directement travailler avec python, mais je n'ai aucune expérience de la facilité avec laquelle cela fonctionne.

Votre but devrait probablement être d'obtenir les images directement dans votre programme python, sans le détour de les écrire sur le disque.

Un simple convertisseur MJPEG (Motion JPEG), simplement canalisée dans le stdin de votre programme pourrait être la façon la plus simple, si vous ne voulez pas utiliser soit libav* ou gstreamer.