Supprimer toutes les images paires ou impaires à l'aide de FFmpeg?


14

Existe-t-il un moyen précis de prendre une vidéo brute et d'en extraire une nouvelle vidéo qui ne contient que des images impaires ou même des images (au choix)?

Par exemple:

J'ai "blah.yuv" avec 400 images (0-399). Je veux créer "blahOdd.yuv" qui contient les images 1-399 (1,3,5,7 ... 399) et "blahEven" qui contient les images 0-398 (0,2,4,6 ... 398 ).

Des idées comment le faire en utilisant uniquement FFmpeg?

Réponses:


11

Pour travailler avec précision, convertissez d'abord la vidéo en flux binaire RAW YUV (si ce n'est pas déjà fait) en:

ffmpeg -i input.mp4 -an -vcodec rawvideo -pix_fmt yuv420p rawbitstream.yuv

Étape suivante: le selectfiltre prend une expression , où nest le numéro de trame.

ffmpeg -r 2 -s WxH -i rawbitstream.yuv -filter:v select="mod(n-1\,2)" \
-c:v rawvideo -r 1 -format rawvideo -pix_fmt yuv420p -an odd.yuv

ffmpeg -r 2 -s WxH -i rawbitstream.yuv -filter:v select="not(mod(n-1\,2))" \
-c:v rawvideo -r 1 -format rawvideo -pix_fmt yuv420p -an even.yuv

Pour ne ffmpegpas dupliquer les images, vous devez forcer la moitié de la fréquence d'images de votre entrée - vous définissez donc "2" comme entrée et "1" pour la sortie. N'oubliez pas de remplacer le WxH par les dimensions réelles de votre clip, car le flux binaire brut n'a pas d'en-tête contenant ces informations.

Au lieu de ce qui précède, une autre possibilité serait d'ajouter le setptsfiltre pour définir de nouveaux horodatages pour la sortie. Mais soyez prudent car cela ne permet pas de supprimer les images avec précision. Ici, 25 est la fréquence d'images de sortie réelle que vous souhaitez:

ffmpeg -i input.mp4 -filter:v select="mod(n-1\,2)",setpts="N/(25*TB)" \
-c:v rawvideo -r 12.5 -format rawvideo -pix_fmt yuv420p -an odd.yuv

ffmpeg -i input.mp4 -filter:v select="not(mod(n-1\,2))",setpts="N/(25*TB)" \
-c:v rawvideo -r 12.5 -format rawvideo -pix_fmt yuv420p -an even.yuv

Vous pouvez bien sûr choisir un autre format de pixel (n'importe lequel ffmpeg -pix_fmts). Assurez-vous que lors de la lecture du fichier, vous connaissez la taille et le format des pixels:

ffmpeg -f rawvideo -s:v 1280x720 -pix_fmt yuv420p input.yuv …

Merci, pour les nouvelles versions de FFMPEG, ce devrait être -vf au lieu de -filter: v. De plus, il devrait être mod (n-1 \, 2) car le nombre n semble commencer à partir de 1 tandis que le nombre d'images à partir de 0 (sinon la première image est dupliquée 3 fois). Mais il y a toujours un problème, cela duplique les images alors que je veux m'en débarrasser - par exemple, le clip final ne contiendra que la moitié des images.
Mark

-vfest un alias de -filter:v. Je ne peux pas le tester de manière fiable maintenant, mais j'y reviendrai plus tard lorsque je serai de retour sur ma machine. Peut-être que le tinterlacefiltre peut faire la même chose?
slhck

J'ai essayé '-r 2 -i blah.yuv -r 1' mais cela me montre une erreur Framerate d'option introuvable.
Mark

Ah désolé .. Grattez ça, ça ne marche pas (plus?) Et seulement pour les images.
slhck

1
@AnmolSinghJaggi Non, cela supprime simplement les images, mais je ne serais pas sûr que ce soit si déterministe (c'est-à-dire qu'il supprime chaque image impaire). Il sera basé sur des codes temporels, qui peuvent ne pas être précis.
slhck

2

Si votre ffmpeg a été construit avec le drapeau AviSynth, je pense que vous pouvez transmettre un .avsfichier.

Vous pouvez vérifier en exécutant ffmpeget en recherchant --enable-avisynthdans les données de configuration . --enable-avisynth

Si elle est là , vous pouvez l' utiliser comme ceci: ffmpeg -i blahEven.avs blahEven.yuv.

blahEven.avsest tout simplement:

ffvideosource ("blah.yuv"). SelectEven ()

Pour les images impaires, utilisez SelectOdd().

Pour une utilisation plus avancée, consultez la documentation SelectEvery .


C'est une excellente alternative, mais comme je l'ai mentionné - je suis limité à n'utiliser que ffmpeg. La raison en est qu'il fait partie d'un système automatisé qui ne créera que des fichiers .bat, aucune possibilité d'ajout d'AVS.
Mark

@Mark Je pensais que si --enable-avisynthc'était le cas, cela signifiait qu'AviSynth était intégré à ffmpeg, mais je n'en suis pas sûr.
Louis
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.