2006-01-16 22:02:54 +01:00
-- Aegisub Automation demonstration script
-- Original written by Niels Martin Hansen
-- Given into the public domain
-- But still, please don't use the effect generated by this script
-- (unchanged) for your own works.
2006-07-11 00:07:24 +02:00
-- Note that many of the techniques used in this script are heavily deprecated, much of the processing done
-- is also done by the karaskel scripts.
-- In fact, this can almost be viewed as an example of how *not* to do things...
-- Since this script assumes some rather specific things about the ASS input, it might not be very useful at first.
-- The original ASS file this was written for is available upon request.
2006-01-16 22:02:54 +01:00
include ( " utils.lua " )
name = " Advanced karaoke effect "
description = " An advanced karaoke effect, making heavy use of both line-copying and per-syllable text placement. Also demonstrates how to treat lines differently, based on their style, and syllables differently based on the timing tag used. "
version , kind , configuration = 3 , ' basic_ass ' , { }
function process_lines ( meta , styles , lines , config )
local output = { n = 0 }
math.randomseed ( 5922 ) -- just to make sure it's initialised the same every time
for curline = 0 , lines.n - 1 do
aegisub.report_progress ( curline / lines.n * 100 )
local lin = lines [ curline ]
if lin.kind == " dialogue " and lin.style == " op romaji " then
doromaji ( lin , output , styles [ " op romaji " ] , 30 )
elseif lin.kind == " dialogue " and lin.style == " op kanji " then
-- Just one of these lines should be uncommented.
-- This script was written before configuration worked, otherwise it would use configuration
-- to select which of the two effects to use for "op kanji" style lines.
--doromaji(lin, output, styles["op kanji"], 20)
dokanji ( lin , output , styles [ " op kanji " ] )
else
-- Unknown lines are copied verbatim
table.insert ( output , lin )
end
end
return output
end
function doromaji ( lin , output , sty , linetop )
aegisub.set_status ( lin.text_stripped )
--local linetop = 50
-- prepare syllable data
local linewidth = 0
local syltime = 0
local syls = { n = 0 }
for i = 1 , lin.karaoke . n - 1 do
local syl = lin.karaoke [ i ]
syl.width , syl.height , syl.descent , syl.extlead = aegisub.text_extents ( sty , syl.text_stripped )
syl.left = linewidth
syl.start_time = syltime
syl.end_time = syltime + syl.duration
syltime = syltime + syl.duration
if syl.kind == " kf " and ( syl.text == " " or syl.text == " " ) then
-- The font this effect was made to work with has too wide spaces, so make those half width
syl.width = math.floor ( syl.width / 2 )
syl.kind = " space "
elseif syl.kind == " kf " then
syl.kind = " deco "
elseif syl.kind == " k " then
syl.kind = " reg "
elseif syl.kind == " ko " then
syl.kind = " dance "
else
syl.kind = " ignore "
end
if syl.text == " # " then
syls [ syls.n - 1 ] . duration = syls [ syls.n - 1 ] . duration + syl.duration
syls [ syls.n - 1 ] . end_time = syls [ syls.n - 1 ] . end_time + syl.duration
else
linewidth = linewidth + syl.width
syls [ syls.n ] = syl
syls.n = syls.n + 1
end
end
local lineofs = math.floor ( ( 640 - linewidth ) / 2 )
for i = 0 , syls.n - 1 do
local syl = syls [ i ] , copy_line ( lin )
if syl.kind == " space " then
-- Spaces are skipped. Since the width of them is already incorporated in the position calculations
-- for the following syllables, they can safely be stripped from output, without losing the spaces.
elseif syl.kind == " ignore " then
-- These are actually syllable kinds we don't know what to do about. They are not included in the output.
else
local startx , starty , shakex , shakey , enterangle
-- angle to enter from
enterangle = math.rad ( ( 180 / lin.karaoke . n ) * i - 90 )
-- position to enter from (350 pixels from (320, 50))
startx = math.sin ( enterangle ) * 350 + 320
starty = linetop - math.cos ( enterangle ) * 350
if syl.kind == " reg " then
shakex = ( syl.left + lineofs ) + math.random ( - 5 , 5 )
shakey = linetop + math.random ( - 5 , 5 )
elseif syl.kind == " deco " then
shakex , shakey = syl.left + lineofs , linetop
elseif syl.kind == " dance " then
shakex = ( syl.left + lineofs ) + math.random ( - 5 , 5 )
shakey = linetop + math.random ( - 5 , 5 )
end
-- origin for rotation
local orgx = syl.left + lineofs + syl.width / 2
local orgy = linetop + syl.height / 2
-- entry effect
local enterlin = copy_line ( lin )
enterlin.start_time = lin.start_time - 40
enterlin.end_time = lin.start_time
enterlin.text = string.format ( " { \\ move(%d,%d,%d,%d) \\ fr%d \\ t( \\ fr0) \\ an7}%s " , startx , starty , shakex , shakey , - math.deg ( enterangle ) , syl.text )
table.insert ( output , enterlin )
-- main highlight effect
local newlin = copy_line ( lin )
local hilistart , hilimid , hiliend = syl.start_time * 10 , ( syl.start_time + syl.duration / 2 ) * 10 , ( syl.start_time + syl.duration ) * 10
newlin.text = string.format ( " \\ move(%d,%d,%d,%d,%d,%d) \\ an7}%s " , shakex , shakey , syl.left + lineofs , linetop , hilistart , hiliend , syl.text )
newlin.layer = 1
if syl.kind == " dance " then
local fx = string.format ( " \\ org(%d,%d) \\ t(%d,%d, \\ fr30) \\ t(%d,%d, \\ fr-30) \\ t(%d,%d, \\ 3c&H0000ff&) \\ t(%d,%d, \\ 3c&H000080&) \\ t(%d,%d, \\ fr0) " , orgx , orgy , hilistart , hilistart + 20 , hilistart + 20 , hiliend , hilistart , hilimid , hilimid , hiliend , hiliend , hiliend + syl.duration * 10 )
newlin.text = fx .. newlin.text
else
local fx = string.format ( " \\ t(%d,%d, \\ 3c&H0000ff&) \\ t(%d,%d, \\ 3c&H000080&) " , hilistart , hilimid , hilimid , hiliend )
newlin.text = fx .. newlin.text
end
local bord = copy_line ( newlin )
bord.layer = 0
bord.text = " { " .. bord.text
newlin.text = " { \\ bord0 " .. newlin.text
table.insert ( output , bord )
table.insert ( output , newlin )
-- leave effect
-- cut the line over in two, lower half "drops down", upper just fades away
local tophalf = copy_line ( lin )
tophalf.start_time = lin.end_time
tophalf.end_time = lin.end_time + 100
tophalf.text = string.format ( " \\ 3c&H000080& \\ fad(0,700) \\ pos(%d,%d) \\ an7}%s " , syl.left + lineofs , linetop , syl.text_stripped )
local bottomhalf = copy_line ( tophalf )
tophalf.text = string.format ( " { \\ t(0,200, \\ 1c&H000080&) \\ clip(0,0,640,%d)%s " , linetop + syl.height / 2 , tophalf.text )
bottomhalf.text = string.format ( " { \\ org(%d,%d) \\ clip(0,%d,640,480) \\ t(0,200, \\ 1c&H000080&) \\ t(200,1000,1.2, \\ frx90 \\ clip(0,%d,640,480)%s " , 320 , linetop + syl.height , linetop + syl.height / 2 , linetop + syl.height , bottomhalf.text )
table.insert ( output , tophalf )
table.insert ( output , bottomhalf )
end
end
end
function dokanji ( lin , output , sty )
aegisub.set_status ( lin.text_stripped )
local fontname = " @HGSHigemoji "
local lineheight = 0
local syltime = 0
local syls = { n = 0 }
for i = 1 , lin.karaoke . n - 1 do
local syl = lin.karaoke [ i ]
syl.height , syl.width , syl.descent , syl.extlead = aegisub.text_extents ( sty , syl.text_stripped )
syl.start_time = syltime
syl.end_time = syltime + syl.duration
syltime = syltime + syl.duration
if syl.text == " # " then
syls [ syls.n - 1 ] . duration = syls [ syls.n - 1 ] . duration + syl.duration
syls [ syls.n - 1 ] . end_time = syls [ syls.n - 1 ] . end_time + syl.duration
--elseif syl.text == "" then
-- skip
else
lineheight = lineheight + syl.height
syls [ syls.n ] = syl
syls.n = syls.n + 1
end
end
for i = 0 , syls.n - 1 do
local syl = syls [ i ]
local top = 170
for j = 0 , 8 do
if i + j >= syls.n then
break
end
local newlin = copy_line ( lin )
newlin.start_time = lin.start_time + syl.start_time
newlin.end_time = newlin.start_time + syl.duration
local startalpha , targetalpha
if j == 0 then
startalpha = 0
targetalpha = 255
else
startalpha = j * 255 / 8
targetalpha = ( j - 1 ) * 255 / 8
end
newlin.text = string.format ( " { \\ fn%s \\ an7 \\ fr-90 \\ move(%d,%d,%d,%d) \\ 1a&H%2x& \\ 3a&H%2x& \\ t( \\ 1a&H%2x& \\ 3a&H%2x&)}%s " , fontname , 620 , top , 620 , top - syl.height , startalpha , startalpha , targetalpha , targetalpha , syls [ i + j ] . text )
top = top + syls [ i + j ] . height
table.insert ( output , newlin )
end
end
end