web-dev-qa-db-fra.com

Récupérer le nombre d'images avec ffmpeg

Est-ce que quelqu'un sait comment récupérer le nombre total d'images d'un fichier vidéo en utilisant ffmpeg? La sortie de rendu de ffmpeg montre l'image actuelle et j'ai besoin du nombre d'images pour calculer la progression en pourcentage.

74
Hansl

Remarque: La présence d'une liste de montage dans MP4/M4V/M4A/MOV peut affecter le numéro de votre image. Voir Editer les listes ci-dessous.


ffprobe: Interroge le conteneur

ffprobe -v error -select_streams v:0 -show_entries stream=nb_frames -of default=nokey=1:noprint_wrappers=1 input.mp4
  • C'est une méthode rapide.
  • Tous les formats (tels que Matroska) ne rapporteront pas le nombre d'images résultant de la sortie de N/A. Voir les autres méthodes énumérées ci-dessous.

ffprobe: Compter le nombre d'images

ffprobe -v error -count_frames -select_streams v:0 -show_entries stream=nb_read_frames -of default=nokey=1:noprint_wrappers=1 input.mkv
  • Ceci est une méthode lente.
  • Ajoutez l’option -skip_frame nokey pour ne compter que les images clés.

ffmpeg: Compter le nombre d'images

Si vous n'avez pas ffprobe, vous pouvez utiliser ffmpeg à la place:

ffmpeg -i input.mkv -map 0:v:0 -c copy -f null -
  • C'est une méthode un peu rapide.
  • Reportez-vous à frame= vers la fin de la sortie de la console.
  • Ajoutez l’option de saisie -discard nokey (avant -i) pour ne comptabiliser que les images clés.

Editer des listes

Ignorer la liste d'édition MP4/M4V/M4A/MOV avec l'option de saisie -ignore_editlist 1. La valeur par défaut est de not ignorer la liste d'édition.

Que signifient les options ffprobe

  • -v error Ceci masque la sortie "info" (informations de version, etc.), ce qui facilite l'analyse.

  • -count_frames Comptez le nombre d'images par flux et signalez-le dans la section de flux correspondante.

  • -select_streams v:0 Sélectionnez uniquement le flux vidéo.

  • -show_entries stream=nb_frames ou -show_entries stream=nb_read_frames Affiche uniquement l'entrée pour nb_frames ou nb_read_frames.

  • -of default=nokey=1:noprint_wrappers=1 Définissez le format de sortie (aka "writer") sur default, n'imprimez pas la clé de chaque champ (nokey=1) et n'imprimez pas l'en-tête et le pied de section (noprint_wrappers=1). Il existe des alternatives plus courtes telles que -of csv=p=0.

Regarde aussi


mediainfo

L'outil bien connu mediainfo peut générer le nombre d'images:

mediainfo --Output="Video;%FrameCount%" input.avi

MP4Box

Pour les fichiers MP4/M4V/M4A.

MP4Box de gpac peut afficher le nombre d'images:

MP4Box -info input.mp4

Reportez-vous à la ligne Media Info dans la sortie du flux vidéo en question:

Media Info: Language "Undetermined (und)" - Type "vide:avc1" - 2525 samples

Dans cet exemple, le flux vidéo contient 2525 images.


boxdumper

Pour les fichiers MP4/M4V/M4A/MOV.

boxdumper est un outil simple de l-smash. Il produira une grande quantité d'informations. Dans la section stsz taille d'échantillon, reportez-vous à sample_count pour connaître le nombre d'images. Dans cet exemple, l'entrée contient 1900 images vidéo:

boxdumper input.mp4
  ...
  [stsz: Sample Size Box]
    position = 342641
    size = 7620
    version = 0
    flags = 0x000000
    sample_size = 0 (variable)
    sample_count = 1900
  • Sachez qu’un fichier peut avoir plus d’un atome stsz.
100
llogan

Sous Unix, cela fonctionne comme un charme:

ffmpeg -i 00000.avi -vcodec copy -acodec copy -f null /dev/null 2>&1 | grep 'frame=' | cut -f 2 -d ' '
23
ataraxic

Calculez-le en fonction du temps, à la place.

C'est ce que je fais et cela fonctionne très bien pour moi et pour beaucoup d'autres.) Tout d'abord, trouvez la longueur de la vidéo dans l'extrait ci-dessous:

Seems stream 0 codec frame rate differs from container frame rate: 5994.00 
(5994/1) -> 29.97 (30000/1001)
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/Users/stu/Movies/District9.mov':
  Duration: 00:02:32.20, start: 0.000000, bitrate: 9808 kb/s
    Stream #0.0(eng): Video: h264, yuv420p, 1920x1056, 29.97tbr, 2997tbn, 5994tbc
    Stream #0.1(eng): Audio: aac, 44100 Hz, 2 channels, s16
    Stream #0.2(eng): Data: tmcd / 0x64636D74

Vous devriez pouvoir trouver Duration: hh:mm:ss.nn de manière cohérente et sûre pour déterminer la taille du clip vidéo source. Ensuite, pour chaque ligne de mise à jour (CR, pas de LF), vous pouvez analyser le texte correspondant à la marque de temps actuelle:

frame=   84 fps= 18 q=10.0 size=       5kB time=1.68 bitrate=  26.1kbits/s    
frame=   90 fps= 17 q=10.0 size=       6kB time=1.92 bitrate=  23.8kbits/s    
frame=   94 fps= 16 q=10.0 size=     232kB time=2.08 bitrate= 913.0kbits/s    

Attention, il ne faut pas toujours s'attendre à une sortie parfaite de ces lignes d'état. Ils peuvent inclure des messages d'erreur comme ici:

frame=   24 fps= 24 q=-1.0 size=       0kB time=1.42 bitrate=   0.3kbits/s    
frame=   41 fps= 26 q=-1.0 size=       0kB time=2.41 bitrate=   0.2kbits/s    
[h264 @ 0x1013000]Cannot parallelize deblocking type 1, decoding such frames in
sequential order
frame=   49 fps= 24 q=26.0 size=       4kB time=0.28 bitrate= 118.1kbits/s    
frame=   56 fps= 22 q=23.0 size=       4kB time=0.56 bitrate=  62.9kbits/s    

Une fois que vous avez le temps, le calcul est simple: time / durration * 100 = % done.

13
Stu Thompson

Tous les formats ne stockent pas leur nombre d'images ni leur durée totale - et même s'ils le font, le fichier peut être incomplet -, par conséquent, ffmpeg ne détecte ni l'un ni l'autre de manière précise par défaut.

Au lieu de cela, essayez de chercher jusqu'à la fin du fichier et lisez l'heure, puis comptez l'heure actuelle pendant que vous y allez.

Alternativement, vous pouvez essayer AVFormatContext->nb_index_entries ou la durée détectée, ce qui devrait fonctionner avec au moins des fichiers AVI/MOV non endommagés, ou avec la bibliothèque FFMS2, qui est probablement trop lente pour une barre de progression.

8
alex strange

Essayez quelque chose comme:

ffmpeg -i "path to file" -f null /dev/null

Il écrit le numéro de l'image sur stderr, vous pouvez donc récupérer la dernière image.

8
a1kmm

Vous pouvez utiliser ffprobe pour obtenir le numéro d'image avec les commandes suivantes

  1. première méthode

ffprobe.exe -i video_name -print_format json -loglevel fatal -show_streams -count_frames -select_streams v

qui dit d'imprimer les données au format json

select_streams v dira à ffprobe de nous donner simplement les données de flux video et si vous les supprimez, cela vous donnera également des informations audio

et la sortie sera comme 

{
    "streams": [
        {
            "index": 0,
            "codec_name": "mpeg4",
            "codec_long_name": "MPEG-4 part 2",
            "profile": "Simple Profile",
            "codec_type": "video",
            "codec_time_base": "1/25",
            "codec_tag_string": "mp4v",
            "codec_tag": "0x7634706d",
            "width": 640,
            "height": 480,
            "coded_width": 640,
            "coded_height": 480,
            "has_b_frames": 1,
            "sample_aspect_ratio": "1:1",
            "display_aspect_ratio": "4:3",
            "pix_fmt": "yuv420p",
            "level": 1,
            "chroma_location": "left",
            "refs": 1,
            "quarter_sample": "0",
            "divx_packed": "0",
            "r_frame_rate": "10/1",
            "avg_frame_rate": "10/1",
            "time_base": "1/3000",
            "start_pts": 0,
            "start_time": "0:00:00.000000",
            "duration_ts": 256500,
            "duration": "0:01:25.500000",
            "bit_rate": "261.816000 Kbit/s",
            "nb_frames": "855",
            "nb_read_frames": "855",
            "disposition": {
                "default": 1,
                "dub": 0,
                "original": 0,
                "comment": 0,
                "lyrics": 0,
                "karaoke": 0,
                "forced": 0,
                "hearing_impaired": 0,
                "visual_impaired": 0,
                "clean_effects": 0,
                "attached_pic": 0
            },
            "tags": {
                "creation_time": "2005-10-17 22:54:33",
                "language": "eng",
                "handler_name": "Apple Video Media Handler",
                "encoder": "3ivx D4 4.5.1"
            }
        }
    ]
}

