web-dev-qa-db-fra.com

Comment puis-je obtenir le nombre d'images d'une vidéo sur la ligne de commande linux?

J'ai un fichier vidéo et je veux obtenir le nombre d'images vidéo qu'il contient. Je peux utiliser ffmpeg pour obtenir la longueur de la vidéo et du FPS. Cependant, je ne vois rien d’évident pour le nombre total de cadres.

En théorie, on devrait pouvoir multiplier la longueur (en secondes) par le FPS pour obtenir le nombre d'images, mais dans ce cas, la longueur (34,43 secondes) et le nombre d'images par seconde (29,97 ips) donnent un nombre non entier, ce qui me rend pense que je fais quelque chose de mal.

Je dois pouvoir le faire en ligne de commande de manière totalement automatisée et non graphique. J'ai également besoin que cela soit assez exact et non une estimation (si c'est même possible avec des fichiers vidéo)

J'ai essayé d'utiliser tcprobe sur certains fichiers. Cela fonctionne pour certains fichiers AVI, mais pour certains fichiers VOB, la sortie de tcprobe n'a pas le nombre d'images. Je reçois cette sortie:

[tcprobe] MPEG program stream (PS)
[tcprobe] summary for myfile.vob, (*) = not default, 0 = not detected
import frame size: -g 720x480 [720x576] (*)
     aspect ratio: 4:3 (*)
       frame rate: -f 29.970 [25.000] frc=4 (*)
                   PTS=2199.3972, frame_time=33ms bitrate=7000 kbps
      audio track: -a 0 [0] -e 48000,16,5 [48000,16,2] -n 0x2000 [0x2000] (*)
                   PTS=2199.2763, bitrate=192 kbps
                   -D 3 --av_fine_ms 20 (frames & ms) [0] [0]
29
Rory

C'est horrible et stupide et lent, mais semble fonctionner:

ffmpeg -i foo.avi -vcodec copy -f rawvideo -y /dev/null 2>&1 | tr ^M '\n' | awk '/^frame=/ {print $2}'|tail -n 1

Cela fonctionnera également sur les fichiers tronqués et les flux bruts (c’est pourquoi vous n’obtenez rien pour les fichiers .vob)

15
user23307

ffprobe peut être utilisé pour obtenir des informations sur un fichier multimédia:

ffprobe -select_streams v -show_streams input.avi

Vous obtiendrez des détails sur le flux:

nb_frames=159697

Recherchez nb_frames avec grep:

ffprobe -select_streams v -show_streams input.avi 2>/dev/null | grep nb_frames | sed -e 's/nb_frames=//'

Cela fonctionne pour avi, mp4, etc. Pour certains conteneurs, il n’affiche pas de valeur valide, par exemple. mpeg.

Dans ce cas, cela fonctionne ffprobe -show_packets a.mpg 2>/dev/null | grep video | wc -l

31
Aftershock

J'ai posté ceci sur une autre question . À l'aide de l'outil tcprobe (à partir du package transcode), le nombre d'images est inclus dans les informations. Utilisez le commutateur -i pour obtenir un vidage d’informations à partir du fichier:

$ tcprobe -i foo.avi
[tcprobe] RIFF data, AVI video
[avilib] V: 29.970 fps, codec=XVID, frames=38630, width=512, height=384
[avilib] A: 48000 Hz, format=0x55, bits=16, channels=2, bitrate=128 kbps,
[avilib]    53707 chunks, 21768720 bytes, VBR
[tcprobe] summary for foo.avi, (*) = not default, 0 = not detected
import frame size: -g 512x384 [720x576] (*)
       frame rate: -f 29.970 [25.000] frc=4 (*)
      audio track: -a 0 [0] -e 48000,16,2 [48000,16,2] -n 0x55 [0x2000] (*)
                   bitrate=128 kbps
           length: 38630 frames, frame_time=33 msec, duration=0:21:28.954

Notez que le nombre d'images est donné sur deux lignes ici (2ème ligne de sortie et dernière ligne de sortie).

16
quack quixote

J'ai trouvé que mediainfo --fullscan inputfile | grep "Frame count" fonctionne bien pour la plupart des fichiers.

Les systèmes Debian peuvent l’installer avec apt-get install mediainfo

Si vous obtenez 2 lignes plutôt que l'une des sorties, la première ligne est la piste vidéo et la deuxième ligne est la piste audio. Il semble que cela se produise sur des fichiers avec de l’audio à débit binaire variable.

Testé sur les échantillons .mkv, .m4v, .mp4, flv, vob et .avi à la date de l'édition.

Sources: Comment récupérer des informations sur un fichier vidéo à partir de la ligne de commande sous Linux? et d’essais sous des versions Ubuntu.

Vous pouvez trouver ici mediainfo disponible pour votre système d'exploitation .

7
Elder Geek

ffprobe -select_streams v -show_frames -count_frames INPUT_FILE | grep pkt_duration_time =

Additionnez la durée. Pourrait être amateur avec sed/awk et ce qui ne l'est pas.

D'après nos tests, je peux dire que pour l'instant, il s'est révélé le meilleur, le plus fiable. Vous obtenez un compte rendu précis et une durée exacte. Même avec un framerate variable auquel tous les autres outils, comme mediainfo, semblent aller gaga.

4
Guillaume Blain

Testé sur Ubuntu.

melt icecap.mp4 -consumer xml
  • melt - melt était conçu comme un outil de test pour le framework MLT, mais c'est aussi un puissant éditeur vidéo multipiste orienté ligne de commande. Il pourrait également être utilisé comme lecteur multimédia minimaliste pour les fichiers audio et vidéo.

  • -consumer id [: arg] [nom = valeur] *
    Réglez le consommateur (évier)

  • xml - Définit le consommateur (récepteur) sur une sortie au format XML

  • <property name="length">nnnn</property> - indique le nombre d'images, où nnnn est remplacé par un nombre entier égal au nombre d'images

Si vous n'avez pas de fusion, vous pouvez l'installer sur Ubuntu et d'autres systèmes basés sur Debian avec Sudo apt-get install melt

3
neoneye

Directement avec mediainfo, pas de grep, ni d'attente, ni rien:

mediainfo --Inform='Video;%FrameCount%' $the_file

Pour plus d'informations, voir mediainfo --info-parameters

3
xenoid

J'ai constaté que le nombre d'images est en réalité le double de la durée en fps * (je ne sais pas pourquoi, je serais heureux de le savoir).

Dans un de mes scripts, j'ai:

# Get duration and fps
duration=$($FFMPEG -i $input 2>&1 | sed -n "s/.* Duration: \([^,]*\), start: .*/\1/p")
fps=$($FFMPEG -i $input 2>&1 | sed -n "s/.*, \(.*\) tb.*/\1/p")

hours=$(echo $duration | cut -d":" -f1)
minutes=$(echo $duration | cut -d":" -f2)
seconds=$(echo $duration | cut -d":" -f3)
# For some reason, we have to multiply by two (no idea why...)
# Get the integer part with cut
frames=$(echo "($hours*3600+$minutes*60+$seconds)*$fps*2" | bc | cut -d"." -f1)

Et oui, pour une raison quelconque, je dois en obtenir la partie entière. Cela n’a aucun sens, mais ce script a toujours réussi à convertir mes vidéos correctement jusqu’à présent.

3
ℝaphink

linux

ffmpeg -i "/home/iorigins/Завантаження/123.mov" -f null /dev/null

Ruby

result = `ffmpeg -i #{path} -f null - 2>&1`
r = result.match("frame=([0-9]+)")
p r[1]
0
Yaroslav Maluk

Vous pouvez le faire en ajoutant et en multipliant les valeurs que vous obtenez de ffprobe.

Remarque: ffprobe fait partie de libav (avconv) - la version linux de ffmpeg.

#your command -
 ffprobe man.avi

Lorsque vous faites cela, vous obtiendrez le nombre d'images par seconde et la durée du clip.

Convertissez la durée du clip en secondes et multipliez cette valeur par le nombre d'images par seconde.

N'oubliez pas d'arrondir le nombre au plus proche.

0
JJAtairu