Как узнать количество кадров в видео в командной строке linux?

48850
Rory

У меня есть видеофайл, и я хочу получить количество видеокадров в нем. Я могу использовать, 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] 
27
ваше уравнение даст вам хорошую приблизительную оценку; только вокруг результата с плавающей точкой вверх. если вам нужно точное количество кадров, вам нужно проверить файл напрямую - ваша оценка может быть отклонена на один или два в любом направлении из-за особенностей видеокодека. quack quixote 14 лет назад 0
это VOB "все в одном" или VOB в стиле DVD, разделенные на несколько файлов? quack quixote 14 лет назад 0
http://stackoverflow.com/questions/2017843/fetch-frame-count-with-ffmpeg Ciro Santilli 新疆改造中心 六四事件 法轮功 8 лет назад 0

11 ответов на вопрос

29
Aftershock

ffprobe can be used to get info about a media file:

ffprobe -select_streams v -show_streams input.avi 

You will get details about the stream:

nb_frames=159697 

Look for nb_frames with grep:

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

That works for avi, mp4 and etc For some containers, it does not show valid value e.g. mpeg.

In that case, this works ffprobe -show_packets a.mpg 2>/dev/null | grep video | wc -l

Отличная идея. Я немного изменил команду, чтобы она только выбирала видеопоток и фильтровала вывод. Это дает вам только количество кадров. slhck 9 лет назад 0
Поздравляю с вашим вторым решением, которое работает с MPEG-2! malat 9 лет назад 0
Не работает с контейнерами MKV. Cenk Alti 8 лет назад 0
nb_frames = N / A в этом файле: http://web.archive.org/web/20180117220713/http://techslides.com/demos/sample-videos/small.webm Ciro Santilli 新疆改造中心 六四事件 法轮功 6 лет назад 0
15
quack quixote

Я отправил это на другой вопрос . Используя 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 

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

Это выглядит как хороший ответ и работает для некоторых файлов, но для некоторых файлов VOB, которые у меня есть, у меня нет этих данных в выводе. Я обновил вопрос с выводом, который я получаю Rory 14 лет назад 0
я ожидаю (но не знаю точно), что tcprobe проверяет заголовки файлов для этой информации. если он не включен в заголовок, tcprobe может не пытаться вычислить его. хороший вопрос; Хотел бы я иметь хороший ответ для вас. quack quixote 14 лет назад 0
13
user23307

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

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

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

Это очень хорошо. По моему опыту, это не займет много времени. 40-минутный файл занимает около 3 секунд для запуска, хотя. Помните, что «^ M» - это не 2 символа ^ и M, вам нужно нажать Control-V, а затем ввести. Вместо вашей команды я использовал: ffmpeg -i somefile.avi -vcodec copy -f rawvideo -y / dev / null 2> & 1 | tr "^ M" '\ n' | grep '^ frame =' | perl -pe 's / ^ frame = \ s * ([0-9] +) \ s. * $ / \ 1 /' | tail -n 1 Ваша команда не выполняется, если после "frames =" нет пробела Rory 14 лет назад 0
В Ubuntu 12.04, ffmpeg версия git-2013-04-15-a4f03f0, вы можете опустить оба `| tr ^ M '\ n'` и `| tail -n 1`. Кроме того, пробел после `frames =` не завершается ошибкой. (Может быть, что-то изменилось за последние четыре года.) Camille Goudeseune 9 лет назад 0
для меня это возвращать каждый раз разные значения CAMOBAP 7 лет назад 0
Решение Mediainfo работает с VOB .. Я бы рекомендовал это вместо. root @ lanparty: / mnt / films # mediainfo --fullscan Bugs_Bunny.vob | grep -i frame \ count Количество кадров: 175715 Количество кадров: 183218 kevinf 7 лет назад 1
6
Elder Geek

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

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

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

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

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

3
Guillaume Blain

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

Add up the duration. Could be fancier with sed/awk and what not.

From our testing I can say that for now it has shown to be the best most reliable. You get a precise framecount and exact duration. Even with variable framerate which all other tools like mediainfo seem to go gaga.

2
ℝaphink

Я обнаружил, что количество кадров на самом деле вдвое больше длительности 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) 

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

Потому что FPS означает «Кадры в секунду» (или шутер от первого лица: D), и если есть 30 FPS, просто умножьте его на количество секунд в видео. John T 14 лет назад 0
Да, Джон, я мог бы понять это, но это не объясняет, почему я должен умножить его на 2, чтобы получить правильное количество кадров ... В моем случае, после того, как я рассчитал количество кадров, я запустил ffmpeg в фон и проанализировали журналы, чтобы сделать индикатор выполнения. Журналы показывают, сколько кадров прошло в преобразовании. Как только все видео было конвертировано, кадр # был int (секунды * fps * 2), отсюда мой код, но я хотел бы знать, почему ;-) ℝaphink 14 лет назад 0
это любопытно; вывод `tcprobe` в моем ответе дает количество кадров в точности как секунды * fps (округлено в большую сторону). я ожидаю, что вы видите причуду ffmpeg. Вы пытались проанализировать файл с помощью других инструментов, чтобы увидеть, показывают ли они одинаковое количество кадров? quack quixote 14 лет назад 0
Хм ... интересно. Я попробовал на видео, и я получил `seconds * fps = 1001.59` и` tcprobe = 1002`. Очевидно, что `tcprobe` говорит мне, что мне не нужно умножать на два. Почему тогда ffmpeg дает мне число, которое в журналах в два раза больше при конвертации? ℝaphink 14 лет назад 0
вы смотрите вывод во время кодирования, а не проверяете файл пост-кодирования, верно? может быть ошибка в выходном коде. может быть что-то в процессе кодирования, так что этот вывод имеет смысл. Я ожидаю, что вам придется изучить код, чтобы выяснить это наверняка. quack quixote 14 лет назад 0
Да, я наблюдаю вывод во время кодирования, чтобы сделать индикатор выполнения. ℝaphink 14 лет назад 0
я запустил `mediainfo filename.mp4 | grep -i fram` и увидел строку с надписью «Настройки формата, ReFrames: 2 кадра». это похоже связано mulllhausen 10 лет назад 0
это чересстрочная съемка? Если так, то в каждом кадре два поля, и это может дать вам количество полей. stib 9 лет назад 1
2
neoneye

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

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

  • -consumerid [: arg] [name = value] *
    Установить потребителя (приемник)

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

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

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

Это очень коротко, вы хотите подробнее рассказать о том, что он делает, почему он работает и т. Д.? David 8 лет назад 1
Это хорошо работает на файлах mp2 h264, которые не предоставляют счетчик кадров через `mediainfo -fullscan filename`. Elder Geek 7 лет назад 0
0
JJAtairu

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

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

#your command - ffprobe man.avi 

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

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

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

В Ubuntu 14.04 LTS `ffprobe` недоступен, но в libav-tools есть нечто, называемое avprobe (которое также предоставляет avconv). Но на моей стороне это не печатает любое количество кадров, по крайней мере, не для форматов, которые я попробовал. Он просто печатает, что печатает также `avprobe -i`, и это, к сожалению, лишь незначительные детали формата. Даже с `-v debug` он говорит только о некоторых хороших свойствах моего аппаратного и программного обеспечения, но ни о какой интересной информации о файле / потоке для проверки. Возможно, это скрывается в некоторых из множества доступных вариантов. Кто знает? Tino 9 лет назад 0
@Tino ffprobe действительно доступен как часть пакета ffmpeg. avconv является вилкой ffmpeg и вызвал некоторую путаницу. Смотрите: http://stackoverflow.com/questions/9477115/what-are-the-differences-and-similities-between-ffmpeg-libav-and-avconv Elder Geek 7 лет назад 0
@ElderGeek Для Ubuntu 14.04 LTS в официальных репозиториях нет `ffmpeg`. Ссылка, которую вы дали правильно, гласит: ** FFmpeg вернулся в Ubuntu 15.04 «Vivid Vervet». **. Однако ситуация изменилась, поскольку 16.04 LTS вышли. Tino 7 лет назад 0
@Tino Это действительно факт. Однако я бы не стал приравнивать недоступность к не существует в репозиториях. Вы заметите, что он доступен для Trusty (14.04) здесь: https://ffmpeg.org/download.html Elder Geek 7 лет назад 0
0
numberer6

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

$ mediainfo --Inform = 'Video;% FrameRate% \ n' VTS_07_4.VOB

23,976

0
xenoid

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

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

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

Похожие вопросы