Coupez avec précision les fichiers vidéo de la ligne de commande

22

J'ai du mal à trouver une application cli qui peut prendre un fichier vidéo (avi, mkv et mp4 de préférence) et découper des clips très courts (2-6 secondes) avec une précision temporelle précise. J'ai essayé ffmpeg , mencoder , avidemux et mp4box mais ils ont tous découpé des images clés, ce qui crée des clips de plus de 6 secondes. Existe-t-il un outil qui réencodera le fichier d'entrée et réduira l'heure exacte ou coupera de manière inexacte, réencodera, puis coupera avec précision?

curmil
la source
Vous devrez probablement recoder avant de couper pour bien faire les choses. Vous pouvez probablement accélérer les choses en supprimant d'abord les images clés environnantes et en réencodant uniquement les extraits.
Nifle
4
Quelle commande FFmpeg avez-vous essayée exactement? Je crois que si vous décodez la vidéo avant (c'est-à-dire que vous placez le -ssparamètre après -i ), elle devrait être plus précise.
slhck
1
L'astuce FFmpeg a fonctionné! Je ne savais pas que l'ordre importait autant. Est-ce la même chose pour les autres outils?
curmil

Réponses:

23

Couper la vidéo avec ffmpeg

Vous pouvez couper avec précision des vidéos avec FFmpeg. Depuis la version 2.5, c'est très simple. Cela réduirait par exemple 10 secondes, à partir de 0 minute, 3 secondes et 123 millisecondes.

ffmpeg -ss 00:00:03.123 -i input.mp4 -t 10 -c:v libx264 -c:a copy out.mp4

La position et l'heure peuvent être en secondes ou en hh:mm:ss[.xxx]forme.

Notez que dans ces exemples, la vidéo sera ré-encodée à l'aide de l' encodeur x264 ; l'audio est copié.

Vous pouvez également utiliser -toau lieu de -tpour spécifier le point final au lieu de la durée. Dans ce cas, cependant, -toest équivalent à -t, car en mettant le -ssdevant -i, ffmpeg cherchera d'abord à ce point puis commencera à sortir.

Voir aussi l' entrée du wiki à la recherche .


Coupe précise pour les anciennes ffmpegversions

Si vous avez une ancienne version de ffmpeg, pour une recherche précise, vous devez placer l' -ssafter -i, ce qui rend le processus d'encodage un peu plus lent, car la vidéo entière doit d'abord être décodée:

ffmpeg -i input.mp4 -ss 00:00:03.123 -t 10 -c:v libx264 -c:a copy out.mp4

Ici, -toet -tse comporter différemment. -t 10créerait un clip de dix secondes, tandis -to 10que créerait un clip de sept secondes.

slhck
la source
Au lieu de -c:v libx264 -c:a libfaacje pense que nous pouvons utiliser -acodec copy -vcodec copyce qui indique à ffmpeg de détecter et d'utiliser les mêmes codecs que le fichier d'origine. Quelqu'un peut-il confirmer?
Baodad
2
@Baodad Vous pouvez, mais cela ne coupera pas avec précision . Lors de la copie de flux binaires vidéo / audio, ffmpeg doit commencer par une image clé, qui peut juste être placée à chaque seconde ou même plus loin.
slhck
Comment surmonter l'erreur "Encodeur inconnu 'libfaac'"?
Doug
@Doug Choisissez un autre encodeur, par exemple -c:a aac -strict experimental. C'est la solution la plus simple.
slhck
1

Le seul outil de ligne de commande Linux que j'ai trouvé jusqu'à présent, qui peut couper à l'image exacte (ou, avec une précision d'image), est melt( sudo apt-get install melt).

