Может ли ffmpeg записывать временной код? - PullRequest
16 голосов
/ 03 июля 2010

Мне нужно записать временной код в видео, и мне интересно, на что способен ffmpeg?

Ответы [ 7 ]

23 голосов
/ 03 сентября 2012

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

-vf drawtext="fontsize=15:fontfile=/Library/Fonts/DroidSansMono.ttf:\
timecode='00\:00\:00\:00':rate=25:text='TCR\:':fontsize=72:fontcolor='white':\
boxcolor=0x000000AA:box=1:x=860-text_w/2:y=960"

Вы должны указать формат тайм-кода в форме чч: мм: сс [:;,] ff.Обратите внимание, что вы должны экранировать двоеточия в строке формата временного кода, и вы должны указать скорость временного кода (здесь 25fps).Вы также можете указать дополнительный текст - здесь это «TCR:»

Вы можете получить частоту кадров с помощью ffprobe и немного оболочки fu:

frame_rate=$(ffprobe -i "movie.mov" -show_streams 2>&1|grep fps|sed "s/.*, \([0-9.]*\) fps,.*/\1/")

Так что вы можете легко подключить все этовместе в сценарии пакетной обработки, например,

for i in *.mov
frame_rate=$(ffprobe -i "$i" -show_streams 2>&1|grep fps|sed "s/.*, \([0-9.]*\) fps,.*/\1/")
clipname=${(basename "$i")/\.*/}
ffmpeg -i "$i" -vcodec whatever -acodec whatever \
-vf drawtext="fontsize=15:fontfile=/Library/Fonts/DroidSansMono.ttf:\
timecode='00\:00\:00\:00':rate=$frame_rate:text='$clipname' TCR:':\
fontsize=72:fontcolor='white':boxcolor=0x000000AA:\
box=1:x=860-text_w/2:y=960" "${i/.mov/_tc.mov}"
done

Это добавит имя клипа и временной код прокрутки в полупрозрачном поле внизу в центре кадра 1920x1080

Edit Так как я перешел на темную сторону, я теперь делаю это в среде Windows Powershell, и вот что я использую:

ls -R -File -filter *.M*|%{
ffmpeg -n -i $_.fullname -vf drawtext="fontsize=72:x=12:y=12:`
timecode='00\:00\:00\:00':rate=25:fontcolor='white':`
boxcolor=0x000000AA:box=1" `
("c:\path\to\destination\{0}" -F ($_.name -replace 'M[OPT][V4S]', 'mp4'))}

Это создает mp4s с учетом папки, содержащей .MOV,.Файлы MP4 и .MTS (с помощью команды -filter он ищет файлы с * .M * в имени, которые вы должны были бы изменить, если бы вы работали с файлами .AVI), и он немного более минималистичный, он просто используетlibx264 с настройками по умолчанию в качестве выходного кодека и без указания шрифта и т. д. В этом случае временной код записывается в верхнем левом углу кадра.

15 голосов
/ 01 декабря 2013

Фильтр drawtext , упомянутый в ответе @ stib , является ключом для вставки времени.Однако использование параметра timecode не соответствует времени настенных часов.Если вы неправильно укажете параметр r (timecode_rate), тогда ваше время не будет соответствовать времени воспроизведения.

Существуют другие параметры, например, параметр text='%{prt}' позволяет отображать прошедшее время с микросекундами.точность.Команда:

ffmpeg -i video.mp4 -vf "drawtext=text='%{prt}'" output.mp4

Чтобы получить часы, мне пришлось использовать устаревшую опцию strftime.У этого есть недокументированная опция basetime, которая может использоваться, чтобы установить время начала в микросекундах .Пример, в котором я установил время запуска на 12:00 1 декабря 2013 года (часть $(...) - это расширение оболочки, выполненное оболочкой) и отображает только время (возможные форматы см. В руководстве strftime *)1019 *):

ffmpeg -i video.mp4 -vf "drawtext=expansion=strftime: \
    basetime=$(date +%s -d'2013-12-01 12:00:00')000000: \
    text='%H\\:%S\\:%S'" output.mp4

\\: используется для экранирования :, который в противном случае получил бы значение разделителя опций.

Другой пример: команда для вставки даты+ время внутри черного ящика, несколько пикселей от верхнего левого угла и «некоторое заполнение» (фактически, два пробела и новые строки по краям):

newline=$'\r'
ffmpeg -i video.mp4 -vf "drawtext=x=8:y=8:box=1:fontcolor=white:boxcolor=black: \
    expansion=strftime:basetime=$(date +%s -d'2013-12-01 12:00:00')000000: \
    text='$newline %Y-%m-%d %H\\:%M\\:%S $newline'" output.mp4

Другой пример, чтобы получить микросекунды нижеclock:

