Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- This script is made by FichteFoll for Akatsuki-subs
- -- You can see this FX in Angel Beats episode 05 (BD version)
- --[[
- Remarks
- ]]
- include("karaskel.lua")
- script_name = "AB ins4 FX"
- script_description = "some effects"
- script_author = "FichteFoll"
- script_version = 1.0
- -- ############################# handler funcs ##############################
- function macro_script_handler(subs)
- aegisub.progress.title(script_name);
- script_handler(subs)
- aegisub.set_undo_point("\""..script_name.."\"")
- end
- function script_handler(subs)
- aegisub.progress.task("Getting header data...")
- generate_styles(subs)
- local meta, styles = karaskel.collect_head(subs, false)
- undo_fx(subs)
- aegisub.progress.task("Applying effect...")
- local i, maxi = 1, #subs
- for i = 1, maxi do
- if aegisub.progress.is_cancelled() then error("User cancelled") end
- aegisub.progress.task(string.format("Applying effect (%d/%d)...", i, maxi))
- aegisub.progress.set((i-1)/maxi*100)
- local l = subs[i]
- if (l.class == "dialogue" and not l.comment) or (l.class == "dialogue" and l.comment and l.effect == "karaoke") then
- do_fx(subs, meta, styles, l)
- l.comment = true
- l.effect = "karaoke"
- subs[i] = l
- end
- i = i + 1
- end
- aegisub.progress.task("Finished!")
- aegisub.progress.set(100)
- end
- function undo_macro_script_handler(subs)
- aegisub.progress.title("Undo "..script_name);
- undo_fx(subs)
- aegisub.set_undo_point("\"Undo "..script_name.."\"")
- end
- -- ############################# fx funcs ############################## -- action begins here
- local li = 0
- local sub_start, kanji_start = false, false
- function do_fx(subs, meta, styles, baseline)
- local line = table.copy(baseline)
- li = li + 1
- -- variables
- local fade_min, fade_max, fadein_accel = 700, 2000, 3
- local _line = {
- fadein = {
- mindur = fade_min,
- maxdur = fade_max,
- accel = fadein_accel;
- },
- fadeout = {
- mindur = fade_min,
- maxdur = fade_max,
- accel = 1.0/fadein_accel;
- },
- color = {},
- alpha = {};
- }
- local _syl = {
- hl = {
- fadein = {
- dur = 50,
- accel = 0.4;
- };
- fadeout = {
- mindur = 800,
- multi = 1.5,
- ymulti = 3,
- movemulti = 6.0;
- };
- };
- start_off = 0,
- end_off = 0,
- noblank = {n = 0};
- }
- for i, c, a in colors_from_style(styles[line.style]) do
- _line.color[i] = c
- _line.alpha[i] = a
- end
- -- generate positions
- if not kanji_start and line.style:find("kanji") then
- kanji_start = true
- li = 1
- end
- if not sub_start and line.style:find("english") then
- sub_start = true
- li = 1
- end
- if (line.actor:find("overlay") and line.actor:find("start")) then li = li-1 end
- local left = (li % 2 == 0)
- if not (line.style == "ins4_romaji" or line.style == "ins4_romaji-blue") then
- if line.style:find("english") and not line.actor:find("bg") then left = not left; end
- if left then
- line.style = line.style.."-left"
- else
- line.style = line.style.."-right"
- end
- if line.style:find("english") and not line.actor:find("bg") then left = not left; end -- reverse change to let syllables fly into the same direction
- end
- local si = 0
- if (line.style:find("ins4_romaji") or line.style:find("ins4_kanji") or line.style:find("ins4_english")) then
- -- generate syls for non-karaoke part
- if line.style:find("ins4_english") then
- local ltext, ltext_stripped = "", strip_comments(line.text)
- for word in ltext_stripped:words() do -- to generate positions for each word
- _syl.noblank.n = _syl.noblank.n + 1
- _syl.noblank[_syl.noblank.n] = string.format("{\\k1}%s ", word)
- ltext = string.format("%s{\\k1}%s ", ltext, word)
- end
- line.text = ltext
- end
- -- karaoke
- karaskel.preproc_line(subs, meta, styles, line)
- line.effect = "fx" -- affects all copies from line
- line.layer = 2
- for i = 1, line.kara.n do
- local syl = line.kara[i]
- if (syl.duration > 0 and syl.text_stripped ~= '' and syl.text_stripped ~= ' ') then
- _syl.noblank.n = _syl.noblank.n + 1
- _syl.noblank[_syl.noblank.n] = syl
- end
- end
- -- For every syl
- for i = 1, line.kara.n do
- local syl = line.kara[i]
- if (syl.duration > 0 and syl.text_stripped ~= '' and syl.text_stripped ~= ' ') then
- si = si + 1
- local l
- -- fade-in
- l = table.copy(line)
- local maxmovex, maxmovey = line.styleref.fontsize*3, -line.styleref.fontsize*3
- local minmovex, minmovey = line.styleref.fontsize, -line.styleref.fontsize
- if left then maxmovex = maxmovex * -1; minmovex = minmovex * -1; end
- if not line.actor:find("start") then
- local temp, colnum = "{\\an5\\move(%%f,%%f,%%f,%%f)}{\\alpha&HFF&\\t(%f,\\1a%s\\3a%s\\4a%s)}{\\frx%%f\\fry%%f\\frz%%f\\t(\\frx0\\fry0\\frz0)}{\\c%s}%s", 2
- if line.style:find("ins4_english") then colnum = 1 end
- temp = string.format(temp, _line.fadein.accel, _line.alpha[colnum], _line.alpha[3], _line.alpha[4], _line.color[colnum], syl.text_stripped)
- l.text = string.format(temp, line.left+syl.center + math.random()*(maxmovex-minmovex)+minmovex, line.middle + math.random()*(maxmovey-minmovey)+minmovey, line.left+syl.center, line.middle,
- math.random(-360,360), math.random(-360,360), math.random(-70,70))
- l.start_time = line.start_time - math.random(_line.fadein.mindur, _line.fadein.maxdur)
- l.end_time = line.start_time
- subs.append(l)
- end
- -- fade-out
- if not line.actor:find("end") then
- l = table.copy(line)
- minmovex = minmovex * -1; maxmovex = maxmovex * -1;
- minmovey = minmovey * -1; maxmovey = maxmovey * -1;
- local temp = string.format("{\\an5\\move(%%f,%%f,%%f,%%f)}{\\t(%f,\\alpha&HFF&)}{\\t(\\frx%%f\\fry%%f\\frz%%f}%s", _line.fadein.accel, syl.text_stripped)
- l.text = string.format(temp, line.left+syl.center, line.middle,
- line.left+syl.center + math.random()*(maxmovex-minmovex)+minmovex, line.middle + math.random()*(maxmovey-minmovey)+minmovey,
- math.random(-360,360), math.random(-360,360), math.random(-70,70))
- l.start_time = line.end_time
- l.end_time = line.end_time + math.random(_line.fadein.mindur, _line.fadein.maxdur)
- subs.append(l)
- end
- end
- end
- -- Highlight effect
- local show, hide, temp = tonumber(line.actor:match("start:(%d+)")), tonumber(line.actor:match("end:(%d+)")), ""
- if show and show > 0 then temp = string.format("{\\alpha&HFF&\\t(%d,%d,\\alpha&H00&)}", show, show) end
- if hide and hide > 0 then temp = string.format("{\\t(%d,%d,\\alpha&HFF&)}", hide, hide) end
- if (line.style:find("ins4_romaji") or line.style:find("ins4_kanji")) then
- l = table.copy(line)
- l.text = string.format("{\\an5\\pos(%f,%f)}%s%s", line.center, line.middle, temp, line.text)
- subs.append(l)
- elseif line.style:find("ins4_english") then
- l = table.copy(line)
- l.text = string.format("{\\an5\\pos(%f,%f)}%s%s", line.center, line.middle, temp, baseline.text)
- subs.append(l)
- end
- --~ local l = table.copy(line)
- --~ if (line.style:find("ins4_romaji") or line.style:find("ins4_kanji")) then
- --~ subs.append(l)
- --~ end
- end
- end
- -- Collect and generate styles
- function generate_styles(subs)
- local styles = {n = 0}
- local toinsert = {}
- local first_style_line, last_style_line = nil, nil
- -- First pass: collect all existing styles
- for i = 1, #subs do
- if aegisub.progress.is_cancelled() then error("User cancelled") end
- local l = subs[i]
- l.i = i
- if l.class == "style" and l.section == "[V4+ Styles]" then
- if not first_style_line then first_style_line = i end
- -- Store styles into the style table
- styles.n = styles.n + 1
- styles[styles.n] = l
- styles[l.name] = l
- l.margin_v = l.margin_t -- convenience
- -- Generate top-left and -right styles for all
- if l.name:find("^ins4_") and (not l.name:find("-left$") and not l.name:find("-right$")) then
- local fxs = table.copy(l)
- fxs.align = 7
- fxs.name = fxs.name .. "-left"
- table.insert(toinsert, fxs) -- queue to insert in file
- fxs = table.copy(l)
- fxs.align = 9
- fxs.name = fxs.name .. "-right"
- table.insert(toinsert, fxs) -- queue to insert in file
- end
- elseif first_style_line and not last_style_line then
- last_style_line = i
- end
- end
- -- Second pass: insert all toinsert styles that don't already exist
- for i = 1, #toinsert do
- if not styles[toinsert[i].name] then
- -- Insert into styles table
- styles.n = styles.n + 1
- styles[styles.n] = toinsert[i]
- styles[toinsert[i].name] = toinsert[i]
- -- And subtitle file
- subs[-(last_style_line)] = toinsert[i]
- else
- subs[styles[toinsert[i].name].i] = toinsert[i]
- end
- end
- end
- function undo_fx(subs)
- aegisub.progress.task("Unapplying effect...")
- local i, ai, maxi, maxai = 1, 1, #subs, #subs
- while i <= maxi do
- aegisub.progress.task(string.format("Unapplying effect (%d/%d)...", ai, maxai))
- aegisub.progress.set((ai-1)/maxai*100)
- local l = subs[i]
- if (l.class == "dialogue" and not l.comment and l.effect == "fx") then
- subs.delete(i)
- maxi = maxi - 1
- else
- if (l.class == "dialogue" and l.comment and l.effect == "karaoke") then
- l.comment = false
- l.effect = ''
- subs[i] = l
- end
- i = i + 1
- end
- end
- end
- -- ############################### helping funcs ##############################
- function colors_from_style(style)
- local i = 0
- function enum_colors_from_style()
- i = i + 1
- if (i > 4) then
- return nil
- end
- return i, color_from_style(style["color"..tostring(i)]), alpha_from_style(style["color"..tostring(i)])
- end
- return enum_colors_from_style, nil, nil
- end
- function strip_comments(str)
- return str:gsub("{.-}", "")
- end
- -- ############################### validation funcs ##############################
- function macro_validation(subs)
- for i = 1, #subs do
- local l = subs[i]
- if (l.class == "dialogue" and not l.comment) or (l.class == "dialogue" and l.comment and l.effect == "karaoke") then
- return true
- end
- end
- return false
- end
- aegisub.register_filter(script_name, "", 2000, script_handler)
- aegisub.register_macro(script_name, "processing script as templater", macro_script_handler, macro_validation)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement