Как узнать длительность видео в секундах?

70

Как я могу получить продолжительность видео в секундах?

Что я пробовал:

ffmpeg -i file.flv 2>&1 | grep "Duration"
  Duration: 00:39:43.08, start: 0.040000, bitrate: 386 kb/s


mediainfo file.flv | grep Duration
Duration : 39mn 43s

Это то, что близко, но это не так точно, 2383 составляет 39,71 минут

ffmpeg -i file.flv 2>&1 | grep "Duration"| cut -d ' ' -f 4 | sed s/,// | sed 's@\..*@@g' | awk '{ split($1, A, ":"); split(A[3], B, "."); print 3600*A[1] + 60*A[2] + B[1] }'
2383
user2783132
источник

Ответы:

36

Чтобы получить минуты, вы должны разделить 2383 секунды на 60.

39.7167

и затем умножьте дробную часть .7167 на 60, чтобы получить оставшиеся секунды.

43.002

Итак, это 39 минут 43 секунды. Приложение, кажется, дает вам точное значение.

Роберт Харви
источник
97

Просто используйте ffprobeнапрямую. Нет необходимости sed, grepи т.д. Там не несколько «длительностей» вы можете приобрести ( в зависимости от входа).

Формат (контейнер) длительность

$ ffprobe -v error -show_entries format=duration \
  -of default=noprint_wrappers=1:nokey=1 input.mp4

30.024000

При добавлении -sexagesimalпараметра будет использоваться формат единицы времени HOURS: MM: SS.MICROSECONDS:

0:00:30.024000

Продолжительность видеопотока

$ ffprobe -v error -select_streams v:0 -show_entries stream=duration \
  -of default=noprint_wrappers=1:nokey=1 input.mp4
30.000000

Вышеприведенные команды взяты из FFmpeg Wiki: FFprobe Tips .

С участием ffmpeg

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

$ ffmpeg -i input.mp4 -f null -
  …
  frame= 1587 fps=0.0 q=0.0 Lsize=N/A time=00:01:03.48 bitrate=N/A

В этом примере time=00:01:03.48это продолжительность:

Сколько времени это займет, конечно, зависит от сложности декодирования и продолжительности вашего ввода и возможностей вашего компьютера.

llogan
источник
Они не работают для файлов .m2v. У вас также есть решение для них
utdev
@utdev Смотрите ffmpegраздел «С ».
Llogan
Ваше третье решение дает мне неправильное время, мое видео имеет длину 01:19:00, но команда возвращает мне время = 01: 09: 15.32, у вас есть предположение, почему это происходит
utdev
Очень полезна продолжительность медиа потока. Спасибо.
Мы Борг,
Для любого, кто использует avprobe, параметры немного отличаются: avprobe -v error -show_format_entry duration. \ Sample.mp4
Брэд
33

Если у вас есть ffmpeg, вы также должны иметь ffprobe:

ffprobe -i input.file -show_format | grep duration
ffprobe -i input.file -show_format -v quiet | sed -n 's/duration=//p'

Это также даст доли секунд, если это проблема, вы можете в дальнейшем обработать это с помощью sed.

evilsoup
источник
как я могу удалить часть доли секунды?
Тина Дж
@TinaJ Просто передайте это printf, например, | xargs printf %.0f- это вернет целочисленное значение.
Илья Ростовцев
3

Для моего ffmpeg-0.6.5-1.el6.rf.x86_64, чтобы получить только второй, формат команды ffprobe:

ffprobe <file> -show_format 2>&1 | sed -n 's/duration=//p' 
Санри
источник
как я могу удалить часть доли секунды?
Тина Дж
3

Решение с mplayer, которое дает секунды напрямую:

mplayer -identify -frames 0 -vo null -nosound file.flv 2>&1 | awk -F= '/LENGTH/{print $2}'
Мике
источник
2
mediainfo --Output='General;%Duration%' file.flv

Это выводит длительность в миллисекундах как одно целочисленное значение. Нет необходимости в grep / cut / sed / ...

