У меня есть список .ts
файлов:
out1.ts ... out749.ts out8159.ts out8818.ts
Как я могу получить общую продолжительность (время выполнения) всех этих файлов?
shell-script
video
k961
источник
источник
Ответы:
У меня нет
.ts
здесь, но это работает для.mp4
. Используйтеffprobe
(частьffmpeg
), чтобы получить время в секундах, например:поэтому для всех
.mp4
файлов в текущем каталоге:затем использовать
paste
для передачи выходных данных, чтобыbc
и получить общее время в секундах:Итак, для
.ts
файлов вы можете попробовать:Еще один инструмент, который работает с видеофайлами, которые у меня здесь есть
exiftool
, например:Общая длина всех
.mp4
файлов в текущем каталоге:Вы также можете перенаправить вывод в другую команду, чтобы преобразовать итог
DD:HH:MM:SS
, см. Ответы здесь .Или используйте для этого
exiftool
внутреннююConvertDuration
(вам нужна относительно недавняя версия):источник
ffprobe
до.paste
иbc
! намного чище, чемawk
скажем.bc
этом...| paste -sd+ - | bc
достигается произвольная точность, один недостаток заключается в том, что в некоторыхbc
реализациях либо будет достигнут предел размера строки (например, вseq 429 | paste -sd+ - | bc
OpenSolaris произойдет сбойbc
), либо будет возможно использование всей памяти в других.avprobe
в репозиториях Arch (возможно, потому что он конфликтует сffmpeg
), поэтому не может попробовать его в ATM, но даст ли он вам продолжительность файла, если вы запустите его следующим образом:avprobe -show_format_entry duration myfile.mp4
илиavprobe -loglevel quiet -show_format_entry duration myfile.mp4
? Я думаю, что одна из этих команд должна дать вам одну строку вывода с продолжительностью файла. Не уверен, хотя.Это использует
ffmpeg
и печатает время ожидания в полных секундах:Объяснение:
for f in *.ts; do
повторяет каждый из файлов, заканчивающийся на ".ts"ffmpeg -i "$f" 2>&1
перенаправляет вывод в stderrgrep "Duration" | grep -o " [0-9:.]*, " | head -n1 | tr ',' ' '
изолирует времяawk -F: '{ print ($1 * 3600) + ($2 * 60) + $3 }'
Преобразует время в секундыtimes+=("$_t")
добавляет секунды в массивecho "${times[@]}" | sed 's/ /+/g' | bc
расширяет каждый из аргументов и заменяет пробелы и передает его вbc
общий калькулятор linuxисточник
Оптимизация ответа @ jmunsch и использование
paste
только что полученного из ответа @ slm ответа на вопрос , вы можете получить что-то вроде этого:Как и в случае с jmunsch, я использую
ffmpeg
для печати длительность, игнорируя ошибку об отсутствующем выходном файле и вместо этого ищу в выводе ошибки строку продолжительности. Я обращаюсьffmpeg
ко всем аспектам локали, вынужденным использовать стандартную локаль C, чтобы мне не пришлось беспокоиться о локализованных выходных сообщениях.Далее я использую сингл
awk
вместо егоgrep | grep | head | tr | awk
. Этотawk
вызов ищет (надеюсь уникальную) строку, содержащуюDuration:
. Используя двоеточие в качестве разделителя, эта метка представляет собой поле 1, часы - это поле 2, минуты, поданные 3, и поле секунд 4. Задняя запятая после секунд, кажется, не беспокоит меняawk
, но если у кого-то есть проблемы, он может включатьtr -d ,
в конвейер междуffmpeg
иawk
.Теперь приходит часть из слх: Я использую
paste
заменить новую строку с плюсами, но не затрагивая символ новой строки ( в отличие отtr \\n +
меня был в предыдущей версии этого ответа). Это дает выражение суммы, которое можно подаватьbc
.Вдохновленная идеей использования slm
date
для обработки временных форматов, вот версия, которая использует ее для форматирования результирующих секунд как дней, часов, минут и секунд с дробной частью:Часть внутри
$(…)
точно так же, как и раньше. Используя@
символ в качестве указания, мы используем это как количество секунд с 1 января 1970 года. Результирующая «дата» форматируется как день года, время и наносекунды. С того дня года мы вычитаем один, так как ввод нулевых секунд уже приводит к 1-му дню 1970-го года. Я не думаю, что есть способ получить подсчет числа дней в году, начинающийся с нуля.Финал
sed
избавляется от лишних конечных нулей. Надеемся, чтоTZ
настройка должна принудительно использовать UTC, чтобы переход на летнее время не мешал работе действительно больших коллекций видео. Если у вас есть видео на срок более одного года, этот подход все равно не сработает.источник
Я не знаком с
.ts
расширением, но предположим, что это какой-то тип видеофайла, который вы можете использоватьffmpeg
для определения продолжительности файла, например так:Затем мы можем разделить этот вывод, выбрав только продолжительность.
Так что теперь нам просто нужен способ перебирать наши файлы и собирать эти значения продолжительности.
Примечание: Здесь для моего примера я просто скопировал мой образец файл
some.mp4
и назвал его1.mp4
,2.mp4
и3.mp4
.Преобразование времени в секунды
Следующий фрагмент возьмет длительности сверху и преобразует их в секунды.
Это берет наши длительности и помещает их в переменную
$dur
, когда мы перебираем файлы. Затем этаdate
команда используется для расчета количества секунд в эпоху Unix (1970/01/01). Вот вышеприведеннаяdate
команда, поэтому ее легче увидеть:ПРИМЕЧАНИЕ. Использование
примерdate
таким способом будет работать только в том случае, если продолжительность всех ваших файлов <24 часа (т.е. 86400 секунд). Если вам нужно что-то, что может обрабатывать большие промежутки времени, вы можете использовать это как альтернативу:Подводя итоги
Затем мы можем взять вывод нашего
for
цикла и запустить его вpaste
команду, которая будет включать+
знаки между каждым числом, например, так:Наконец, мы запускаем это в калькуляторе командной строки,
bc
чтобы суммировать их:В результате общая продолжительность всех файлов, в секундах. Это, конечно, может быть преобразовано в другой формат, если это необходимо.
источник
date
может подавиться, еслиffmpeg -i some.mp4 2>&1 | grep -oP "(?<=Duration: ).*(?=, start.*)"
возвращает что-то вроде26:33:21.68
(то есть, длительность ≥ 24 часа / 86400 секунд)paste
мое внимание. Я думаю,java -classpath $(find -name \*.jar | paste -sd:)
это будет очень полезно для меня, учитывая хаки, которые я использовал для этого в прошлом.paste
моя любимая команда 8-)Отказ от принятого ответа и использование классического инструмента обратной полировки UNIX:
То есть: добавляя,
+
аp
затем обматывая это,dc
вы получите свою сумму.источник
bc
получает слишком много любви. Вы все положить+
знаки между каждой линией (вступление в+
), в то время как с обратной полируют вы можете просто Чак+
на конце иp
Ринт его;)Убедитесь, что у вас установлен MPlayer .
источник
Как ubuntu грузим libav вместо ffmpeg:
В большой степени основанный на идеях MvG
источник
Ну, все эти решения требуют немного работы, то, что я сделал, было очень просто, 1)
Перейдите в нужную папку и щелкните правой кнопкой мыши -> открыть с другим приложением
Затем выберите медиаплеер VLC,
вот пример
1.
2.
3.
Вы можете видеть прямо под панелью инструментов, там написан плейлист [10:35:51] , поэтому папка содержит 10 часов 35 минут и 51 секундную продолжительность всего видео.
источник
У меня были подкаталоги в текущей папке, поэтому мне пришлось рекурсивно вычислять продолжительность:
find . -iname '*.mp4' -print0 | xargs --null exiftool -n -q -p '${Duration;our $sum;$_=ConvertDuration($sum+=$_)}' | tail -n1
источник