newline=$'\r'
ffmpeg -i video.mp4 -vf "drawtext=expansion=strftime: \
    basetime=$(date +%s -d'2013-12-01 12:00:00')000000: \
    text='$newline %H\\:%M\\:%S $newline':fontcolor=white:box=1:boxcolor=black, \
    drawtext=text='$newline %{pts} $newline': \
    y=2*th/3:box=1:fontcolor=white:boxcolor=black:" output.mp4

При этом используется тот факт, что текст на самом деле имеет длину в три строки и что оба текста имеют добавленную и добавленную новую строку (возврат каретки, ^M).(Без этой новой строки пробел удаляется)

Другие подсказки:

  • -vf и -filter:v равны.
  • Нельзя указывать фильтры несколько разНапример, -vf drawtext=text=1 -vf drawtext=text=2 будет рисовать только второй текст.Вы можете комбинировать фильтры с запятой, как я показал выше.
3 голосов
/ 03 июля 2010

Короткий ответ, нет.

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

Редактировать: Я былработать над этой проблемой, потому что это интересный вопрос / проект для меня.Я немного продвинулся в решении, написав скрипт Perl , который сгенерирует файл .srt со встроенным в него временным кодом для любого данного видеофайла, из которого FFmpeg настроен для чтения.метаданные.Он использует библиотеку Video::FFmpeg для чтения продолжительности и сохраняет файл субтитров как ${video}.srt.Это сделает так, что он будет автоматически отображаться в Mplayer, если вы вставите в ваш ~/.mplayer/config следующие строки:

# select subtitle files automatically in the current directory, all files
# matching the basename of the current playing file
sub-fuzziness=1

Все еще работаете над тем, как расположить и наложить визуализированные субтитры на видео и перекодироватьв том же формате.Я буду обновлять этот пост, как я знаю больше.

2 голосов
/ 11 августа 2012

в более поздних сборках вы можете использовать фильтр drawtext («t» в его примерах, как я полагаю, является меткой времени кадра) для вставки текста. Он также работает для srtftime в «текущее» системное время.

1 голос
/ 09 августа 2015

Самое простое решение, которое я нашел, чтобы показать часы, когда файл был захвачен, а не его продолжительность и он работает / основан на этом посте, спасибо! / Is

D:\Temp\2>ffmpeg.exe -i test.avi -vf "drawtext=fontfile=C\\:/Windows/Fonts/arial.ttf:timecode='00\:20\:10\:00':rate=25:text='TCR\:':fontsize=46:fontcolor=white:x=500:y=50: box=1: boxcolor=0x00000000@1"  -f mp4 textts.mp4

Так просто в таймкодеВаше время старта, тогда счет идет хорошо!Пример для Windows

0 голосов
/ 12 августа 2017

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

ffmpeg -i test.mp4 -vf \
    "drawtext=fontfile=arialbd.ttf:text='%{pts\:gmtime\:0\:%H\\\:%M\\\:%S}'" test.avi

Это создает штамп вФормат ЧЧ: ММ: СС;Вы можете изменить его на любое, используя strftime .

. Может показаться, что он вставит метку времени с gmtime, но это не так.Фактически, он передает текущее время видео в секундах в gmtime, производя дату 1/1/1970 и время, которое, однако, много секунд после полуночи.Таким образом, вы просто отбрасываете часть даты и используете часть времени.

Обратите внимание на экранированные двоеточия triple в функции pts, что вам придется сделать, если вы введете ее как Iделал выше.Также вы можете видеть, что я скопировал файл шрифта для Arial Bold и поместил его прямо в рабочий каталог для простоты.

0 голосов
/ 13 июля 2010

FFMPEG сможет выполнить большую часть работы, но он не будет полностью упакован. Используя FFMPEG, вы можете сделать так, чтобы он декодировал все кадры в последовательности, и предоставил вам «метку времени презентации» (в некоторых форматах могут быть доступны дополнительные метаданные, относящиеся ко времени, но PTS - это то, что вам нужно для начала работы .) Затем вы сами можете нарисовать текст на декодированной рамке самостоятельно. Я использую Qt для подобных вещей, используя QPainter для QImage с данными кадра, но может быть какой-то другой API для рисования на изображении, которое вы находите более очевидным. Затем используйте API FFMPEG для создания сжатого видео, в котором будут только что нарисованные кадры. Это будет немного сложнее, если вы также хотите аудио. Моя собственная работа не заботится об аудио, поэтому я не потрудился изучить аудио аспекты API. По сути, когда вы выполняете цикл чтения, получая пакеты из файла, некоторые из них будут аудио. Вместо того, чтобы отбрасывать их, как я, вам нужно сохранить их и записать в выходной файл так, как вы их получили.

Я использовал только C API, а не C #, поэтому я не знаю, есть ли какие-то особые ошибки, о которых стоит беспокоиться.

...