Encoder une vid=c3=a9o pour en modifier la vitesse
Le
Francois Lafont

Bonjour à tous,
Je suis sous Ubuntu 18.04 et je cherche (pour un usage perso) à modifier
la vitesse de vidéos .mp4 prises avec mon smartphone. Je préviens, je n'y
connais rien encodage de vidéos. Point important peut-être, je me moque
de l'audio, la vidéo que je génère n'a pas de son (seule l'image m'importe).
En cherchant sur le Web, c'est vers ffmpeg que je me suis tourné mais je
n'ai aucune préférence, si un autre outil peut faire le job, je suis preneur.
Un peu par tâtonnement, j'ai trouvé cette commande qui me semble marcher :
factor=0.1 # Pour avoir une vitesse « x 0,1 » (ie 10 fois plus lente)
ffmpeg -i myvideo.mp4 -vf "setpts=(1/$factor)*PTS" -an
-max_muxing_queue_size 4000 myvideo-slow.mp4
L'option « -max_muxing_queue_size 4000 », je l'ai mise car, sur certaines de
mes vidéos, je suis tombé sur le message d'erreur :
Too many packets buffered for output stream 0:0
et avec l'option l'erreur disparaissait (constat empirique).
Voici mes questions :
1. Est-ce que la façon de faire ci-dessus est correcte d'après vous ?
Peut-être qu'il existe des outils plus simples pour faire cela ?
2. En fait, je pensais que modifier la vitesse d'une vidéo était une
opération rapide où il fallait juste modifier une sorte de metadata du
fichier vidéo (une peu comme on modifierait un header dans une requête
HTTP). Mais je constate que :
a) l'encodage prend du temps (qq dizaines de secondes pour une vidéo
de 38MB en entrée);
b) la taille de la vidéo générée est plus grosse que la vidéo en
entrée (toujours avec mon exemple de vidéo de 38MB en entrée,
la vidéo « ralentie » générée fait 53MB).
Mon idée de la metadata à modifier est donc fausse ? C'est plus compliqué
que ça ? Certains players sont capables de lire une vidéo plus lentement
et pourtant j'imagine qu'ils ne réencodent pas la vidéo à la volée, non ?
3. Avec ma commande, j'ai parfois les messages suivants :
More than 1000 frames duplicated
Ils sont en jaune dans mon terminal, comme si c'était un warning ou une
erreur. Est-ce grave ?
Merci d'avance pour votre aide.
--
François Lafont
Je suis sous Ubuntu 18.04 et je cherche (pour un usage perso) à modifier
la vitesse de vidéos .mp4 prises avec mon smartphone. Je préviens, je n'y
connais rien encodage de vidéos. Point important peut-être, je me moque
de l'audio, la vidéo que je génère n'a pas de son (seule l'image m'importe).
En cherchant sur le Web, c'est vers ffmpeg que je me suis tourné mais je
n'ai aucune préférence, si un autre outil peut faire le job, je suis preneur.
Un peu par tâtonnement, j'ai trouvé cette commande qui me semble marcher :
factor=0.1 # Pour avoir une vitesse « x 0,1 » (ie 10 fois plus lente)
ffmpeg -i myvideo.mp4 -vf "setpts=(1/$factor)*PTS" -an
-max_muxing_queue_size 4000 myvideo-slow.mp4
L'option « -max_muxing_queue_size 4000 », je l'ai mise car, sur certaines de
mes vidéos, je suis tombé sur le message d'erreur :
Too many packets buffered for output stream 0:0
et avec l'option l'erreur disparaissait (constat empirique).
Voici mes questions :
1. Est-ce que la façon de faire ci-dessus est correcte d'après vous ?
Peut-être qu'il existe des outils plus simples pour faire cela ?
2. En fait, je pensais que modifier la vitesse d'une vidéo était une
opération rapide où il fallait juste modifier une sorte de metadata du
fichier vidéo (une peu comme on modifierait un header dans une requête
HTTP). Mais je constate que :
a) l'encodage prend du temps (qq dizaines de secondes pour une vidéo
de 38MB en entrée);
b) la taille de la vidéo générée est plus grosse que la vidéo en
entrée (toujours avec mon exemple de vidéo de 38MB en entrée,
la vidéo « ralentie » générée fait 53MB).
Mon idée de la metadata à modifier est donc fausse ? C'est plus compliqué
que ça ? Certains players sont capables de lire une vidéo plus lentement
et pourtant j'imagine qu'ils ne réencodent pas la vidéo à la volée, non ?
3. Avec ma commande, j'ai parfois les messages suivants :
More than 1000 frames duplicated
Ils sont en jaune dans mon terminal, comme si c'était un warning ou une
erreur. Est-ce grave ?
Merci d'avance pour votre aide.
--
François Lafont
[...]
Je précise que j'ai aussi regardé du côté du programme "mpv" qui avait
l'air de pouvoir faire plein de choses (comme du cropping ce qui pouvait
m'intéresser) mais je n'ai jamais réussi à modifier la vitesse de la
vidéo générée avec "mpv". Si quelqu'un sait comment faire avec "mpv",
ça m'intéresse.
--
François Lafont
0. As-tu essayé de poser la question dans le groupe ad hoc ?
--
16:17 gege> Java en édition light, ca fait Java LE ? Ca sux...
L'audio n'est pas un problème, il y a un filtre efficace pour changer la
vitesse.
C'est un bon début.
L'avertissement disparaît, pas le problème sous-jacent. À première vue,
j'aurais pensé qu'il était causé par l'audio, mais -an est présent. Il
faudrait voir la sortie de diagnostic complète pour voir ce qui peut
clocher.
Oui, ta ligne de commande transcode la vidéo. Tu peux l'éviter avec « -c
copy », mais alors les filtres ne sont plus appliqués. Mais pour changer
la vitesse, si l'entrée a un débit d'images constant, l'option -r en
entrée devrait suffire.
Tu n'as spécifié aucune option pour la qualité, donc tu te retrouves
avec les valeurs par défaut.
Partiellement. Dans les formats décents, chaque paquet est marqué par le
temps où il est censé arriver, c'est ça qu'il faut ajuster. C'est plus
qu'une donnée globale pour le fichier, mais ça ne nécessite pas de tout
réencoder.
Oui. Mais pour voir pourquoi, il faudrait voir la sortie complète.
On 5/2/19 10:03 AM, Jo Engo wrote:
Non. Je vais éviter de multiplier les fils de discussion maintenant que j'ai
posté ici mais je garde en tête cette possibilité si jamais mon fil n'aboutit
pas et tombe dans les oubliettes. ;)
--
François Lafont
Sans -an, c'est normal : tu ralentis la vidéo mais pas l'audio, donc les
paquets vidéos doivent être mis en attente le temps que les paquets
audio les rattrapent.
Cette version de ffmpeg semble médiocrement compilée.
L'option -r en entrée est censée marcher, mais elle cassez de temps en
temps. Essaie avec la toute dernière version, et si ça ne marche
signale-le sur le bug-tracker.
Probablement, mais ce n'est pas certain. Le MP4 est vraiment un format pourri.
Si on ne transcode pas, la sortie est identique à l'original. Si on
transcode, cette notion n'a pas de sens rigoureusement défini.
Le verbose est rarement utile, en fait.
Voilà le problème : l'entrée semble être à 240 images par seconde, comme
tu l'as dit. Donc la sortie est mise au même rythme. Or le muxer MP4 de
ffmpeg ne supporte que les débits d'image constants. Donc il va chercher
à faire vraiment du 240 images par seconde, en décuplant chaque image.
Il faudrait préciser -r en sortie.
Ok.
C'est la version packagée dans Ubuntu 18.04.
Ok, je testerai.
Et bien, sauf erreur, ça ne marche pas où alors je n'ai pas fait comme il
fallait :
---------------------------------------------------------
$ ffmpeg -i myvideo.mp4 -an -c copy -r 10 myvideo-slow.mp4; echo $?
ffmpeg version 3.4.4-0ubuntu0.18.04.1 Copyright (c) 2000-2018 the FFmpeg developers
built with gcc 7 (Ubuntu 7.3.0-16ubuntu3)
configuration: [...]
avcodec configuration: [...]
libavutil 55. 78.100 / 55. 78.100
libavcodec 57.107.100 / 57.107.100
libavformat 57. 83.100 / 57. 83.100
libavdevice 57. 10.100 / 57. 10.100
libavfilter 6.107.100 / 6.107.100
libavresample 3. 7. 0 / 3. 7. 0
libswscale 4. 8.100 / 4. 8.100
libswresample 2. 9.100 / 2. 9.100
libpostproc 54. 7.100 / 54. 7.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'myvideo.mp4':
Metadata:
major_brand : mp42
minor_version : 0
compatible_brands: isommp42
creation_time : 2019-05-01T15:10:26.000000Z
location : +48.7367+002.2386/
location-eng : +48.7367+002.2386/
com.android.version: 9
com.android.capture.fps: 240.000000
Duration: 00:00:03.97, start: 0.000000, bitrate: 72422 kb/s
Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709/bt709/smpte170m), 1920x1080, 72527 kb/s, SAR 1:1 DAR 16:9, 239.68 fps, 240 tbr, 90k tbn, 180k tbc (default)
Metadata:
rotate : 90
creation_time : 2019-05-01T15:10:26.000000Z
handler_name : VideoHandle
Side data:
displaymatrix: rotation of -90.00 degrees
Stream #0:1(eng): Audio: aac (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 256 kb/s (default)
Metadata:
creation_time : 2019-05-01T15:10:26.000000Z
handler_name : SoundHandle
Output #0, mp4, to 'myvideo-slow.mp4':
Metadata:
major_brand : mp42
minor_version : 0
compatible_brands: isommp42
com.android.capture.fps: 240.000000
location : +48.7367+002.2386/
location-eng : +48.7367+002.2386/
com.android.version: 9
encoder : Lavf57.83.100
Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709/bt709/smpte170m), 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 72527 kb/s, 239.68 fps, 240 tbr, 10240 tbn, 10 tbc (default)
Metadata:
rotate : 90
creation_time : 2019-05-01T15:10:26.000000Z
handler_name : VideoHandle
Side data:
displaymatrix: rotation of -90.00 degrees
Stream mapping:
Stream #0:0 -> #0:0 (copy)
Press [q] to stop, [?] for help
frame= 946 fps=0.0 q=-1.0 Lsize= 34955kB time :00:03.94 bitrater623.8kbits/s speed= 182x
video:34945kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.029969%
0
---------------------------------------------------------
Et la vidéo générée a toujours une vitesse identique à l'originale.
--
François Lafont
Je viens de tester avec la dernière version de ffmpeg (sauf erreur) et j'ai
toujours une vidéo générée de vitesse identique à la vidéo d'origine. J'ai
tenté avec -r en entrée puis avec -r en sortie. Voici les commandes :
-------------------------------------------------------------------
$ pwd
/home/flaf/tmp/ffmpeg-git-amd64-static/ffmpeg-git-20190429-amd64-static
$ ./ffmpeg -r 10 -i myvideo.mp4 -an -c copy myvideo-slow.mp4; echo $?
ffmpeg version N-48722-gac551c54b1-static https://johnvansickle.com/ffmpeg/ Copyright (c) 2000-2019 the FFmpeg developers
built with gcc 6.3.0 (Debian 6.3.0-18+deb9u1) 20170516
configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio
--disable-outdev=sndio --cc=gcc-6 --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gmp
--enable-gray --enable-libaom --enable-libfribidi --enable-libass --enable-libvmaf --enable-libfreetype
--enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg
--enable-librubberband --enable-libsoxr --enable-libspeex --enable-libvorbis --enable-libopus
--enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvpx --enable-libwebp
--enable-libx264 --enable-libx265 --enable-libxml2 --enable-libdav1d --enable-libxvid --enable-libzvbi
--enable-libzimg
libavutil 56. 26.100 / 56. 26.100
libavcodec 58. 52.100 / 58. 52.100
libavformat 58. 27.103 / 58. 27.103
libavdevice 58. 7.100 / 58. 7.100
libavfilter 7. 50.100 / 7. 50.100
libswscale 5. 4.100 / 5. 4.100
libswresample 3. 4.100 / 3. 4.100
libpostproc 55. 4.100 / 55. 4.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'myvideo.mp4':
Metadata:
major_brand : mp42
minor_version : 0
compatible_brands: isommp42
creation_time : 2019-05-01T15:10:26.000000Z
location : +48.7367+002.2386/
location-eng : +48.7367+002.2386/
com.android.version: 9
com.android.capture.fps: 240.000000
Duration: 00:00:03.97, start: 0.000000, bitrate: 72422 kb/s
Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709/bt709/smpte170m), 1920x1080, 72527 kb/s, SAR 1:1 DAR 16:9, 239.68 fps, 240 tbr, 90k tbn, 180k tbc (default)
Metadata:
rotate : 90
creation_time : 2019-05-01T15:10:26.000000Z
handler_name : VideoHandle
Side data:
displaymatrix: rotation of -90.00 degrees
Stream #0:1(eng): Audio: aac (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 256 kb/s (default)
Metadata:
creation_time : 2019-05-01T15:10:26.000000Z
handler_name : SoundHandle
Output #0, mp4, to 'myvideo-slow.mp4':
Metadata:
major_brand : mp42
minor_version : 0
compatible_brands: isommp42
com.android.capture.fps: 240.000000
location : +48.7367+002.2386/
location-eng : +48.7367+002.2386/
com.android.version: 9
encoder : Lavf58.27.103
Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709/bt709/smpte170m), 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 72527 kb/s, 239.68 fps, 240 tbr, 10240 tbn, 10 tbc (default)
Metadata:
rotate : 90
creation_time : 2019-05-01T15:10:26.000000Z
handler_name : VideoHandle
Side data:
displaymatrix: rotation of -90.00 degrees
Stream mapping:
Stream #0:0 -> #0:0 (copy)
Press [q] to stop, [?] for help
frame= 946 fps=0.0 q=-1.0 Lsize= 34955kB time :00:03.94 bitrater623.8kbits/s speed= 193x
video:34945kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.029966%
0
$ ./ffmpeg -i myvideo.mp4 -an -c copy -r 10 myvideo-slow.mp4; echo $?
ffmpeg version N-48722-gac551c54b1-static https://johnvansickle.com/ffmpeg/ Copyright (c) 2000-2019 the FFmpeg developers
built with gcc 6.3.0 (Debian 6.3.0-18+deb9u1) 20170516
configuration: [...]
libavutil 56. 26.100 / 56. 26.100
libavcodec 58. 52.100 / 58. 52.100
libavformat 58. 27.103 / 58. 27.103
libavdevice 58. 7.100 / 58. 7.100
libavfilter 7. 50.100 / 7. 50.100
libswscale 5. 4.100 / 5. 4.100
libswresample 3. 4.100 / 3. 4.100
libpostproc 55. 4.100 / 55. 4.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'myvideo.mp4':
Metadata:
major_brand : mp42
minor_version : 0
compatible_brands: isommp42
creation_time : 2019-05-01T15:10:26.000000Z
location : +48.7367+002.2386/
location-eng : +48.7367+002.2386/
com.android.version: 9
com.android.capture.fps: 240.000000
Duration: 00:00:03.97, start: 0.000000, bitrate: 72422 kb/s
Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709/bt709/smpte170m), 1920x1080, 72527 kb/s, SAR 1:1 DAR 16:9, 239.68 fps, 240 tbr, 90k tbn, 180k tbc (default)
Metadata:
rotate : 90
creation_time : 2019-05-01T15:10:26.000000Z
handler_name : VideoHandle
Side data:
displaymatrix: rotation of -90.00 degrees
Stream #0:1(eng): Audio: aac (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 256 kb/s (default)
Metadata:
creation_time : 2019-05-01T15:10:26.000000Z
handler_name : SoundHandle
Output #0, mp4, to 'myvideo-slow.mp4':
Metadata:
major_brand : mp42
minor_version : 0
compatible_brands: isommp42
com.android.capture.fps: 240.000000
location : +48.7367+002.2386/
location-eng : +48.7367+002.2386/
com.android.version: 9
encoder : Lavf58.27.103
Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709/bt709/smpte170m), 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 72527 kb/s, 239.68 fps, 240 tbr, 10240 tbn, 10 tbc (default)
Metadata:
rotate : 90
creation_time : 2019-05-01T15:10:26.000000Z
handler_name : VideoHandle
Side data:
displaymatrix: rotation of -90.00 degrees
Stream mapping:
Stream #0:0 -> #0:0 (copy)
Press [q] to stop, [?] for help
frame= 946 fps=0.0 q=-1.0 Lsize= 34955kB time :00:03.94 bitrater623.8kbits/s speed= 204x
video:34945kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.029966%
0
-------------------------------------------------------------------
Est-ce qu'il faut considérer qu'il y a un bug ou je m'y suis mal pris ?
--
François Lafont
C'est bien ce que je disais...
Il faut utiliser l'option -r en sortie avec setpts, et donc sans -c
copy.
Mais a bien dix images par seconde.
Erreur : 32 commits de retard. Aucun n'est en rapport avec le problème,
mais ça aurait pu si c'est un bug qui a été réintroduit récemment.
Il vaut mieux compiler soi-même.
De mémoire, c'est censé marcher. Manifestement, ce n'est pas le cas,
donc...
Oui.
Accessoirement :
... est avantageusement remplacé par « setopt printexitvalue » dans zsh.
On 5/3/19 11:15 AM, Nicolas George wrote:
Pour information, j'ai tenté un bug report ici :
https://trac.ffmpeg.org/ticket/7911
À suivre...
--
François Lafont