185 lines
6.7 KiB
Lua
185 lines
6.7 KiB
Lua
-- Times a sign with {TS 3:24} to 3:24-3:25. Can convert and use a few other formats, like {3:24}, {TS,3:24}, {3,24}, etc.
|
|
-- supported timecodes: {TS 1:23}, {TS 1:23 words}, {TS words 1:23}, {TS,1:23}, {1:23}, {1;23}, {1,23}, {1.23}, [1:23], and variations
|
|
-- Manual: http://unanimated.xtreemhost.com/ts/scripts-manuals.htm#timesigns
|
|
|
|
script_name="Time Signs"
|
|
script_description="Rough-times signs from TS timecodes"
|
|
script_author="unanimated"
|
|
script_version="2.8"
|
|
script_namespace="ua.TimeSigns"
|
|
|
|
local haveDepCtrl,DependencyControl,depRec=pcall(require,"l0.DependencyControl")
|
|
if haveDepCtrl then
|
|
script_version="2.8.0"
|
|
depRec=DependencyControl{feed="https://raw.githubusercontent.com/TypesettingTools/unanimated-Aegisub-Scripts/master/DependencyControl.json"}
|
|
end
|
|
|
|
function signtime(subs,sel)
|
|
for z=#sel,1,-1 do
|
|
i=sel[z]
|
|
line=subs[i]
|
|
text=line.text
|
|
-- format timecodes
|
|
text=text
|
|
:gsub("({.-})({TS.-})","%2%1")
|
|
:gsub("(%d+):(%d%d):(%d%d)",
|
|
function(a,b,c) return a*60+b..":"..c end) -- hours
|
|
:gsub("^(%d%d%d%d)%s%s*","{TS %1}") -- ^1234 text
|
|
:gsub("(%d%d)ish","%1") -- 1:23ish
|
|
:gsub("^([%d%s:,%-]+)","{%1}") -- ^1:23, 2:34, 4:56
|
|
:gsub("^(%d+:%d%d)%s%-%s","{TS %1}") -- ^12?:34 -
|
|
:gsub("^(%d+:%d%d%s*)","{TS %1}") -- ^12?:34
|
|
:gsub("^{(%d+:%d%d)","{TS %1") -- ^{12?:34
|
|
:gsub("^%[(%d+:%d%d)%]:?%s*","{TS %1}") -- ^[12?:34]:?
|
|
:gsub("{TS[%s%p]+(%d)","{TS %1") -- {TS ~12:34
|
|
:gsub("({[^}]-)(%d+)[%;%.,]?(%d%d)([^:%d][^}]-})","%1%2:%3%4") -- {1;23 / 1.23 / 1,23 123}
|
|
:gsub("{TS%s([^%d\\}]+)%s(%d+:%d%d)","{TS %2 %1") -- {TS comment 12:34}
|
|
:gsub(":%s?}","}") -- {TS 12:34: }
|
|
:gsub("|","\\N")
|
|
tc=text:match("^{[^}]-}") or ""
|
|
tc=tc:gsub("(%d+)(%d%d)([^:])","%1:%2%3")
|
|
text=text:gsub("^{[^}]-}%s*",tc)
|
|
if res.blur then text=text:gsub("\\blur[%d%.]+",""):gsub("{}",""):gsub("^","{\\blur"..res.bl.."}") end
|
|
line.text=text
|
|
|
|
tstags=text:match("{TS[^}]-}") or ""
|
|
|
|
times={} -- collect times if there are more
|
|
for tag in tstags:gmatch("%d+:%d+") do table.insert(times,tag) end
|
|
|
|
for t=#times,1,-1 do
|
|
tim=times[t]
|
|
-- convert to start time
|
|
tstid1,tstid2=tim:match("(%d+):(%d%d)")
|
|
if tstid1 then tid=(tstid1*60000+tstid2*1000-500) end
|
|
-- shifting times
|
|
if tid then
|
|
if res.shift then tid=tid+res.secs*1000 end
|
|
-- set start and end time [500ms before and after the timecode]
|
|
line.start_time=tid line.end_time=(tid+1000)
|
|
end
|
|
|
|
-- snapping to keyframes
|
|
if res.snap then
|
|
start=line.start_time
|
|
endt=line.end_time
|
|
startf=ms2fr(start)
|
|
endf=ms2fr(endt)
|
|
diff=250
|
|
diffe=250
|
|
startkf=keyframes[1]
|
|
endkf=keyframes[#keyframes]
|
|
|
|
-- check for nearby keyframes
|
|
for k,kf in ipairs(keyframes) do
|
|
-- startframe snap up to 24 frames back [scroll down to change default] and 5 frames forward
|
|
if kf>=startf-res.kfs and kf<startf+5 then
|
|
tdiff=math.abs(startf-kf)
|
|
if tdiff<=diff then diff=tdiff startkf=kf end
|
|
start=fr2ms(startkf)
|
|
line.start_time=start
|
|
end
|
|
-- endframe snap up to 24 frames forward [scroll down to change default] and 10 frames back
|
|
if kf>=endf-10 and kf<=endf+res.kfe then
|
|
tdiff=math.abs(endf-kf)
|
|
if tdiff<diffe then diffe=tdiff endkf=kf end
|
|
endt=fr2ms(endkf)
|
|
line.end_time=endt
|
|
end
|
|
end
|
|
end
|
|
line.text=line.text:gsub("{TS[^}]-}","{TS "..tim.."}")
|
|
if res.nots then line.text=line.text:gsub("{TS[^}]-}",""):gsub("{(\\[^}]-)}{(\\[^}]-)}","{%1%2}"):gsub("^({[^}]-})%s*","%1") end
|
|
subs.insert(i+1,line)
|
|
if t>1 then table.insert(sel,sel[#sel]+1) end
|
|
end
|
|
if #times>0 then subs.delete(i) end
|
|
end
|
|
if res.copy then taim=0 tame=0
|
|
for z,i in ipairs(sel) do
|
|
l=subs[i]
|
|
if l.start_time==0 then l.start_time=taim l.end_time=tame end
|
|
taim=l.start_time
|
|
tame=l.end_time
|
|
subs[i]=l
|
|
end
|
|
end
|
|
return sel
|
|
end
|
|
|
|
-- Config Stuff --
|
|
function saveconfig()
|
|
savecfg="Time Signs Settings\n\n"
|
|
for key,val in ipairs(GUI) do
|
|
if val.class=="floatedit" or val.class=="intedit" or val.class=="checkbox" and val.name~="save" then
|
|
savecfg=savecfg..val.name..":"..tf(res[val.name]).."\n"
|
|
end
|
|
end
|
|
file=io.open(cfgpath,"w")
|
|
file:write(savecfg)
|
|
file:close()
|
|
ADD({{class="label",label="Config saved to:\n"..cfgpath}},{"OK"},{close='OK'})
|
|
end
|
|
|
|
function loadconfig()
|
|
cfgpath=aegisub.decode_path("?user").."\\timesigns.conf"
|
|
file=io.open(cfgpath)
|
|
if file~=nil then
|
|
konf=file:read("*all")
|
|
file:close()
|
|
for key,val in ipairs(GUI) do
|
|
if val.class=="floatedit" or val.class=="checkbox" or val.class=="intedit" then
|
|
if konf:match(val.name) then val.value=detf(konf:match(val.name..":(.-)\n")) end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function tf(val)
|
|
if val==true then ret="true"
|
|
elseif val==false then ret="false"
|
|
else ret=val end
|
|
return ret
|
|
end
|
|
|
|
function detf(txt)
|
|
if txt=="true" then ret=true
|
|
elseif txt=="false" then ret=false
|
|
else ret=txt end
|
|
return ret
|
|
end
|
|
|
|
|
|
function timesigns(subs,sel)
|
|
ADD=aegisub.dialog.display
|
|
GUI={
|
|
{x=0,y=0,width=4,class="label",label="Check this if all your timecodes are too late or early:"},
|
|
{x=0,y=1,class="checkbox",name="shift",label="Shift timecodes by "},
|
|
{x=1,y=1,width=2,class="floatedit",name="secs",value=-10,hint="Negative=backward / positive=forward",step=0.5},
|
|
{x=3,y=1,class="label",label=" sec."},
|
|
{x=0,y=2,width=4,class="checkbox",name="copy",label="For lines without timecodes, copy from the previous line"},
|
|
{x=0,y=3,width=4,class="checkbox",name="nots",label="Automatically remove {TS ...} comments"},
|
|
{x=0,y=4,width=2,class="checkbox",name="blur",label="Automatically add blur:"},
|
|
{x=2,y=4,width=2,class="floatedit",name="bl",value="0.6"},
|
|
{x=0,y=5,width=2,class="checkbox",name="snap",label="Snapping to keyframes:",value=true},
|
|
{x=0,y=6,width=2,class="label",label="Frames to search back:"},
|
|
{x=0,y=7,width=2,class="label",label="Frames to search forward:"},
|
|
{x=2,y=6,width=2,class="intedit",name="kfs",value="24",step=1,min=1,max=250},
|
|
{x=2,y=7,width=2,class="intedit",name="kfe",value="24",step=1,min=1,max=250},
|
|
{x=0,y=8,width=2,class="checkbox",name="save",label="Save current settings"},
|
|
{x=2,y=8,width=2,class="label",label=" [Time Signs v"..script_version.."]"},
|
|
}
|
|
loadconfig()
|
|
buttons={"No more suffering with SHAFT signs!","Exit"}
|
|
P,res=ADD(GUI,buttons,{ok='No more suffering with SHAFT signs!',cancel='Exit'})
|
|
if P=="Exit" then aegisub.cancel() end
|
|
ms2fr=aegisub.frame_from_ms
|
|
fr2ms=aegisub.ms_from_frame
|
|
keyframes=aegisub.keyframes()
|
|
if res.save then saveconfig() end
|
|
if P=="No more suffering with SHAFT signs!" then sel=signtime(subs,sel) end
|
|
aegisub.set_undo_point(script_name)
|
|
return sel
|
|
end
|
|
|
|
if haveDepCtrl then depRec:registerMacro(timesigns) else aegisub.register_macro(script_name,script_description,timesigns) end |