Йозеф Куфнер
источник
Спасибо - это было именно то, что я искал. Может быть установлен на MacOS сbrew install mediainfo
Alex K
0

Я столкнулся с проблемой получения некоторых странных и неправильных метаданных из некоторых видеофайлов, с которыми я работал, и мне не удалось найти шаблон или любой другой тип обработки с использованием кода и таких инструментов, как ffmpeg, mp4box, ffprobe, mediainfo, mplayer, чтобы получить реальную продолжительность видео.

Определение реальной продолжительности видео было требованием для проекта, над которым я работал, и единственный способ, который я нашел, чтобы получить его всегда правильно, - это перекодировать видеофайл с помощью ffmpeg и заставить закодированные файлы игнорировать метаданные исходного файла, например:

ffmpeg -i INPUT_FILENAME -acodec copy -vcodec copy -map_metadata -1 OUTPUT_FILENAME"

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

... а затем получить продолжительность, используя инструмент по вашему выбору. Мне нравится mediainfo, кстати: - "mediainfo FILE --Inform =" Video;% Duration% "дает вам продолжительность в миллисекундах.

satirio
источник
Вы не предоставили больше информации или лучшего решения, чем другие ответы
Сэм
0

Если вам нужно только запросить метаданные:

ffprobe -hide_banner -v quiet -show_streams -print_format flat video.mp4

[...]

streams.stream.0.duration="5221.146009"

[...]

Таким образом, вы можете разобрать это:

while read -r; do
  if [[ "$REPLY" =~ ^streams\.stream\.([0-9])+\.duration=\"([^"]+)\"$ ]]; then
    echo -E Duration of stream "${BASH_REMATCH[1]}": "${BASH_REMATCH[2]}"
  fi
done < <(ffprobe -hide_banner -v quiet -show_streams -print_format flat video.mp4)

Но если вы хотите получить эффективную длительность контейнера, вам нужно расшифровать его:

AV_LOG_FORCE_NOCOLOR=y ffmpeg -nostdin -hide_banner -nostats -loglevel info -i video.mp4 -f null -c copy - 2>&1 | tail -n 2

Процесс декодирования займет некоторое время, пока:

[...]

frame=130527 fps=53271 q=-1.0 Lsize=N/A time=01:27:01.12 bitrate=N/A speed=2.13e+03x
video:152014kB audio:40790kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown

Затем вы можете разобрать это:

if [[ "$(AV_LOG_FORCE_NOCOLOR=y ffmpeg -nostdin -hide_banner -nostats -loglevel info -i video.mp4 -f null -c copy - 2>&1 | tail -n 2 | head -n 1)" =~ \ time=([0-9]+):([0-9]{2}):([0-9]{2})\.([0-9]+) ]]; then
  declare duration=0 us="${BASH_REMATCH[4]}" t
  for t in "${BASH_REMATCH[@]:1:3}"; do
    ((duration *= 60))
    ((duration += ${t#0} ))
  done
  while [ ${#us} -lt 6 ]; do us+=0; done
  ((us >= 500000)) && ((duration++))
  ((duration)) || ((duration++))
fi
echo -E Duration: "$duration"
Luchostein
источник
-6

Если вам нужна ТОЧНАЯ продолжительность, забудьте FFmpeg. Это только дает оценку на основе размера файла и среднего битрейта. Я нашел, в некоторых случаях, предполагаемое время выключения в 2 раза!

В Linux, если файл создается и изменяется только во время указанной видеозаписи, альтернативным решением будет использование времени создания и последнего изменения для вычисления продолжительности, как показано в:

stat -c "%X %Y" video.mpg | awk '{print $2 - $1}'
codechimp
источник
5
Где вы обнаружили, что ffmpeg неточен?
aleb
4
% X - время последнего доступа. % Y - время с момента последнего изменения. Это ничего не говорит о продолжительности видео.
Джо Хилленбранд,
1
Это похоже на тролля
Джордж Чалхуб