Répéter / boucle la vidéo d'entrée avec ffmpeg?

52

Je veux juste boucler une vidéo mp4 avec ffmpeg et conserver les paramètres et le codec actuels.

Par exemple, si input.mp4 a une longueur de 0:10 et que je voudrais le boucler 4 fois, alors output.mp4 a une durée de 0:40, comment pourrais-je modifier la ligne de commande suivante pour le faire?

ffmpeg -i input.mp4 -c copy output.mp4

J'ai essayé...

ffmpeg -loop 4 -i input.mp4 -c copy output.mp4

... mais je reçois le message d'erreur "Option loop not found".

Thomas King
la source
Utilisez quicktime 7 pro et mov container. Ainsi, vous n’obtiendrez pas une taille de fichier supérieure à celle d’opensource.
Дмитрий Мышков le

Réponses:

70

Démultiplexeur

Cela vous permet de boucler une entrée sans avoir à ré-encoder.

  1. Faire un fichier texte. Contenu d'un exemple de fichier texte à répéter 4 fois.

    file 'input.mp4'
    file 'input.mp4'
    file 'input.mp4'
    file 'input.mp4'
    
  2. Puis lancez ffmpeg:

    ffmpeg -f concat -i list.txt -c copy output.mp4
    

Pour les utilisateurs de Linux

Cet exemple est le même que ci-dessus mais vous n'avez pas à faire manuellement list.txt:

for i in {1..4}; do printf "file '%s'\n" input.mp4 >> list.txt; done
ffmpeg -f concat -i list.txt -c copy output.mp4

Avec les coques modernes les plus couramment utilisées, vous pouvez même éviter list.txtentièrement la création du fichier. Par exemple, avec bash:

ffmpeg -f concat -i <(for i in {1..4}; do printf "file '%s'\n" input.mp4; done) -c copy output.mp4

Regarde aussi:


filtre de boucle

Exemple utilisant le filtre de boucle pour boucler 4 fois, chaque boucle est de 75 images, chaque boucle ignore les 25 premières images de l’entrée:

ffmpeg -i input -filter_complex loop=loop=3:size=75:start=25 output
  • Ou utilisez le raccourci: loop=3:75:25
  • Le filtrage nécessite un ré-encodage.
  • Ce filtre place toutes les images en mémoire .
  • Utiliser loop=3sera en boucle 4 fois.
  • Pour utiliser une boucle infinie -1.
  • Vous devez indiquer le nombre d'images à boucler (indiqué par 75 dans l'exemple ci-dessus). La valeur maximale est 32767.
  • Voir aussi ffmpeg -h filter=loop.

filtre de film

Le filtre de film a une option de boucle. Voir la réponse ci-dessous de Monah Tuk. Le filtrage nécessite un ré-encodage. Pour l’audio, utilisez le filtre amovie.


-stream_loop option

Voir la réponse ci-dessous par Thingy et la réponse par Gyan.

Notez que cette option était boguée (voir les rapports de bogue N ° 5719 , N ° 6121 et N ° 7043 ); elle risque donc de ne pas fonctionner pour les anciennes versions (toute version antérieure à 2018 06-27, y compris la branche de publication de FFmpeg 4.0.x). Pour les utilisateurs d'anciennes versions, comme indiqué par mulvya dans le ticket n ° 6121, l'une des solutions de contournement consiste à commencer par re-mux sur MKV ou TS, puis à utiliser -stream_loopdans la commande suivante.


-loop option

L' -loopoption est spécifique au démultiplexeur de fichiers d'image et à gif muxer ; elle ne peut donc pas être utilisée pour des fichiers vidéo classiques, mais elle peut également être utilisée pour boucler en boucle une série d'images en entrée. Cet exemple sera répété plusieurs fois mais -t 30limitera la durée de sortie à 30 secondes:

ffmpeg -loop 1 -i %03d.png -t 30 output.mkv

Ou pour boucler une sortie GIF:

ffmpeg -i input -loop 3 output.gif
llogan
la source
Est-ce que cela fonctionne bien avec les fichiers mp4?
Thomas King
3
Je reçois cette erreur> <(for i in {1..4}; do printf "file '%s'\n" input.mp4; done) -bash: /dev/fd/63: Permission denied
JZ11
1
@jamesfzhang - Je pense que c'est parce que vous avez besoin d'un chemin absolu vers le fichier (comme expliqué ici: trac.ffmpeg.org/wiki/Concatenate ). Pour cela, vous pouvez écrire: ffmpeg -safe 0 -f concat -i <(pour i dans {1..4}; ne pas printf "fichier '$ PWD' / '% s' \ n" input.mp4; done ) -c copy output.mp4
Plenus Franckly
1
Quant à moi, cela fonctionne pour répéter une vidéo à plein temps sans ignorer quatre fois le titreffmpeg -i video.mp4 -filter_complex "loop=4:32767" output.mp4
Vlad
Ce numéro a 4 ans et personne n'a remarqué que le lien vers le deuxième numéro de la -stream_loopsection indique le même ticket que le premier ...
Leonid Usov
15

Au moins sur FFmpeg 2.8.x (mais oldie devrait également fonctionner), vous pouvez utiliser lavficomme format d’entrée et graphique de filtrage complexe l’utilisation de movieet setptsfilters comme argument d’ -ioption.

