Можете его записать в код время?



У меня есть потребность записать в коде времени видео и мне интересно, если это то, что ffmpeg способен?

676   7  

7 ответов:

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

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

Edit: я работаю над этой проблемой, потому что это интересный вопрос/Проект Для меня. У меня есть продвиньтесь немного дальше в решении, написавсценарий 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

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

Фильтр drawtext 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"

Вы должны указать формат тайм-кода в виде hh: mm: ss [:;,] ff. Обратите внимание, что вы должны экранировать двоеточия в строке формата timecode, и вы должны указать скорость timecode (здесь 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

Это добавило бы имя клипа и скользящий тайм-код в полупрозрачной коробке в нижнем центре кадра 1920х1080

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 заданную папку, содержащую .Мова, .MP4 и .Файлы MTS (с помощью команды -filter он ищет файлы с *.М* в названии, которое вам придется изменить если бы ты это делал .AVI-файлы), и он немного более минимален, он просто использует libx264 с настройками по умолчанию в качестве выходного кодека и не указывает шрифт и т. д. Временной код в этом случае записывается в верхнем левом углу кадра.

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

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

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

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

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

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

Другой пример: a команда для вставки даты и времени в черный прямоугольник, несколько пикселей от верхнего левого угла и "некоторые отступы" (на самом деле, два пробела и новые строки по краям):

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

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

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 нарисует только второй текст. Вы можете комбинировать фильтры с запятой, как я показал выше.

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

Самое простое решение, которое я нашел, чтобы показать часы, когда файл был захвачен, а не его продолжительность и он работает /на основе этого поста, спасибо!/ 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

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

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

Это создает штамп в формате HH:MM:SS; вы можете изменить его на любой другой, используя strftime.

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

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

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

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

Comments

    Ничего не найдено.