J'ai une vidéo mkv (h264) de 23,976 i/s (24000/1001) mais je souhaite la convertir à 25 i/s sans réencodage ni perte de qualité. Je sais que mkvmerge peut le faire (avec l'option --default-duration '0: 25fps') mais j'aimerais le faire directement depuis ffmpeg si possible. Selon la documentation, cela devrait fonctionner:
ffmpeg -i input.mkv -r 25 -vcodec copy output.mkv
mais quand je l'exécute, je ne reçois que les mêmes images par seconde. Quelle est la bonne méthode pour le faire (s'il existe) dans ffmpeg?
Voici la méthode utilisant les versions actuelles de FFmpeg. Il repose sur le démultiplexeur concat ne pas redimensionner le PTS des entrées après le premier fichier, mais simplement appliquer un décalage fixe. Supposons que vous ayez un flux de 30 images par seconde avec une échelle de temps de 15360
(typique de la sortie FFmpeg). Cela signifie que frame 0
a PTS 0
et frame 30
a PTS 15360
. Cela deviendrait un flux de 45 ips si nous pouvions changer l’échelle de temps en 23040
sans affecter les valeurs PTS.
C'est essentiellement ce que fait la méthode ci-dessous.
1 . Identifiez les propriétés de la source.
Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 1171 kb/s,
30 fps, 30 tbr, 15360 tbn (default)
Vous souhaitez noter les propriétés source, en particulier résolution et tbn
name__.
2a . (Facultatif) Modifiez l’échelle de temps en fonction de vos besoins afin de simplifier les calculs.
ffmpeg -i in.mp4 -c copy -an -video_track_timescale 30 in-v30.mp4
Cela nous obtient
Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 1171 kb/s, \
30 fps, 30 tbr, 30 tbn (default
Si vous faites cette étape, la nouvelle échelle de temps doit être égale ou un multiple entier de la fréquence d'images d'origine.
2b . Calculez l'échelle de temps nécessaire pour que, pour le framerate cible x
name__, le PTS de l'image # x
dans la source ait la même valeur que le nouveau tbn
name__. Si vous avez effectué l'étape 2a, c'est très simple et il ne s'agit que du nouveau framerate. Ainsi, pour les images cibles 45
, new tbn
devrait être 45
.
3 . Générer une vidéo factice.
ffmpeg -f lavfi -i color=s=1280x720:r=45:d=1 -profile:v main -video_track_timescale 45 0.mp4
Toutes les propriétés doivent être identiques (résolution, profil H.264, format de pixel, nombre de références, etc.) pour obtenir les meilleurs résultats.
4 Concattez les vidéos.
Commencez par créer un fichier texte
file '0.mp4'
file 'in-v30.mp4'
Ensuite, le concat
ffmpeg -f concat -i list.txt -c copy -video_track_timescale 45 45fps.mp4
La deuxième vidéo sera lue à 45 ips dans le fichier de sortie.
5 . Maintenant, cliver le preroll factice
ffmpeg -ss 1.1 -i 45fps.mp4 -c copy -avoid_negative_ts make_zero in45.mp4
et tu as
Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 1757 kb/s, \
45 fps, 45 tbr, 11520 tbn (default)
J'ai dit que c'était compliqué!