Pouvez-vous diffuser des images de ffmpeg pour construire une vidéo, au lieu de les sauvegarder sur le disque?
Mon travail récemment implique par programme faire des vidéos. En python, le flux de travail typique ressemble à ceci:
import subprocess, Image, ImageDraw
for i in range(frames_per_second * video_duration_seconds):
img = createFrame(i)
img.save("%07d.png" % i)
subprocess.call(["ffmpeg","-y","-r",str(frames_per_second),"-i", "%07d.png","-vcodec","mpeg4", "-qscale","5", "-r", str(frames_per_second), "video.avi"])
Ce flux de travail permet de créer une image pour chaque image de la vidéo et de l'enregistrer sur le disque. Après que toutes les images ont été enregistrées, ffmpeg est appelé à construire une vidéo à partir de toutes les images.
Enregistrer les images sur le disque (pas la création d'images dans la mémoire) consomme la plupart des cycles ici, et ne semble pas être nécessaire. Est-il possible de réaliser la même fonction, mais sans enregistrer les images sur le disque? Donc, ffmpeg seraient appelés et les images seraient construits et nourris à ffmpeg immédiatement après avoir été construit.
- Je ne sais pas comment vous êtes en train de créer les images, mais ffmpeg accepte tuyau d'entrées trop:
ffmpeg -f image2pipe -c:v png -r 30000/1001 -i -
. - Pour des raisons de simplicité, il suffit de supposer que
createFrame(i)
retourne un Python Image de la Bibliothèque de l'image de l'objet, que nous stockons dansimg
. Je pense que votre réponse est un pas dans la bonne direction, mais la moitié du défi serait de tuyauterie les images construites à ffmpeg alors que dans le programme python. - peut-être que la file d'attente et ensuite copier les images par l'intermédiaire d'un deuxième thread?
- Peut-être en mesure d'envoyer votre entrée dans un tube nommé et le passer à ffmpeg, ainsi, fondamentalement, le même processus...
Vous devez vous connecter pour publier un commentaire.
Ok je l'ai eu à travailler. grâce à LordNeckbeard suggestion pour l'utilisation image2pipe. J'ai eu à utiliser jpg encodage au lieu de png, car image2pipe avec les png ne fonctionne pas sur mon verision de ffmpeg. Le premier script est essentiellement le même que votre question du code, sauf que j'ai implémenté une simple création de l'image qui crée des images allant du noir au rouge. J'ai également ajouté un peu de code pour le temps de l'exécution.
l'exécution de série
l'exécution en parallèle (sans les images enregistrées sur le disque)
les résultats sont intéressants, j'ai couru chaque script 3 fois pour comparer les performances:
série:
parallèle:
Il semble donc que la version parallèle est plus rapide d'environ 1,5 fois plus rapide.
-vcodec png
etim.save(p.stdin, 'PNG')
si la taille du fichier est x4OSError: [WinError 6] The handle is invalid
sur lep = Popen(['ffmpeg',...
ligne. Aucune oeuvre de solutions de rechange?stdout=PIPE
comme un argument supplémentaire pourPopen
imageio prend en charge directement. Il utilise FFMPEG et le L'Accélération vidéo API, qui le rend très rapide: