116 votes

Utilisation de ffmpeg pour changer le framerate

J'essaie de convertir un clip vidéo (MP4, yuv420p) de 30 ips à 24 ips. Le nombre d'images est correct et mon résultat devrait passer de 20 minutes à 30 images par seconde à 25 minutes à 24 images par seconde. Tout le reste devrait rester inchangé.

J'ai beau essayer, tout ce que j'essaie avec ffmpeg convertit la fréquence d'images mais change le nombre d'images pour garder la même durée ou change la durée sans modifier la fréquence d'images.

Donc j'ai typiquement essayé des choses comme ;

ffmpeg -y -r 30 -i seeing_noaudio.mp4 -r 24 seeing.mp4

(Je fais cela sous Windows mais normalement je le ferais sous linux). Cela permet de convertir le taux de rafraîchissement mais en supprimant des images pour que la durée totale reste inchangée.

Ou j'ai essayé

ffmpeg -y -i seeing_noaudio.mp4 -filter:v "setpts=1.25*PTS" seeing.mp4

Ce qui change la durée mais pas le framerate.

Je devrais sûrement pouvoir le faire avec une seule commande ffmpeg sans avoir à réencoder ou même, comme certains l'ont suggéré, à revenir aux images brutes originales.

Aide, s'il vous plaît

110voto

Gyan Points 28168

Avec ré-encodage :

ffmpeg -y -i seeing_noaudio.mp4 -vf "setpts=1.25*PTS" -r 24 seeing.mp4

Sans ré-encodage :

Première étape - extraire la vidéo en flux binaire brut

ffmpeg -y -i seeing_noaudio.mp4 -c copy -f h264 seeing_noaudio.h264

Remux avec nouveau framerate

ffmpeg -y -r 24 -i seeing_noaudio.h264 -c copy seeing.mp4

1 votes

Merci pour cela. Le premier a fonctionné, mais pas le second, qui renvoie un message d'erreur du type "Could not write header for output file #0 (incorrect codec parameters ?) : Invalid argument". Je n'ai aucune idée de ce que cela signifie, mais le premier a fonctionné.

0 votes

On dirait que le codec vidéo n'est pas H.264. Lequel est-ce ?

0 votes

-filter:v fps OU -r fps . lequel est préféré ?

77voto

kelin Points 5278

Vous pouvez envisager d'utiliser fps filtre. Il ne modifie pas la vitesse de lecture de la vidéo :

ffmpeg -i <input> -filter:v fps=fps=30 <output>

Ça a bien marché pour réduire les fps de 59,6 à 30.

6 votes

Cela fonctionne pour garder l'audio en synchronisation avec la vidéo, merci.

2 votes

Nice btw il s'avère que vous pouvez utiliser cette commande pour réduire la taille des enregistrements OBS par un facteur ~2 sans sacrifier ni la qualité ni la fluidité (si vous utilisez 60fps changer pour fps=fps=60). Toutes les autres commandes, y compris le réencodage avec la meilleure qualité possible avec x264/nvenc ont donné des artefacts visibles.

5 votes

Pourquoi utiliser fps=fps= en spécifiant deux fois les mots-clés ? merci

31voto

MKaama Points 972

Il suffit de spécifier le taux de rafraîchissement souhaité dans l'option "-r" avant le fichier d'entrée :

ffmpeg -y -r 24 -i seeing_noaudio.mp4 seeing.mp4

Les options affectent le fichier suivant après elles. "-r" devant un fichier d'entrée force à réinterpréter son en-tête comme si la vidéo était encodée au framerate donné. Aucune recompression n'est nécessaire. Il y avait un petit utilitaire avifrate.exe La commande ffmpeg ci-dessus fait essentiellement la même chose, mais doit copier le fichier entier.

0 votes

Aucune des deux réponses ne fonctionne pour moi avec un fichier VP8 WebM (que j'essaie de ralentir de 25 fps à 6 fps sans ré-encodage). La vidéo de sortie est identique à celle d'entrée.

14 votes

Cela ne change pas du tout la fréquence d'images du fichier de sortie pour moi.

0 votes

Cela fonctionne pour moi en réduisant la fréquence d'images mais cela désynchronise l'audio.

5voto

Elder Geek Points 322

A ma connaissance, vous ne pouvez pas faire cela avec ffmpeg sans ré-encodage. J'avais un fichier de 24 images par seconde que je voulais convertir en 25 images par seconde pour qu'il corresponde à un autre matériel sur lequel je travaillais. J'ai utilisé la commande ffmpeg -i inputfile -r 25 outputfile qui fonctionne parfaitement avec une entrée webm, matroska et donne une sortie h264, matroska en utilisant l'encodeur : Lavc56.60.100

Vous pouvez accomplir la même chose à 6 images par seconde mais, comme vous l'avez noté, la durée ne changera pas (ce qui, dans la plupart des cas, est une bonne chose car, sinon, vous perdrez la synchronisation audio). Si cela ne correspond pas à vos besoins, je vous suggère d'essayer les options suivantes cette réponse bien que, d'après mon expérience, il ré-encode toujours le fichier de sortie.

Pour la meilleure précision d'image, vous êtes toujours mieux de décoder en flux bruts comme suggéré précédemment. J'utilise un script pour cela comme reproduit ci-dessous :

#!/bin/bash
#This script will decompress all files in the current directory, video to huffyuv and audio to PCM
#unsigned 8-bit and place the output #in an avi container to ease frame accurate editing.
for f in *
do
ffmpeg -i "$f" -c:v huffyuv -c:a pcm_u8 "$f".avi
done

Il est clair que ce script s'attend à ce que tous les fichiers du répertoire actuel soient des fichiers médias, mais il peut facilement être modifié pour restreindre le traitement à une extension spécifique de votre choix. Sachez que la taille de votre fichier augmentera d'un facteur assez important lorsque vous décompresserez en flux bruts.

2voto

Tim Le Points 107

Vous pouvez utiliser cette commande et la durée de la vidéo reste inchangée.

ffmpeg -i input.mp4 -r 24 output.mp4

0 votes

Si vous faites cela, votre vidéo sera coupée. Vous devez spécifier le -r avant le fichier d'entrée.

2 votes

@zenw0lf coupé comment ? Je l'ai testé et cela a bien fonctionné. C'est documenté sur le site de ffmpeg.

2 votes

Après avoir utilisé cette option, ma vidéo a juste été étirée de 5 à 10 minutes.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X