27

У меня есть видеофайл, и я хочу получить количество видеокадров в нем. Я могу использовать ffmpeg чтобы получить длину видео и FPS. Однако я не вижу ничего очевидного для общего количества кадров.

Теоретически можно умножить длину (в секундах) на FPS, чтобы получить количество кадров, но в этом случае длина (34,43 секунды) и частота кадров (29,97 кадров в секунду) дают нецелое число, что делает меня кажется, я делаю что-то не так

Я должен быть в состоянии сделать это в командной строке полностью автоматизированным и неграфическим способом. Мне также нужно, чтобы это было довольно точно, а не оценка (если это возможно даже с видеофайлами)

Я пытался использовать tcprobe на некоторых файлах. Для некоторых файлов AVI это работает, но для некоторых файлов VOB вывод tcprobe не имеет количества кадров. Я получаю этот вывод:

[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]

11 ответов11

30

ffprobe может использоваться для получения информации о медиа-файле:

ffprobe -select_streams v -show_streams input.avi

Вы получите подробную информацию о потоке:

nb_frames=159697

Ищите nb_frames с помощью grep:

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

Это работает для avi, mp4 и т.д. Для некоторых контейнеров не отображается допустимое значение, например, mpeg.

В этом случае это работает ffprobe -show_packets a.mpg 2>/dev/null | grep video | wc -l

15

Я отправил это на другой вопрос. Используя инструмент tcprobe (из пакета transcode ), количество кадров включается в информацию. Используйте ключ -i чтобы получить дамп информации из файла:

$ 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

Обратите внимание, что количество кадров указано здесь в двух строках (вторая строка вывода и последняя строка вывода).

13

Это ужасно, глупо и медленно, но, похоже, работает

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

Он также будет работать правильно с усеченными файлами и необработанными потоками (поэтому вы ничего не получаете за файлы .vob)

6

Я обнаружил, что mediainfo --fullscan inputfile | grep "Frame count" прекрасно работает для большинства файлов.

Системы на основе Debian могут установить его с помощью apt-get install mediainfo

Если вы получаете 2 строки, а не одну из выходных данных, первая строка - это дорожка видео, а вторая - звуковая дорожка. Похоже, что это происходит с файлами с аудио с переменной битовой скоростью.

Проверено на образцах .mkv, .m4v, .mp4, flv, vob и .avi на дату редактирования.

Источники: Как получить информацию о видеофайле из командной строки под Linux и тестировать под Ubuntu.

3

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

Сложите продолжительность. Может быть моднее с sed/awk, а что нет.

Из наших испытаний я могу сказать, что на данный момент он показал себя как самый надежный. Вы получаете точное количество кадров и точную продолжительность. Даже с переменной частотой кадров, которую все другие инструменты, такие как mediainfo, кажутся бесполезными.

2

Проверено на Ubuntu.

melt icecap.mp4 -consumer xml
  • melt melt был задуман как инструмент тестирования для среды MLT, но он также является мощным многодорожечным редактором видео, ориентированным на командную строку. Он также может использоваться как минималистичный медиаплеер для аудио и видео файлов.

  • идентификатор -consumer [:arg] [имя = значение] *
    Комплект потребительский (мойка)

  • xml - установить для потребителя (приемника) форматированный вывод xml

  • <property name="length">nnnn</property> - показывает количество кадров, где nnnn заменяется целым числом, равным количеству кадров

Если у вас нет melt, вы можете установить его в Ubuntu и других системах на основе Debian с помощью sudo apt-get install melt

2

Я обнаружил, что количество кадров на самом деле вдвое больше длительности fps * (не знаю почему, я был бы рад знать).

В моем сценарии у меня есть:

# 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)

И да, по какой-то причине я должен получить целую часть этого. Это не имеет смысла, но этот скрипт до сих пор всегда правильно конвертировал мои видео.

0

Это дает вам конкретное значение без необходимости разбирать ответ из выходной строки:

$ mediainfo --Inform = 'Video;% FrameRate%\n' VTS_07_4.ВОБ

23,976

0

Непосредственно с mediainfo , без grep, без ожидания, без ничего:

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

Для получения дополнительной информации см. mediainfo --info-parameters

0

линукс

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

Рубин

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

Вы можете сделать это, добавив и умножив значения, полученные из ffprobe.

Примечание: ffprobe является частью libav(avconv) - версии ffmpeg для Linux.

#your command -
 ffprobe man.avi

Когда вы сделаете это, вы получите количество кадров в секунду, а также продолжительность клипа.

Преобразуйте длительность клипа в секунды и умножьте это значение на количество кадров в секунду.

Не забудьте округлить число до ближайшего.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .