2013-09-25 19:35:33 +0000 2013-09-25 19:35:33 +0000
75
75

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

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

То, что я пробовал:

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

Ответы (9)

105
105
105
2015-07-26 22:07:37 +0000

Просто используйте 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

Длительность видеопотока

Вышеуказанные команды исходят из FFmpeg Wiki: FFprobe Tips .

С ffmpeg

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

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

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

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

35
35
35
2013-09-25 19:41:05 +0000

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

39.7167

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

43.002

Так что это 39 минут 43 секунды. Похоже, что приложение дает точное значение.

34
34
34
2013-09-25 21:10:07 +0000

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

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

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

3
3
3
2018-05-05 08:00:38 +0000
mediainfo --Output='General;%Duration%' file.flv

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

3
3
3
2013-09-25 19:56:50 +0000

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

mplayer -identify -frames 0 -vo null -nosound file.flv 2>&1 | awk -F= '/LENGTH/{print $2}'
3
3
3
2014-06-16 22:06:49 +0000

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

ffprobe <file> -show_format 2>&1 | sed -n 's/duration=//p'
0
0
0
2019-08-30 19:39:55 +0000

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

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
0
0
0
2017-06-01 01:01:24 +0000

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

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

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

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

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

-6
-6
-6
2015-04-27 01:59:24 +0000

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

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

stat -c "%X %Y" video.mpg | awk '{print $2 - $1}'

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

8
12
3
7
3