2 . Vous pouvez utiliser 

ffprobe -v error -show_format -show_streams video_name

qui vous donnera des données de flux, si vous voulez des informations sélectionnées comme la cadence, utilisez la commande suivante

ffprobe -v error -select_streams v:0 -show_entries stream=avg_frame_rate -of default=noprint_wrappers=1:nokey=1 video_name

qui donnent une base numérique à vos informations vidéo, le problème est que lorsque vous utilisez cette méthode, il est possible que vous obteniez un N/A en sortie.

pour plus d'informations, consultez cette page Conseils FFProbe

7
Hadi Rasekh

essaye ça:

ffmpeg -i "path to file" -f null /dev/null 2>&1 | grep 'frame=' | cut -f 2 -d ' '
3
Julien

La seule précision que j'ai pu faire est la suivante:

ffprobe -i my_video.mp4 -show_frames 2>&1|grep -c '^\[FRAME'

Pour vous assurer que cela fonctionne avec la vidéo:

ffprobe -i my_video.mp4 -show_frames 2>&1 | grep -c media_type=video
2
Lloyd Moore

construire sur la réponse de stu. voici comment j'ai trouvé le taux de trame d'une vidéo de mon téléphone portable. J'ai couru la commande suivante pendant un moment. Je laisse le nombre d'images atteindre environ 10 000 avant de devenir impatient et de toucher ^ C:

$ ffmpeg -i 2013-07-07\ 12.00.59.mp4 -f null /dev/null 2>&1
...
Press [q] to stop, [?] for help
[null @ 0x7fcc80836000] Encoder did not produce proper pts, making some up.
frame= 7989 fps= 92 q=0.0 Lsize=N/A time=00:04:26.30 bitrate=N/A dup=10 drop=0    
video:749kB audio:49828kB subtitle:0 global headers:0kB muxing overhead -100.000042%
Received signal 2: terminating.
$

ensuite, j'ai saisi deux informations à partir de cette ligne qui commence par "frame =", le nombre d'images par seconde de 7989 et l'heure 00: 04: 26.30. Vous devez d’abord convertir le temps en secondes, puis diviser le nombre d’images par secondes pour obtenir «images par seconde». "images par seconde" est votre fréquence d'images.

$ bc -l
0*60*60 + 4*60 + 26.3
266.3

7989/(4*60+26.3)
30.00000000000000000000
$

le framerate pour ma vidéo est de 30 images par seconde.

2
margaret

J'utilise le php_ffmpeg alors je peux obtenir tous les temps et toutes les images d'un film. Comme belows

$input_file='/home/strone/workspace/play/CI/abc.rmvb';
$ffmpegObj = new ffmpeg_movie($input_file);
echo $ffmpegObj->getDuration();
    echo $ffmpegObj->getFrameCount();

Et puis le détail est sur la page.

http://ffmpeg-php.sourceforge.net/doc/api/ffmpeg_movie.php

1
xingyue

Désolé pour la réponse necro, mais j'aurai peut-être besoin de cela (je n'ai pas trouvé de solution pour les dernières versions de ffmpeg.

Avec ffmpeg 3.3.4 j'ai trouvé on peut trouver avec ce qui suit:

ffprobe -i video.mp4 -show_streams -hide_banner | grep "nb_frames"

À la fin, le nombre d'images sera généré. Cela a fonctionné pour moi sur des vidéos avec audio. Cela donne deux fois une ligne "nb_frames", cependant, mais la première ligne était le nombre d'images réel sur les vidéos que j'ai testées.

1
acidrums4
Cmd ->

ffprobe.exe -v error -select_streams v:0 -show_entries stream=r_frame_rate,duration -of default=nw=1 "d:\movies\The.Matrix.1999.1080p.BrRip.x264.YIFY.dut.mp4"

Result ->

