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]
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)
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
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).
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 .
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.
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
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
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.
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]
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.