Modifier la fréquence d'images d'une vidéo MP4 avec ffmpeg

8

J'ai une vidéo au format mp4 avec une fréquence d'images de .33(1 image pendant 3 secondes). Je souhaite augmenter la fréquence d'images à 5 images / s. J'ai essayé la commande ci-dessous mais cela ne fait rien:

ffmpeg -i <input.mp4> -r 5 <output.mp4>

Une idée pourquoi ffmpeg ignore l' -roption?

firemonkey
la source
Si vous essayez d'accélérer / ralentir une vidéo, au lieu de dupliquer / supprimer des images, consultez superuser.com/questions/854753/… et / ou askubuntu.com/questions/370692/…
Peter Cordes

Réponses:

7

Je sais que c'est une vieille question mais aucune des réponses actuelles n'est plus recommandée.

Remuxage sans perte (vidéo)

Comme indiqué dans les commentaires, il existe un moyen de le faire lorsque la vidéo n'a pas à être ré-encodée. Il nécessite le remuxage du fichier dans un format de conteneur MKV différent, puis le remuxage dans un MP4. Voici un exemple qui change une vidéo en 12 images / seconde:

mkvmerge --default-duration 0:12fps --fix-bitstream-timing-information 0 original-video.mp4 -o temp-video.mkv
ffmpeg -i temp-video.mkv -c:v copy slow-video.mp4

Si la vidéo contient de l'audio, vous pouvez également la ralentir sans modifier la hauteur, mais ce n'est pas une conversion sans perte. L'exemple ci-dessous suppose que la vidéo source était de 24 images / seconde, de sorte que l'audio devait être ralenti à la moitié (0,5) de la vitesse à l'aide du filtre atempo de ffmpeg .

mkvmerge --default-duration 0:12fps --fix-bitstream-timing-information 0 original-video.mp4 -o temp-video.mkv
ffmpeg -i temp-video.mkv -c:v copy -c:a aac -filter:a "atempo=0.5" slow-video-with-audio.mp4

FFMPEG Wiki Guidance

Ceci est le guide du wiki ffmpeg . Notez que toutes ces options nécessitent un ré-encodage de la vidéo.

Accélérer / ralentir la vidéo

Vous pouvez modifier la vitesse d'un flux vidéo à l'aide du filtre vidéo setpts. Notez que dans les exemples suivants, le flux audio n'est pas modifié, il devrait donc idéalement être désactivé avec -an.

Pour doubler la vitesse de la vidéo, vous pouvez utiliser:

ffmpeg -i input.mkv -filter:v "setpts=0.5*PTS" output.mkv

Le filtre fonctionne en modifiant l'horodatage de présentation (PTS) de chaque image vidéo. Par exemple, s'il y a deux images successives affichées aux horodatages 1 et 2 et que vous souhaitez accélérer la vidéo, ces horodatages doivent devenir respectivement 0,5 et 1. Il faut donc les multiplier par 0,5.

Notez que cette méthode supprimera les images pour atteindre la vitesse souhaitée. Vous pouvez éviter les pertes d'images en spécifiant une fréquence d'images de sortie plus élevée que l'entrée. Par exemple, pour passer d'une entrée de 4 FPS à une entrée accélérée jusqu'à 4x (16 FPS):

ffmpeg -i input.mkv -r 16 -filter:v "setpts=0.25*PTS" output.mkv

Pour ralentir votre vidéo, vous devez utiliser un multiplicateur supérieur à 1:

ffmpeg -i input.mkv -filter:v "setpts=2.0*PTS" output.mkv

Lisse

Vous pouvez lisser la vidéo lente / rapide avec le filtre vidéo minterpolate. Ceci est également connu comme "interpolation de mouvement" ou "flux optique".

ffmpeg -i input.mkv -filter "minterpolate='mi_mode=mci:mc_mode=aobmc:vsbmc=1:fps=120'" output.mkv

D'autres options incluent slowmoVideo et Butterflow. Accélérer / ralentir l'audio

Vous pouvez accélérer ou ralentir l'audio avec le filtre audio atempo. Pour doubler la vitesse de l'audio:

ffmpeg -i input.mkv -filter:a "atempo=2.0" -vn output.mkv

Le filtre atempo est limité à l'utilisation de valeurs comprises entre 0,5 et 2,0 (il peut donc le ralentir à pas moins de la moitié de la vitesse d'origine et accélérer jusqu'à pas plus du double de l'entrée). Si vous en avez besoin, vous pouvez contourner cette limitation en enchaînant plusieurs filtres atempo ensemble. Ce qui suit avec quadruple la vitesse audio:

ffmpeg -i input.mkv -filter:a "atempo=2.0,atempo=2.0" -vn output.mkv

En utilisant un filtre graphique complexe, vous pouvez accélérer la vidéo et l'audio en même temps:

ffmpeg -i input.mkv -filter_complex "[0:v]setpts=0.5*PTS[v];[0:a]atempo=2.0[a]" -map "[v]" -map "[a]" output.mkv
pseudosavant
la source
1
Il est possible d'accélérer / ralentir simplement en remuxant, mais FFmpeg ne sait pas comment le faire . par exemple pour mkv, mkvtoolnix peut le faire. Par exemple, mkvmerge --default-duration 0:24000/1001fps --fix-bitstream-timing-information 0 in.mkv -o out.mkv changer le framerate sur le conteneur MKV . Vous pouvez redistribuer vers MKV et revenir à MP4, ou trouver un outil qui le fait directement pour MP4. Le codage de la vidéo est très gourmand en CPU et avec perte, c'est donc une option horrible.
Peter Cordes
Tout à fait d'accord pour dire que le remuxage vers une fréquence d'images inférieure est préférable car il s'agit d'une approche sans perte qui nécessite beaucoup moins de ressources. En pratique, je n'ai cependant pas trouvé de bons outils pour le faire avec les MP4. Je n'ai pas essayé vraiment récemment, mais lorsque j'ai écrit cette réponse pour la première fois, je faisais du remuxage MP4-> MKV-> MP4 et je ne pouvais pas le faire fonctionner avec mkvtoolnix, ffmpeg et / ou mp4box. Je vais devoir essayer avec les paramètres que vous proposez.
pseudosavant
6

