AviSynth. Песня с текстом.

/ Просмотров: 867
Метки:
AviSynth. Песня с текстом.

Задумал я один проект. Есть много старых аудиозаписей, которые хотелось бы выложить на YouTube. В качестве видеоряда решено было сделать фон из картинки и движущийся текст песни, на подобии финальных титров кинофильма. Конечно же хочется все это автоматизировать, значит будем использовать AviSynth.

1. Вводные данные: В наличии у нас имеется фоновая картинка уже нужного размера и пропорций, звуковой файл песни, текстовый файл со словами и, еще один текстовый файл с названием. Все это складывем в папку запускаем bat`ник и получаем видео и обложку.

2. Необходbмые плагины:

NicAudio - для загрузки mp3

RT_Stats - для загрузки текста из файла

SubtitleEx - для плавного затухания заголовка композиции.

3. Переходим к основному скрипту для генерации видео main.avs.

# Подгружаем плагины:
LoadPlugin("..\RT_Stats_25.dll")
LoadPlugin("..\NicAudio.dll")
LoadPlugin("..\SubtitleEx_25.dll")
# Загружаем аудио
#audiotrack=NicMPG123Source("audio.mp3") #для np3
audiotrack=WavSource("audio.wav") #для wav
# вычисляем длительность видео в кадрах. Исходим из того, что частота кадров 24 герц.
FullFrameCount=audiotrack.AudioLength*24/audiotrack.AudioRate
# Загружаем фоновую картинку:
videotrack=ImageReader("image.jpg", end=FullFrameCount, pixel_type="RGB32")
# соединяем аудио и видеодорожки
AudioDub(videotrack, audiotrack)

Далее представим, что наши титры это прямоугольник. Высота прямоугольника = количеству строк умноженное на высоту шрифта. С помощью функции Animate мы будем перемещать этот прямоугольник так, чтобы в начале видео первая строка титров располагалась в центре экрана по вертикале, а в конце видео в центре экранна должна оказаться последняя строка.

Вот как это выглядит визуально:

# вычисляем размер шрифта, размер должен быть пропорционален размеру кадра нашего видео
FontSize=int(width/20)
# помещаем содержание тестового файла со славами песни в переменную
S=RT_ReadTxtFromFile("text.txt")
# помещаем содержание тестового файла с заголовком в переменную
T=RT_ReadTxtFromFile("title.txt")
# вычисляем количество строк в тексте песни
LineCount=RT_TxtQueryLines(S)
# текст песни будем выравнивать по горизонтали по центру, для этого вычислим координаты центра
XPosition=int(width/2)
# вычисляем высоту титров а пикселях
TextHight=LineCount*FontSize
# Стартовая позиция первой строки титров по вертикал - центр экрана
BeginTextPositionH=int(Height/2)
# Финальная позиция последней строки титров по вертикал - центр экрана
EndTextPositionH=-1*(TextHight-(Height/2))
ZerroFrame=(BeginTextPositionH+1)*FullFrameCount/TextHight
# Затемняем фоновую картинку
Levels(0, 1, 255, 1, 128)
# выводим на 12 секунд название песни и ее автора. Потом заголовок плавно исчезает.
SubtitleEx(RT_TxtGetLine(T, 0), x=XPosition, y=FontSize, firstframe=0, lastframe=360, size=FontSize, effects="c,f(0,50)")
SubtitleEx(RT_TxtGetLine(T, 1), x=XPosition, y=int(FontSize*1.5), firstframe=0, lastframe=360, size=FontSize/2, effects="c,f(0,50)")
# Двигаем "прямоугольник" титров.
Animate(0,FullFrameCount,"Subtitle", \
    S,XPosition,BeginTextPositionH,0,FullFrameCount,"Arial",FontSize,$FFFF00,0,5,0,-1, \
    S,XPosition,EndTextPositionH,0,FullFrameCount,"Arial",FontSize,$FFFF00,0,5,0,-1)
# выводим водяной знак (понты)
WriteLogo(last,0,FontSize)
function WriteLogo(clip c, int i, FontSize)
{
    step=4
    logo="      xbe.tomsk.ru "
    i=i+1
    clp = Subtitle(trim(c,(i-1)*step, i*step-1), MidStr(logo, 1, i)+"_", font="calibri", size=FontSize*0.7, text_color=$aaaaaa, align=3)
    return( i==StrLen(logo) ? clp + Subtitle(trim(c,i*step, 0), MidStr(logo, 1, i)+"  ", font="calibri", size=FontSize*0.7, text_color=$aaaaaa, align=3) : clp + WriteLogo(c,i,FontSize))
}
# начальное и финальное затухание.
FadeOut(FadeIn(50),50)

4. На этом можно было бы закончить, да вот вылез один неприятный баг. Наши титры движутся от BeginTextPositionH до EndTextPositionH, при этом EndTextPositionH < 0. В момент когда вертикальная координата равна 0, титры перескакивают в центр экрана на пару кадров, а потом возвращаются на прежние координаты. Не понятно? Вот как это выглядит на примере небольшого скрипта:

BlankClip(length=50, width=72, height=40)
Animate(0,50,"Subtitle", \
                "Text1\nText2",36,10,0,50,"Arial",24,$FFFF00,0,5,0,-1, \
                "Text1\nText2",36,-10,0,50,"Arial",24,$FFFF00,0,5,0,-1)

На этот счет я создал issue. А пока придется делать "костыль".

Вычислим на каком кадре титры переходят через 0. Одной командой будем двигать титры до нулевой координаты, другой командой - от нулевой.

# Вычислим на каком кадре титры переходят через 0.
ZerroFrame=(BeginTextPositionH+1)*FullFrameCount/TextHight
# двигаем от центра экрана до 0
Animate(0,ZerroFrame,"Subtitle", \
                S,XPosition,BeginTextPositionH,0,ZerroFrame,"Arial",FontSize,$FFFF00,0,5,0,-1, \
                S,XPosition,0,0,ZerroFrame,"Arial",FontSize,$FFFF00,0,5,0,-1)
# двигаем от 0 до конца видео
Animate(ZerroFrame+1,FullFrameCount,"Subtitle", \
                S,XPosition,-4,ZerroFrame+1,FullFrameCount,"Arial",FontSize,$FFFF00,0,5,0,-1, \
                S,XPosition,EndTextPositionH,ZerroFrame+1,FullFrameCount,"Arial",FontSize,$FFFF00,0,5,0,-1)

Источник основной идеи

5. Сисок используемых файлов:

main.avs - основной скрипт для формирования видео;

text.txt - текст песни;

title.txt - файл с заголовком и информацией об авторе;

cover.avs - скрипт для создания обложки;

video.cmd - cmd`шник для создания видеофайла;

cover.cmd - cmd`шник jpeg`а обложки;

Вот так это выглядит в результате: