Si vous avez des cycles de processeur à perdre, vous pouvez extraire plusieurs vidéos en parallèle:parallel -i {} -r 1/1 {.}-%03d.bmp ::: *mpg
Ole Tange
Réponses:
156
Si l'étape de codage JPEG est trop gourmande en performances, vous pouvez toujours stocker les images non compressées sous forme d'images BMP:
ffmpeg -i file.mpg -r 1/1 $filename%03d.bmp
Cela présente également l'avantage de ne pas entraîner davantage de perte de qualité grâce à la quantification par transcodage au format JPEG. (PNG est également sans perte mais a tendance à prendre beaucoup plus de temps que JPEG à encoder.)
Il en résulte beaucoup de chutes d'images sur ma machine. Puis-je dire à ffmpeg de tout rendre?
Evi1M4chine
45
@ Evi1M4chine supprimez simplement le paramètre -r cela extraira toutes les images
studioj
14
Je voudrais ajouter que si JPEG n'est pas vraiment difficile pour le processeur, les Bitmaps non compressés sont vraiment très difficiles pour le stockage, donc je doute que vous obtiendrez un débit plus élevé avec BMP par rapport au JPEG.
Marcus Müller
4
Pour extraire toutes les images:ffmpeg -r 1 file.mp4 -r 1 "$filename%03d.png"
fiatjaf
10
Vous voulez dire ffmpeg -r 1 -i file.mp4 -r 1 "$filename%03d.png, non? (il vous manquait le -i)
Joschua
68
Je suis tombé sur cette question, alors voici une comparaison rapide. Comparez ces deux façons différentes d'extraire une image par minute d'une vidéo de 38 min 07 s:
time ffmpeg -i input.mp4 -filter:v fps=fps=1/60 ffmpeg_%0d.bmp
1m36.029s
Cela prend du temps car ffmpeg analyse l'intégralité du fichier vidéo pour obtenir les images souhaitées.
time for i in {0..39} ; do ffmpeg -accurate_seek -ss `echo $i*60.0 | bc` -i input.mp4 -frames:v 1 period_down_$i.bmp ; done
0m4.689s
C'est environ 20 fois plus rapide. Nous utilisons la recherche rapide pour accéder à l'index temporel souhaité et extraire une image, puis appelons ffmpeg plusieurs fois pour chaque index temporel. Notez qu'il -accurate_seeks'agit de la valeur par défaut
et assurez-vous d'ajouter -ssavant l' -ioption d' entrée vidéo .
Février 2016: depuis ffmpeg 2.1, l'option de recherche précise est désormais par défaut - trac.ffmpeg.org/wiki/Seeking
mafrosis
1
bcn'est pas un paquet Ubuntu, on peut utiliser au lieu bash: let "i = $i * 60". BTW - excellente idée
gilad mayani
3
Bon conseil en ajoutant -ssavant -i. Sinon, toute la vidéo sera décodée et les images non requises seront supprimées
MoustafaAAtta
2
Puisqu'il s'agit du sommet de Google, j'aimerais noter qu'en 2018, c'est toujours une approche qui rapporte des dividendes. Le meilleur résultat semble être d'en exécuter un ffmpegpar cœur de votre hôte - ce qui (pour bmp) produit des améliorations presque linéaires de la vitesse (jusqu'à ce que vous rencontriez un autre goulot d'étranglement, comme le disque).
Knetic
Cela devrait être la réponse acceptée, car la question porte sur le «moyen le plus rapide». De toute évidence, vous devez connaître la variable de sortie pour la «boucle for» en utilisant ffprobe, ce qui, à mon avis, est encore plus rapide que les autres méthodes.
iamprem
9
Si vous savez exactement quelles images extraire, par exemple 1, 200, 400, 600, 800, 1000, essayez d'utiliser:
J'utilise ceci avec un tuyau vers le montage d'Imagemagick pour obtenir un aperçu de 10 images de toutes les vidéos. De toute évidence, les numéros de cadre que vous devrez déterminer en utilisantffprobe
J'essaie ffmpeg -i "input URL" -vf fps=1/5 out%d.png où l'URL d'entrée doit être un lien https.
x2212 le
ffmpeg -i file.mpg -vf fps=1 %d.jpg
Kishan Vaghela le
1
Dans mon cas, j'ai besoin de cadres au moins toutes les secondes. J'ai utilisé l'approche «chercher» ci-dessus, mais je me suis demandé si je pouvais paralléliser la tâche. J'ai utilisé les processus N avec l'approche FIFO ici:
/unix/103920/parallelize-a-bash-for-loop/216475#216475
open_sem(){
mkfifo /tmp/pipe-$$
exec 3<>/tmp/pipe-$$
rm /tmp/pipe-$$
local i=$1
for((;i>0;i--)); do
printf %s 000 >&3
done
}
run_with_lock(){
local x
read -u 3 -n 3 x && ((0==x)) || exit $x
(
"$@"
printf '%.3d' $? >&3
)&
}
N=16
open_sem $N
time for i in {0..39} ; do run_with_lock ffmpeg -ss `echo $i` -i /tmp/input/GOPR1456.MP4 -frames:v 1 /tmp/output/period_down_$i.jpg & done
Essentiellement, j'ai bifurqué le processus avec & mais j'ai limité le nombre de threads simultanés à N.
Cela a amélioré l'approche «chercher à» de 26 secondes à 16 secondes dans mon cas. Le seul problème est que le thread principal ne revient pas proprement vers le terminal car stdout est noyé.
parallel -i {} -r 1/1 {.}-%03d.bmp ::: *mpg
Réponses:
Si l'étape de codage JPEG est trop gourmande en performances, vous pouvez toujours stocker les images non compressées sous forme d'images BMP:
Cela présente également l'avantage de ne pas entraîner davantage de perte de qualité grâce à la quantification par transcodage au format JPEG. (PNG est également sans perte mais a tendance à prendre beaucoup plus de temps que JPEG à encoder.)
la source
ffmpeg -r 1 file.mp4 -r 1 "$filename%03d.png"
ffmpeg -r 1 -i file.mp4 -r 1 "$filename%03d.png
, non? (il vous manquait le-i
)Je suis tombé sur cette question, alors voici une comparaison rapide. Comparez ces deux façons différentes d'extraire une image par minute d'une vidéo de 38 min 07 s:
1m36.029s
Cela prend du temps car ffmpeg analyse l'intégralité du fichier vidéo pour obtenir les images souhaitées.
0m4.689s
C'est environ 20 fois plus rapide. Nous utilisons la recherche rapide pour accéder à l'index temporel souhaité et extraire une image, puis appelons ffmpeg plusieurs fois pour chaque index temporel. Notez qu'il
-accurate_seek
s'agit de la valeur par défaut et assurez-vous d'ajouter-ss
avant l'-i
option d' entrée vidéo .Notez qu'il est préférable d'utiliser
-filter:v -fps=fps=...
au lieu de-r
car ce dernier peut être inexact. Bien que le ticket soit marqué comme corrigé , j'ai toujours rencontré des problèmes, alors mieux vaut jouer en toute sécurité.la source
bc
n'est pas un paquet Ubuntu, on peut utiliser au lieu bash:let "i = $i * 60"
. BTW - excellente idée-ss
avant-i
. Sinon, toute la vidéo sera décodée et les images non requises seront suppriméesffmpeg
par cœur de votre hôte - ce qui (pour bmp) produit des améliorations presque linéaires de la vitesse (jusqu'à ce que vous rencontriez un autre goulot d'étranglement, comme le disque).Si vous savez exactement quelles images extraire, par exemple 1, 200, 400, 600, 800, 1000, essayez d'utiliser:
J'utilise ceci avec un tuyau vers le montage d'Imagemagick pour obtenir un aperçu de 10 images de toutes les vidéos. De toute évidence, les numéros de cadre que vous devrez déterminer en utilisant
ffprobe
.
Petite explication:
+
signifie OR et*
AND\,
échappe simplement au,
personnage-vsync vfr -q:v 2
cela ne semble pas fonctionner mais je ne sais pas pourquoi - n'importe qui?la source
Je l'ai essayé. 3600 images en 32 secondes. votre méthode est vraiment lente. Vous devriez essayer ceci.
la source
ffmpeg -i "input URL" -vf fps=1/5 out%d.png
où l'URL d'entrée doit être un lien https.ffmpeg -i file.mpg -vf fps=1 %d.jpg
Dans mon cas, j'ai besoin de cadres au moins toutes les secondes. J'ai utilisé l'approche «chercher» ci-dessus, mais je me suis demandé si je pouvais paralléliser la tâche. J'ai utilisé les processus N avec l'approche FIFO ici: /unix/103920/parallelize-a-bash-for-loop/216475#216475
Essentiellement, j'ai bifurqué le processus avec & mais j'ai limité le nombre de threads simultanés à N.
Cela a amélioré l'approche «chercher à» de 26 secondes à 16 secondes dans mon cas. Le seul problème est que le thread principal ne revient pas proprement vers le terminal car stdout est noyé.
la source
Cela a fonctionné pour moi
ffmpeg -i file.mp4 -vf fps=1 %d.jpg
la source