Prochaine commande faisant ce travail pour vous:

ffmpeg -re -f lavfi -i "movie=filename=input.mp4:loop=0, setpts=N/(FRAME_RATE*TB)" output.mp4

Zéro loop=argument signifie une boucle infinie. Les valeurs supérieures à zéro définissent les comptes répétés. setptsles filtres requis pour l'ajustement PTS en fonction des répétitions suivantes et ultérieures, sinon la plupart des multiplexeurs en sortie échoueront avec une augmentation de PTS non monotone: la boucle ne recalcule pas PTS.

Notez que l'utilisation de filtres supposant que les images de contournement sans décodage / encodage est impossible: par leur conception, les filtres ne traitent que des images décodées.

FFmpeg 2.8.2: nouvelle option d’entrée -stream_loopintroduite. J'ai d'abord l'air que cela fonctionne plus simple et permet de copier du contenu sans transcodage:

ffmpeg -re -stream_loop -1 -i input.mp4 -c copy -y output.mp4

Mais il ne recalcule pas le PTS et le fichier de sortie est incorrect. Si vous ajoutez un filtre pour corriger le PTS (voir setpts), vous devez -c copyégalement le supprimer . Seuls les filtres de flux de données peuvent traiter les paquets codés, mais il n’existe aucun filtre de flux de données pour corriger le PTS (voir: https://ffmpeg.org/ffmpeg-bitstream-filters.html ).

Dans tous les cas, ffmpeg lors du second passage échoue avec l'erreur:

input.mp4: Resource temporarily unavailable

Solution connue pour moi : utiliser un conteneur pour un fichier d’entrée sans limite de PTS (conteneur en continu). L'un d'entre eux, connu de moi, est MPEG-TS. Vous pouvez donc convertir simplement votre fichier MP4 en MPEG-TS:

ffmpeg -i input.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts input.ts

Et utilisez la commande suivante pour composer le fichier infinity:

ffmpeg -re -stream_loop -1 -i input.ts -c copy -strict -2 -bsf:a aac_adtstoasc -y output.mp4

(les filtres de flux binaires ne doivent être utilisés que si nécessaire, sur mes échantillons, il est requis)

FFmpeg> = 2.8.2 est requis dans ce cas.

Monah Tuk
la source
1
L'exécution de cette commande me donne l'erreur suivante: "[mp4 @ 00000000053fa1a0] Impossible de trouver la balise pour le codec rawvideo dans le flux n ° 0, le codec n'est actuellement pas pris en charge dans le conteneur". Si j'ajoute -vcodec h264 avant l'entrée, cette erreur disparaît mais l'encodeur ne se ferme pas. Fournir un nombre de boucles différent de zéro génère beaucoup d'erreurs mais se termine. Le fichier n'est pas une sortie valide.
Gyan
1
La documentation de stream_loop indique "La boucle 0 ne signifie aucune boucle, la boucle -1 signifie une boucle infinie".
Gyan
Semble les fichiers d'entrée incorrects. Pourriez-vous s'il vous plait le partager? "La boucle 0 signifie pas de boucle, la boucle -1 signifie la boucle infinie." - Il semble que je voie de vieux docs :-)
Monah Tuk
1
J'ai oublié: filtres supposant transcodage (décodage / encodage). Intentionnellement. Donc, vous devez enlever -c copy. Réponse corrigée.
Monah Tuk
1
Bon à savoir, mais c'est une limitation importante si vous avez une grande boucle à générer.
Gyan
14

Avec ffmpeg 2.8.4, la commande suivante crée output.mp4 qui est une copie répétée de input.mp4 jusqu'à ce que le processus ffmpeg soit arrêté:

ffmpeg -stream_loop -1 -i input.mp4 -c copy output.mp4

Cette commande ne se terminera pas d'elle-même et le fichier de sortie grossira à l'infini.

Truc
la source
2
Semble être la méthode la plus rapide
josef
2
La méthode la plus rapide est un euphémisme, cette méthode passe à la vitesse de plusieurs vidéos en quelques secondes.
SleighBoy
C'est une méthode très pratique car il n'est pas nécessaire de créer un fichier avec des lignes répétitives.
Markus Zeller
-1

Q: "... comment pourrais-je changer la ligne de commande suivante pour faire cela? Ffmpeg -i input.mp4 -c copy output.mp4"?

R: La méthode simple qui évite les problèmes de commande de travail avec quelle version est la "solution triviale":

ffmpeg -i input.mp4 -i input.mp4 -i input.mp4 -i input.mp4 -c copier la sortie.mp4

Voir aussi: https://trac.ffmpeg.org/wiki/Concatenate pour de nombreux exemples.

Rob
la source
2
Cela ne fait aucune concaténation. Au moins une des méthodes concat doit être utilisée: protocole, filtre ou démultiplexeur. Dans cette commande, le mappage automatique de ffmpeg sélectionne un flux vidéo, un flux audio et un sous-titre parmi les entrées. Comme ils sont identiques, cela équivaut à la première commande de l'OP.
Gyan
Merci de tester Mulvya, car il diffère du comportement décrit dans la documentation: ffmpeg.org/ffmpeg.html#Description - S'il existe une similitude dans les noms de fichier, utilisez "-i -i /tmp/test%d.mp4" ( et al. est également possible.
Rob