r_frame_rate=24000/1001
duration=8177.794625

Calculation ->

Frames=24000/1001*8177.794625=196071

Proof -> 

ffmpeg -i "d:\movies\The.Matrix.1999.1080p.BrRip.x264.YIFY.dut.mp4" -f null /dev/null
ffmpeg version N-92938-g0aaaca25e0-ffmpeg-windows-pacman Copyright (c) 2000-2019 the FFmpeg developers
  built with gcc 8.2.0 (GCC)
  configuration: --pkg-config=pkg-config --pkg-config-flags=--static --extra-version=ffmpeg-windows-pacman --enable-version3 --disable-debug --disable-w32threads --Arch=x86_64 --target-os=mingw32 --cross-prefix=/opt/sandbox/cross_compilers/mingw-w64-x86_64/bin/x86_64-w64-mingw32- --enable-libcaca --enable-gray --enable-libtesseract --enable-fontconfig --enable-gmp --enable-gnutls --enable-libass --enable-libbluray --enable-libbs2b --enable-libflite --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopus --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libzimg --enable-libzvbi --enable-libmysofa --enable-libaom --enable-libopenjpeg --enable-libopenh264 --enable-liblensfun --enable-nvenc --enable-nvdec --extra-libs=-lm --extra-libs=-lpthread --extra-cflags=-DLIBTWOLAME_STATIC --extra-cflags=-DMODPLUG_STATIC --extra-cflags=-DCACA_STATIC --enable-amf --enable-libmfx --enable-gpl --enable-avisynth --enable-frei0r --enable-filter=frei0r --enable-librubberband --enable-libvidstab --enable-libx264 --enable-libx265 --enable-libxvid --enable-libxavs --enable-avresample --extra-cflags='-march=core2' --extra-cflags=-O2 --enable-static --disable-shared --prefix=/opt/sandbox/cross_compilers/mingw-w64-x86_64/x86_64-w64-mingw32 --enable-nonfree --enable-decklink --enable-libfdk-aac
  libavutil      56. 25.100 / 56. 25.100
  libavcodec     58. 43.100 / 58. 43.100
  libavformat    58. 25.100 / 58. 25.100
  libavdevice    58.  6.101 / 58.  6.101
  libavfilter     7. 47.100 /  7. 47.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  4.100 /  5.  4.100
  libswresample   3.  4.100 /  3.  4.100
  libpostproc    55.  4.100 / 55.  4.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'd:\movies\The.Matrix.1999.1080p.BrRip.x264.YIFY.dut.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.25.100
  Duration: 02:16:17.91, start: 0.000000, bitrate: 2497 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x800 [SAR 1:1 DAR 12:5], 2397 kb/s, 23.98 fps, 23.98 tbr, 24k tbn, 47.95 tbc (default)
    Metadata:
      handler_name    : VideoHandler
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 93 kb/s (default)
    Metadata:
      handler_name    : GPAC ISO Audio Handler
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> wrapped_avframe (native))
  Stream #0:1 -> #0:1 (aac (native) -> pcm_s16le (native))
Press [q] to stop, [?] for help
Output #0, null, to '/dev/null':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.25.100
    Stream #0:0(und): Video: wrapped_avframe, yuv420p, 1920x800 [SAR 1:1 DAR 12:5], q=2-31, 200 kb/s, 23.98 fps, 23.98 tbn, 23.98 tbc (default)
    Metadata:
      handler_name    : VideoHandler
      encoder         : Lavc58.43.100 wrapped_avframe
    Stream #0:1(und): Audio: pcm_s16le, 44100 Hz, stereo, s16, 1411 kb/s (default)
    Metadata:
      handler_name    : GPAC ISO Audio Handler
      encoder         : Lavc58.43.100 pcm_s16le
frame=196071 fps=331 q=-0.0 Lsize=N/A time=02:16:17.90 bitrate=N/A speed=13.8x
video:102631kB audio:1408772kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
0
Gerard Wensink

Dans l'une des réponses, comment compter le nombre d'images avec 'mediainfo':

mediainfo --Output = "Vidéo;% FrameCount%" input.avi

Si le fichier d'entrée est h264, le flux élémentaire 'mediainfo' ne rapporte pas le nombre d'images . Seulement si le fichier d'entrée est un conteneur (mp4, ts ou avi), le nombre d'images est compté et rapporté. 

0
Shevach Riabtsev