Disons que vous avez un inputvid.mp4- vérifiez d'abord ses paramètres d'encodage avec say ffmpeg(ici, je dis simplement que je veux le recoder -f mp4, mais comme le fichier de /dev/nullsorte que la sortie est supprimée; je redirige stderr afin que je puisse le parcourir - note au milieu , la commande vous invite, et vous devez répondre yavec ENTER, afin que le processus se poursuive et vide les informations utiles; c'est avec ffmpeg 3.3.3 sur Ubuntu 14):

ffmpeg -i inputvid.mp4 -f mp4 /dev/null 2>&1 | grep 'Stream\|encoder'
    Stream #0:0(und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p(tv, bt709), 640x360 [SAR 1:1 DAR 16:9], 389 kb/s, 23.98 fps, 23.98 tbr, 24k tbn, 47.95 tbc (default)
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 95 kb/s (default)
y
File '/dev/null' already exists. Overwrite ? [y/N] Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
  Stream #0:1 -> #0:1 (aac (native) -> aac (native))
    encoder         : Lavf57.71.100
    Stream #0:0(und): Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv420p(progressive), 640x360 [SAR 1:1 DAR 16:9], q=-1--1, 23.98 fps, 24k tbn, 23.98 tbc (default)
      encoder         : Lavc57.89.100 libx264
    Stream #0:1(und): Audio: aac (LC) ([64][0][0][0] / 0x0040), 44100 Hz, stereo, fltp, 128 kb/s (default)
      encoder         : Lavc57.89.100 aac

Ok, donc nous pouvons voir les ffmpegchoix libx264et les aacencodeurs pour cette vidéo; alors nous pouvons saisir ceci pour melt:

melt inputvid.mp4 in=7235 out=7349 -consumer avformat:cut.mp4 acodec=aac vcodec=libx264

.... et meltcoupera avec la pièce entre les cadres et 7235 7349 dans un nouveau fichier, cut.mp4. Ensuite, pour vérifier si les cut.mp4boucles sont correctes, utilisez à meltnouveau pour les lire deux fois - et lisez-les dans une fenêtre SDL:

melt cut.mp4 cut.mp4 -consumer sdl

... et voici ce que ffmpegvoit ce fichier:

ffmpeg -i cut.mp4 -f mp4 /dev/null 2>&1 | grep 'Stream\|encoder'    encoder         : Lavf54.20.4
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 640x360 [SAR 1:1 DAR 16:9], 526 kb/s, 23.98 fps, 23.98 tbr, 24k tbn, 47.95 tbc (default)
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 182 kb/s (default)
y
File '/dev/null' already exists. Overwrite ? [y/N] Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
  Stream #0:1 -> #0:1 (aac (native) -> aac (native))
    encoder         : Lavf57.71.100
    Stream #0:0(und): Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv420p, 640x360 [SAR 1:1 DAR 16:9], q=-1--1, 23.98 fps, 24k tbn, 23.98 tbc (default)
      encoder         : Lavc57.89.100 libx264
    Stream #0:1(und): Audio: aac (LC) ([64][0][0][0] / 0x0040), 48000 Hz, stereo, fltp, 128 kb/s (default)
      encoder         : Lavc57.89.100 aac

Les paramètres de codage vidéo cut.mp4semblent être identiques à, inputvid.mp4sauf le débit binaire vidéo changé de 389 kb / s à 526 kb / s, et les paramètres de codage audio sont également presque les mêmes, sauf que la fréquence d'échantillonnage est passée de 44100 à 48000 Hz; bien que cela puisse être réglementé avec:

melt inputvid.mp4 in=7235 out=7349 -consumer avformat:cut.mp4 acodec=aac ar=44100 ab=95k vcodec=libx264 vb=389k

... cependant, même avec cela, le bitrate vidéo final pour moi finit par 337 kb / s. Pourtant, les coupes bouclent bien (et cela inclut l'audio) lorsqu'elles sont jouées en boucle, donc je suppose que c'est en effet une image précise ...

sdaau
la source
1
meltréencode la vidéo et utilise les bibliothèques FFmpeg en dessous. Si vous autorisez le ré-encodage, ffmpeg peut produire la même sortie.
Gyan
Merci @Gyan - n'était pas au courant (en particulier qui meltutilise les bibliothèques FFmpeg), bon à savoir!
sdaau
melt semble plus facile à utiliser que ffmpeg, tout ce dont nous avons besoin est un moyen de spécifier les heures, en particulier les heures en heures, minutes, secondes ou en heures, minutes, secondes, ms, qui les convertit dans le cadre de droite.
barlop
0

Comme Baodad l'a dit dans les commentaires (je poste car il n'est pas facile de trouver si vous lisez rapidement), la meilleure approche est de détecter automatiquement les encodeurs audio / vidéo par ffmpeg, donc:

ffmpeg -ss 00:05:17.18 -i in.mp4 -t 00:06:29.10 -acodec copy -vcodec copy out.mp4 
  • start @ 00: 05: 17.18
  • input = in.mp4
  • arrêt @ 00: 06: 29.10
  • sortie = out.mp4
Gilles Quenot
la source
2
Cela ne réencode pas et ne fournit pas de précision de trame.
Andrea Lazzarotto