Как извлечь время продолжительности из вывода ffmpeg?

Чтобы получить много информации о медиа файле, вы можете сделать

ffmpeg -i <filename>

где он выведет много строк, в частности

Duration: 00:08:07.98, start: 0.000000, bitrate: 2080 kb/s

Я хотел бы выводить только 00:08:07.98, поэтому я пытаюсь

ffmpeg -i file.mp4 | grep Duration| sed 's/Duration: \(.*\), start/\1/g'

Но он печатает все, а не только длину.

Даже ffmpeg -i file.mp4 | grep Duration выводит все.

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

Ответ 1

ffmpeg записывает эту информацию в stderr, а не stdout. Попробуйте следующее:

ffmpeg -i file.mp4 2>&1 | grep Duration | sed 's/Duration: \(.*\), start/\1/g'

Обратите внимание на перенаправление от stderr до stdout: 2>&1

EDIT:

Ваш оператор sed тоже не работает. Попробуйте следующее:

ffmpeg -i file.mp4 2>&1 | grep Duration | awk '{print $2}' | tr -d ,

Ответ 2

Вы можете использовать ffprobe:

ffprobe -i <file> -show_entries format=duration -v quiet -of csv="p=0"

Он выведет продолжительность в секундах, например:

154.12

Добавление опции -sexagesimal будет выдавать длительность как часы: минуты: секунды .microseconds:

00:02:34.12

Ответ 3

Из моего опыта многие инструменты предлагают желаемые данные в какой-либо структуре таблицы/упорядочения, а также предлагают параметры для сбора определенных частей этих данных. Это относится, например, к smartctl, nvidia-smi и ffmpeg/ffprobe. Проще говоря - часто нет необходимости собирать данные вокруг или открывать подоболочки для такой задачи.

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

$ ffmpeg --version
ffmpeg version 2.2.3 ...

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

#!/usr/bin/env bash
input_file="/path/to/media/file"

# Get raw duration value
ffprobe -v quiet -print_format compact=print_section=0:nokey=1:escape=csv -show_entries format=duration "$input_file"

Объяснение:

"- v quiet": не выводить ничего, кроме нужного значения исходных данных

"- print_format": использовать определенный формат для печати данных

"compact =": использовать компактный выходной формат

"print_section = 0": не печатать имя раздела

": nokey = 1": не печатайте ключ пары ключ: значение

": escape = csv": вывести значение

"- show_entries format = duration": Получить записи поля с именем duration внутри раздела с именем format

Ссылка: справочные страницы ffprobe

Ответ 4

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

amber ~ > mediainfo --Output=General;%Duration% ~/work/files/testfiles/+h263_aac.avi 
24840

Ответ 5

ffmpeg -i abc.mp4 2>&1 | grep Duration | cut -d ' ' -f 4 | sed s/,//

выводит вывод

HH: MM: SS.milisecs

Ответ 6

Для тех, кто хочет выполнить одни и те же вычисления без дополнительного программного обеспечения в Windows, введите script для командной строки script:

set input=video.ts

ffmpeg -i "%input%" 2> output.tmp

rem search "  Duration: HH:MM:SS.mm, start: NNNN.NNNN, bitrate: xxxx kb/s"
for /F "tokens=1,2,3,4,5,6 delims=:., " %%i in (output.tmp) do (
    if "%%i"=="Duration" call :calcLength %%j %%k %%l %%m
)
goto :EOF

:calcLength
set /A s=%3
set /A s=s+%2*60
set /A s=s+%1*60*60
set /A VIDEO_LENGTH_S = s
set /A VIDEO_LENGTH_MS = s*1000 + %4
echo Video duration %1:%2:%3.%4 = %VIDEO_LENGTH_MS%ms = %VIDEO_LENGTH_S%s

Тот же ответ отправлен здесь: Как обрезать последние N секунд из видео TS

Ответ 7

Я бы просто сделал это на С++ с текстовым файлом и извлек токены. Зачем? Я не эксперт по терминалу Linux, как другие.
Чтобы настроить его, я бы сделал это в Linux..

ffmpeg -i 2>&1 | grep "" > mytext.txt

а затем запустите некоторое приложение С++, чтобы получить необходимые данные. Возможно, извлеките все важные значения и переформатируйте их для дальнейшей обработки с помощью токенов. Мне просто нужно будет работать над своим собственным решением, и люди просто посмеются над мной, потому что я новичок в Linux, и мне не нравится слишком много сценариев.

Ответ 8

Argh. Забудь об этом. Похоже, я должен получить паутину из моего программирования на C и С++ и использовать это вместо этого. Я не знаю всех трюков с оболочкой, чтобы заставить его работать. Вот как далеко я добрался.

ffmpeg -i myfile 2>&1 | grep "" > textdump.txt

а затем, скорее всего, выберем продолжительность с помощью С++-приложения, извлекая токены.

Я не отправляю решение, потому что сейчас я не хороший человек.

Обновление - у меня есть мой подход к получению этой временной отметки времени

Шаг 1 - Получите информацию о мультимедиа в текстовый файл
`ffprobe -i myfile 2>&1 | grep "" > textdump.txt`
<Б > ИЛИ
`ffprobe -i myfile 2>&1 | awk '{ print }' > textdump.txt`

Шаг 2 - Входите в нужную информацию и извлеките ее
cat textdump.txt | grep "Duration" | awk '{ print $2 }' | ./a.outкод >
Обратите внимание на a.out. Это мой код на C, чтобы вырезать результирующую запятую, потому что вывод - это что-то вроде 00: 00: 01.33,
Вот код C, который принимает stdin и выводит нужную информацию. Я должен был взять больше и меньше, чем выходить на просмотр.

#include stdio.h #include string.h void main() { //by Admiral Smith Nov 3. 2016 char time[80]; int len; char *correct; scanf("%s", &time); correct = (char *)malloc(strlen(time)); if (!correct) { printf("\nmemory error"); return; } memcpy(correct,&time,strlen(time)-1); correct[strlen(time)]='/0'; printf("%s", correct); free(correct); }

Теперь форматы вывода корректно, как 00: 00: 01.33

Ответ 9

Вы можете попробовать следующее:

/*
* Determine video duration with ffmpeg
* ffmpeg should be installed on your server.
*/
function mbmGetFLVDuration($file){

  //$time = 00:00:00.000 format
  $time =  exec("ffmpeg -i ".$file." 2>&1 | grep 'Duration' | cut -d ' ' -f 4 | sed s/,//");

  $duration = explode(":",$time);
  $duration_in_seconds = $duration[0]*3600 + $duration[1]*60+ round($duration[2]);

  return $duration_in_seconds;

}

$duration = mbmGetFLVDuration('/home/username/webdir/video/file.mov');
echo $duration;

Ответ 10

ffmpeg был заменен avconv: просто замените avconb на ответ Луи Марасио.

avconv -i file.mp4 2>&1 | grep Duration | sed 's/Duration: \(.*\), start.*/\1/g'

Примечание: добавочный. * после начала, чтобы получить время в одиночестве!!