SHOW:
|
|
- or go back to the newest paste.
1 | ffmpegSource2("C:\Users\Seedmanc\Desktop\guiminer\avisynth\imas_question_pause.mkv") | |
2 | global samples = ImageReader("C:\Users\Seedmanc\Desktop\guiminer\avisynth\subhelp\names.png", end=framecount-1, fps=framerate, pixel_type="y8").converttoyv12.mt_edge | |
3 | #^ Path to the pic with names http://puu.sh/4bqOU.png | |
4 | ||
5 | #Settings: | |
6 | global workdir ="C:\Users\Seedmanc\Desktop\guiminer\avisynth\" | |
7 | # ^ Folder where frames will be written to | |
8 | - | global debug = true # Controls visual indication and writebuffer flushing. Without them script runs at ~600 fps. |
8 | + | |
9 | global stringtemplate = "Dialogue: 0,0:00:00.00,0:00:01.00,Style,Actor,0000,0000,0000,," | |
10 | global shift = 0 # Shift of subtitle line placement in milliseconds, relative to time of detection. Both starting and ending times are affected | |
11 | global mult = 1.0 # Multiplier of subtitle line duration relative to detected on-screen duration. You'll likely want to increase it. | |
12 | global debug = true # Controls visual indication and writebuffer flushing. Without them script runs at ~450 fps. | |
13 | global overwrite = false # Overwrites output file instead of appending to it. Useful while testing. | |
14 | global TBlowthr = 185 # Detection lower threshold, separates textbox from darker background. | |
15 | # Raising will delay detection until textbox fully appears, but might fail to catch textboxes with lots of text. | |
16 | # Lower values might result in false positives on brighter backgrounds | |
17 | global TBhighthr = 225 # Detection higher threshold, separates textbox from brighter flash-screens | |
18 | # Lower values ensure no false positives, but might delay detecting past the appearance of first few words on brighter backgrounds | |
19 | global QBthr = 150 # Detection threshold for questionboxes, lower values - sooner happening and longer lasting detection at the cost of higher false positive chance (it's pretty low though). | |
20 | # Depends on the background, so having an idol in blue clothes on the left and another one in red on the right => more error chances. | |
21 | global minlength = 1000 # Minimum duration of legit detection in milliseconds, used to filter out accidental false positives. | |
22 | #/Settings. | |
23 | ||
24 | function analyze(int cur_frame) | |
25 | { | |
26 | mode = "add" | |
27 | - | \ c.overlay(c.blankclip(width=tbw, height=tbh, color=$00FF00), x=tbx, y=tby, opacity=0.25, mode=mode) |
27 | + | method = "xor" |
28 | namebox = " | |
29 | - | \ " |
29 | + | \ global n = (n>=nmax)?0:n+1 |
30 | \ sample = samples.crop(0, n*nh, 0, nh) | |
31 | \ dif = rt_averageluma(mt_logic(narea, sample, method ).mt_deflate,n=cur_frame) | |
32 | - | \ value = qarea.rt_averageluma(n=cur_frame) |
32 | + | \ global nfound = (dif<10) |
33 | - | \ global analyzed = (value>qbthr) |
33 | + | \ " |
34 | - | \ global yellow = (analyzed)? |
34 | + | |
35 | - | \ (yarea.RT_AverageLuma(n=cur_frame)>qbthr) |
35 | + | |
36 | - | \ :(yellow) |
36 | + | |
37 | - | \ mark = c.blankclip(width=qw, height=qh, color=$00FF00) |
37 | + | \ (analyzed && !nfound)? |
38 | - | \ (analyzed && debug)? |
38 | + | \ eval(namebox) |
39 | - | \ c.overlay(mark, x=qxb, y=qyb, opacity=0.33, mode=mode). |
39 | + | \ :(nop) |
40 | - | \ overlay(mark, x=qxr, y=qyr, opacity=0.33, mode=mode). |
40 | + | |
41 | - | \ overlay((yellow)?mark:c.crop(qxy, qyy, 4, 2), x=qxy, y=qyy, opacity=(yellow)?0.33:0, mode=mode) |
41 | + | \ c.overlay(c.blankclip(width=tbw, height=tbh, color=$00FF00), x=tbx, y=tby, opacity=0.25, mode=mode). |
42 | - | \ :c |
42 | + | \ overlay((nfound)?c.blankclip(width=nw*2, height=nh, color=$00FF00):c.crop(nx,ny,4,2), x=nx-6, y=ny, opacity=(nfound)?0.25:0, mode=mode) |
43 | - | \ " |
43 | + | \ :c |
44 | \ " | |
45 | - | return eval(rt_txtgetline("eval(textbox)"+chr(10)+"eval(qbox)",n )) |
45 | + | |
46 | qbox = " | |
47 | \ value = qarea.rt_averageluma(n=cur_frame) | |
48 | \ global analyzed = (value>qbthr) | |
49 | \ global yellow = (analyzed)? | |
50 | \ (yarea.RT_AverageLuma(n=cur_frame)>qbthr) | |
51 | \ :(yellow) | |
52 | \ mark = c.blankclip(width=qw, height=qh, color=$00FF00) | |
53 | \ (analyzed && debug)? | |
54 | \ c.overlay(mark, x=qxb, y=qyb, opacity=0.33, mode=mode). | |
55 | - | \ global startframe = cur_frame |
55 | + | \ overlay(mark, x=qxr, y=qyr, opacity=0.33, mode=mode). |
56 | \ overlay((yellow)?mark:c.crop(qxy, qyy, 4, 2), x=qxy, y=qyy, opacity=(yellow)?0.33:0, mode=mode) | |
57 | \ :c | |
58 | \ " | |
59 | ||
60 | return eval(rt_txtgetline("eval(textbox)"+chr(10)+"eval(qbox)",m )) | |
61 | - | \ global endframe = cur_frame |
61 | + | |
62 | ||
63 | function detect(int cur_frame) | |
64 | { | |
65 | (analyzed)? | |
66 | - | \ :eval("global n = (n>=nmax)?0:n+1") |
66 | + | |
67 | \ nop | |
68 | \ :eval(" | |
69 | \ global detected = true | |
70 | \ global startframe = cur_frame | |
71 | \ global qbthr = qbthr-15 | |
72 | \ ") | |
73 | - | (accepted)? |
73 | + | |
74 | - | \ c.writefile(filename, "prepareline(stringtemplate, startframe+shift, startframe+round(delta*mult)+shift)", append=true, flush=debug) |
74 | + | |
75 | - | \ :nop |
75 | + | |
76 | \ global endframe = cur_frame-1 | |
77 | \ global startshow = startframe | |
78 | \ global qbthr = qbthr+15 | |
79 | \ validate() | |
80 | \ ") | |
81 | \ :eval("global m = (m>=mmax)?0:m+1") | |
82 | - | result = (n==1)? |
82 | + | |
83 | ||
84 | function validate() | |
85 | { | |
86 | global delta = endframe-startframe | |
87 | global accepted = (delta>minlength) | |
88 | (accepted)? eval(""" | |
89 | - | \ :result |
89 | + | \ c.writefile(filename, "prepareline(stringtemplate, startframe+shift, startframe+round(delta*mult)+shift)", append=true, flush=debug) |
90 | - | |
90 | + | \ fname=rt_strreplace(frame2time(startframe+shift),":","-") |
91 | \ converttorgb24 | |
92 | \ imagewriter(file=workdir+fname+"%0.0f.jpg",type="jpg", info=debug) | |
93 | \ converttoyv12""") | |
94 | \ :nop | |
95 | ||
96 | } | |
97 | ||
98 | function prepareline(string s, int b, int e) | |
99 | { | |
100 | result = RT_StrReplace(s, "0:00:00.00", frame2time(b)) | |
101 | result = RT_StrReplace(result, "0:00:01.00", frame2time(e)) | |
102 | result = (m==1)? | |
103 | \ (RT_StrReplace(result, "Style", "QB_Blue")+chr(10) | |
104 | \ +(yellow? | |
105 | \ RT_StrReplace(result, "Style", "QB_Yellow")+chr(10) | |
106 | \ :"") | |
107 | \ +RT_StrReplace(result, "Style", "QB_Red") | |
108 | \ ).RT_StrReplace("Actor", "Q-Box") | |
109 | \ :(m==0)? | |
110 | \ (nfound)? | |
111 | \ rt_strreplace(result,"Actor",rt_txtgetline(names,n)) | |
112 | \ :result | |
113 | \ :result | |
114 | global nfound=false | |
115 | global n = 0 | |
116 | #these 2 lines must be inside of detect() after validate() call | |
117 | #but Avisynth is retarded so I have to put them here for script to work | |
118 | return result | |
119 | } | |
120 | ||
121 | function frame2time(int f) | |
122 | { | |
123 | rawtime = f/framerate | |
124 | hours = rawtime/3600.0 | |
125 | - | global n = 0 global nmax = 1 |
125 | + | |
126 | seconds = frac(minutes)*60.0 | |
127 | time = string(floor(hours), "%1.0f")+":"+string(floor(minutes), "%02.0f")+":"+string(seconds, "%05.2f") | |
128 | ||
129 | return time | |
130 | } | |
131 | ||
132 | # Textbox description | |
133 | global tbX = 238 global tbY = 584 | |
134 | global tbW = 840 global tbH = 90 | |
135 | global tarea = crop(tbx, tby, tbw, tbh).coloryuv(autogain=true) | |
136 | # Namebox description | |
137 | global names = \ | |
138 | "Chihaya | |
139 | Hibiki | |
140 | Producer" | |
141 | global nfound = false | |
142 | global n = 0 | |
143 | - | \ rt_subtitle(frame2time(startshow)+" > "+frame2time(endframe)+chr(13)+(accepted?"Accepted":"REJECTED")) |
143 | + | global nmax = RT_TxtQueryLines(names)-1 |
144 | global nx = 244 global ny = 552 | |
145 | global nw = 62 global nh = 32 | |
146 | global narea = crop(nx, ny, nw, nh).mt_edge | |
147 | - | #assumefps(500) # Set Debug to false to get ~500 fps without visual indications (when you finished tuning the script and ready to process your videos). |
147 | + | |
148 | global qw = 308 global qh = 120 | |
149 | global qxb = 200 global qyb = 322 | |
150 | global qxr = 772 global qyr = qyb | |
151 | global qxy = 486 global qyy = 180 | |
152 | bluebox = crop(qxb, qyb, qw, qh) | |
153 | bluemask = bluebox.maskhs(starthue=360-60, endhue=360-20, maxsat=76, minsat=5).converttoyv12.mt_inflate.mt_expand | |
154 | redbox = crop(qxr, qyr, qw, qh) | |
155 | redmask = redbox. maskhs(starthue=80, endhue=120, maxsat=76, minsat=5).converttoyv12.mt_inflate.mt_expand | |
156 | global qarea = mt_logic(bluemask, redmask, mode="min") | |
157 | yellowbox = crop(qxy, qyy, qw, qh) | |
158 | yellowmask = yellowbox.maskhs(starthue=130, endhue=160, maxsat=75, minsat=5).converttoyv12.mt_inflate.mt_expand | |
159 | global yarea = yellowmask | |
160 | global yellow = false | |
161 | ||
162 | # Common variables | |
163 | global m = 0 global mmax = 1 | |
164 | global framerate = last.framerate | |
165 | global shift = round(shift/1000.0*framerate) | |
166 | global minlength = round(minlength/1000.0*framerate) | |
167 | global startframe = 0 | |
168 | global startshow = 0 | |
169 | global endframe = 0 | |
170 | global analyzed = false | |
171 | global detected = false | |
172 | global accepted = true | |
173 | writefilestart(filename, "chr(13)", append=!(overwrite)) | |
174 | global c = last | |
175 | ||
176 | # main() | |
177 | scriptclip(""" | |
178 | analyze(current_frame) | |
179 | detect(current_frame) | |
180 | (debug)? | |
181 | \ rt_subtitle(((nfound)?rt_txtgetline(names,n):"")+chr(13)+ | |
182 | \ frame2time(startshow)+" > "+frame2time(endframe)+chr(13)+ | |
183 | \ (accepted?"Accepted":"REJECTED")) | |
184 | \ :last | |
185 | """) | |
186 | ||
187 | #assumefps(450) # Set Debug to false to get ~450 fps without visual indications (when you finished tuning the script and ready to process your videos). |