Si le fichier d'entrée n'a pas de fréquence d'images valide, vous devrez peut-être le définir explicitement

ffmpeg -r 1 -i input.mp4 -r 24 output.mp4
Martin Beckett
la source
Cela transcode lorsque vous n'avez vraiment besoin que de remuxer. (À moins que vous ne vouliez réellement dupliquer / supprimer des images au lieu de ralentir / accélérer la vidéo.)
Peter Cordes
3

Je ne pouvais obtenir le taux de rafraîchissement modifié que si le fichier d'entrée était classé comme un fichier "brut":

ffmpeg -r 5 -f h264 -i input.h264 -vcodec copy -an output.mkv

Sans spécifier, -f h264il serait par défaut à 25 fps et il ne pourrait pas être changé. Apparemment, cela était dû au fait que le flux ne contenait aucune information de fréquence d'images et qu'il s'agit de la fréquence d'images par défaut de ffmpeg.

Apparemment, lorsque vous utilisez -rune option de sortie, il duplique ou supprime des images pour que la vidéo soit lue à la même vitesse - dans ce cas, pas ce que vous voulez! Mais en changeant le framerate d'entrée comme ci-dessus, la vidéo accélérera ou ralentira, sans perte ni duplication d'images.

Malvineous
la source
1
Ma réponse utile. Pas de ré-encodage ici
yota
1

Une telle caractéristique - de changer le framerate - est appelée "conforme" et est souvent utilisée pour produire un ralenti ou une avance rapide comme montrant la croissance d'une plante en quelques minutes en quelques jours. ffmpeg n'autorise pas l'écrasement / la modification de la fréquence d'images sans réencodage . Si tel est le cas, la durée changera et l'audio sera désynchronisé, à moins d'être réparé séparément. Mais je crains que l'audio ne soit pas intéressant dans votre cas avec une fréquence d'images de 0,33

Vous voulez vous conformer parce que vous voulez juste changer le framerate, mais ffmpeg ignore -rsilencieusementsi la fréquence d'images est spécifiée dans le fichier d'entrée. Étant donné que votre fichier d'entrée est au format .mp4, son propre taux de rafraîchissement a priorité sur-rlorsque le réencodage n'est pas nécessaire. Pour cela, vous avez besoin d'un outil différent: mencoder.

En supposant que votre fichier d'entrée ne contienne aucun son - probablement vrai pour toute vidéo avec une fréquence d'images de 0,33 - ce dont vous avez besoin est:

$ mencoder -fps 5 -o <output> -ovc copy -nosound <input.mp4>

Notez que mencoder produit par défaut une sortie au format AVI.

Tankman 六四
la source
1
C'est faux. Si rest spécifié comme commutateur de sortie, ffmpeg produira une sortie à cette fréquence d'images spécifiée, quelle que soit la fréquence d'images de l'entrée. Si rest spécifié en tant que commutateur d'entrée, ffmpeg dupliquera ou supprimera les images selon les besoins pour fournir le nombre spécifié d'images par seconde d'entrée au filtre / encodeur.
Gyan
Le comportement que vous décrivez lorsqu'un rcommutateur d'entrée est en contradiction avec mon expérience précédente sur le format .mp4, la note de Malvineous (sur cette page) et la description du bogue 403 trac.ffmpeg.org/ticket/403 ; votre description lorsque rest utilisé sur la sortie se produit lors du ré-encodage, alors que le scénario de OP semble être un cas conforme (correction de la fréquence d'images sans ré-encodage) par le fait qu'il avait une fréquence d'images de 0,33.
Tankman
1
Vérifiez le rapport collé ici . Notez la ligne de commande en haut, les métadonnées d'entrée et de sortie et enfin le no. de trames codées.
Gyan
1
Il est convenu que l'OP veut simplement se conformer au fichier mais que leur commande donnée est le ré-encodage car les commutateurs de copie ne sont pas spécifiés. Dans ce scénario, ffmpeg devrait générer un nouveau flux à rfps.
Gyan
Merci Mulvya pour la sortie d'échantillon convaincante. Oui, vous avez raison sur l'utilisation de -r. Cette utilisation n'a pas pu affecter mes expériences précédentes en réponse à OP parce que, pensant à un cas conforme, je n'ai jamais laissé tomber le paramètre de copie de ffmpeg, et -rest donc ignoré. J'ai écrit une demande de fonctionnalité: trac.ffmpeg.org/ticket/5170
Tankman
0

Le moyen le plus rapide consiste à créer un fichier BAT dans le répertoire avec les lignes suivantes:

@ECHO OFF

for %%f in (*.mp4) do (

echo “fullname: %%f”

del temp.mkv

mkvmerge --default-duration 0:18fps --fix-bitstream-timing-information 0 %%f -o temp.mkv

del %%f

ffmpeg -i temp.mkv -c:v copy %%f

del temp.mkv

)

Vous devez avoir mkvmerge et ffmpeg dans le même répertoire. Il change automatiquement chaque fichier mp4 en quelques secondes sans perte de qualité.

Peder Gerdin
la source