Prompt48 commited on
Commit
ec68494
·
verified ·
1 Parent(s): 56a6328

Upload edit\gen_full.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. edit//gen_full.py +222 -0
edit//gen_full.py ADDED
@@ -0,0 +1,222 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Generate hf/index.html for the FULL LM Studio MTP video (all chapters)."""
2
+ import json, sys
3
+ from pathlib import Path
4
+ sys.path.insert(0, r"C:\Users\palas\.claude\skills\screencast-hype\scripts")
5
+ from captions_html import build_captions
6
+ import cutmap
7
+ M = cutmap.map_time
8
+ DUR = round(cutmap.out_duration() + 0.3, 2)
9
+
10
+ ROOT = Path(r"D:\PromptEngineer48\In-Progress\P11-Editor\edit")
11
+ words = json.load(open(ROOT/"transcripts/LMSTUDIO-MTP1.json", encoding="utf-8"))["words"]
12
+
13
+ body = [] # HTML element strings
14
+ tw = [] # GSAP tween JS lines
15
+ center = [] # ids needing xPercent/yPercent centering
16
+ sfx = [] # (file, src_time, vol)
17
+ track = [2] # mutable track index counter for sfx
18
+
19
+ def add_sfx(f, t, v=0.8):
20
+ sfx.append((f, M(t), v, track[0])); track[0]+=1
21
+
22
+ # ---------- captions ----------
23
+ cap_divs, cap_tw = build_captions(words, 0, cutmap.SRC_DURATION, per=2, map_time=M)
24
+ body.append(cap_divs)
25
+ tw.append(cap_tw)
26
+
27
+ # ---------- helper builders ----------
28
+ def title_card(cid, kicker, title, subtitle, accent, tin, tout):
29
+ center.append(cid)
30
+ body.append(f'''<div class="title-card glass" id="{cid}">
31
+ {'<div class="kicker">'+kicker+'</div>' if kicker else ''}
32
+ <div class="bigt">{title}</div>
33
+ <div class="uline" id="{cid}_u" style="background:{accent};box-shadow:0 0 22px {accent}"></div>
34
+ <div class="subt" id="{cid}_s" style="color:{accent}">{subtitle}</div>
35
+ </div>''')
36
+ tw.append(f'tl.set("#{cid}",{{xPercent:-50,yPercent:-50}},0);')
37
+ tw.append(f'tl.fromTo("#{cid}",{{opacity:0,scale:0.88,filter:"blur(14px)"}},{{opacity:1,scale:1,filter:"blur(0px)",duration:0.55,ease:"power3.out"}},{M(tin):.2f});')
38
+ tw.append(f'tl.to("#{cid}_u",{{width:480,duration:0.5,ease:"power2.out"}},{M(tin)+0.35:.2f});')
39
+ tw.append(f'tl.fromTo("#{cid}_s",{{opacity:0,y:16}},{{opacity:1,y:0,duration:0.4,ease:"power2.out"}},{M(tin)+0.6:.2f});')
40
+ tw.append(f'tl.to("#{cid}",{{opacity:0,scale:0.96,y:-20,duration:0.4,ease:"power2.in"}},{M(tout):.2f});')
41
+
42
+ def chip(cid, text, accent, tin, tout):
43
+ body.append(f'<div class="chip glass" id="{cid}" style="border-color:{accent}66"><span style="color:{accent}">●</span>&nbsp;{text}</div>')
44
+ center.append(cid)
45
+ tw.append(f'tl.set("#{cid}",{{xPercent:-50}},0);')
46
+ tw.append(f'tl.fromTo("#{cid}",{{opacity:0,y:-26,scale:0.9}},{{opacity:1,y:0,scale:1,duration:0.45,ease:"back.out(2)"}},{M(tin):.2f});')
47
+ tw.append(f'tl.to("#{cid}",{{opacity:0,y:-18,duration:0.35,ease:"power2.in"}},{M(tout):.2f});')
48
+
49
+ def corner_badge(cid, text, color, tin, tout):
50
+ body.append(f'<div class="cbadge" id="{cid}" style="border-color:{color};color:{color}"><b style="color:{color}">{text}</b></div>')
51
+ tw.append(f'tl.fromTo("#{cid}",{{opacity:0,x:40}},{{opacity:1,x:0,duration:0.4,ease:"power3.out"}},{M(tin):.2f});')
52
+ tw.append(f'tl.to("#{cid}",{{opacity:0,x:40,duration:0.3,ease:"power2.in"}},{M(tout):.2f});')
53
+
54
+ def stat_pop(cid, big, small, accent, tin, tout):
55
+ center.append(cid)
56
+ body.append(f'''<div class="statpop glass" id="{cid}">
57
+ <span class="sp_big" style="color:{accent}">{big}</span>
58
+ <span class="sp_small">{small}</span></div>''')
59
+ tw.append(f'tl.set("#{cid}",{{xPercent:-50,yPercent:-50}},0);')
60
+ tw.append(f'tl.fromTo("#{cid}",{{opacity:0,scale:0.6}},{{opacity:1,scale:1,duration:0.45,ease:"back.out(2.4)"}},{M(tin):.2f});')
61
+ tw.append(f'tl.to("#{cid}",{{opacity:0,scale:0.9,duration:0.35,ease:"power2.in"}},{M(tout):.2f});')
62
+
63
+ def sponsor(cid, name, tag, accent, tin, tout):
64
+ center.append(cid)
65
+ body.append(f'''<div class="sponsor glass" id="{cid}">
66
+ <div class="sp_name" style="color:{accent}">{name}</div>
67
+ <div class="sp_tag">{tag}</div></div>''')
68
+ tw.append(f'tl.set("#{cid}",{{xPercent:-50,yPercent:-50}},0);')
69
+ tw.append(f'tl.fromTo("#{cid}",{{opacity:0,y:40,scale:0.92}},{{opacity:1,y:0,scale:1,duration:0.5,ease:"back.out(1.6)"}},{M(tin):.2f});')
70
+ tw.append(f'tl.to("#{cid}",{{opacity:0,y:-26,duration:0.4,ease:"power2.in"}},{M(tout):.2f});')
71
+
72
+ # ---------- COLD OPEN counter ----------
73
+ def counter(cid, label, tin, tbefore, tafter, tbadge, tout):
74
+ center.append(cid)
75
+ body.append(f'''<div class="hook-card glass" id="{cid}">
76
+ <div class="hook-label">{label}</div>
77
+ <div class="row" id="{cid}_no"><span class="tag" style="color:#F87171">WITHOUT MTP</span><span><span class="num" style="color:#F87171">62</span><span class="unit">tok/s</span></span></div>
78
+ <div class="row" id="{cid}_yes"><span class="tag" style="color:#A3E635">WITH MTP</span><span><span class="num" style="color:#A3E635">78</span><span class="unit">tok/s</span></span></div>
79
+ <div class="badge" id="{cid}_b">+25% FASTER</div></div>''')
80
+ tw.append(f'tl.set("#{cid}",{{xPercent:-50,yPercent:-50}},0);')
81
+ tw.append(f'tl.fromTo("#{cid}",{{opacity:0,scale:0.9,y:30}},{{opacity:1,scale:1,y:0,duration:0.5,ease:"back.out(1.6)"}},{M(tin):.2f});')
82
+ tw.append(f'tl.fromTo("#{cid}_no",{{opacity:0,x:-40}},{{opacity:1,x:0,duration:0.4,ease:"power3.out"}},{M(tbefore):.2f});')
83
+ tw.append(f'tl.fromTo("#{cid}_yes",{{opacity:0,x:-40}},{{opacity:1,x:0,duration:0.4,ease:"power3.out"}},{M(tafter):.2f});')
84
+ tw.append(f'tl.fromTo("#{cid}_b",{{opacity:0,scale:0.4,rotation:-30}},{{opacity:1,scale:1,rotation:-6,duration:0.5,ease:"back.out(3)"}},{M(tbadge):.2f});')
85
+ tw.append(f'tl.to("#{cid}",{{opacity:0,scale:0.96,y:-24,duration:0.4,ease:"power2.in"}},{M(tout):.2f});')
86
+
87
+ # === COLD OPEN ===
88
+ counter("hook","TOKENS / SECOND",6.5,7.94,12.98,14.45,19.2)
89
+ add_sfx("riser.mp3",6.0,0.6); add_sfx("pop.mp3",7.94); add_sfx("impact.mp3",12.98,0.85); add_sfx("ding.mp3",14.45,0.7)
90
+
91
+ # === CH1 What is MTP ===
92
+ title_card("c_mtp","","WHAT IS MTP?","MULTI-TOKEN PREDICTION","#22D3EE",24.2,28.8); add_sfx("whoosh.mp3",24.2)
93
+
94
+ # === CH2 The Slow Way (lower-third style as title) ===
95
+ title_card("c_slow","THE SLOW WAY","STANDARD AUTOREGRESSION","3 PASSES · FULL 27B COST EACH","#F87171",79.8,85.5); add_sfx("whoosh.mp3",79.8)
96
+
97
+ # === CH3 The Fast Way ===
98
+ title_card("c_fast","THE FAST WAY","MTP: DRAFT + VERIFY","ONE PASS · MULTIPLE TOKENS","#A3E635",102.5,108.5); add_sfx("whoosh.mp3",102.5)
99
+
100
+ # === CH4 The Numbers (stat card with 3 rows) ===
101
+ center.append("c_num")
102
+ body.append('''<div class="title-card glass" id="c_num" style="gap:14px">
103
+ <div class="kicker">THE NUMBERS</div>
104
+ <div class="numrow" id="c_num_1"><b style="color:#A3E635">~2&times; FASTER</b><span>2.5 tokens / verified pass</span></div>
105
+ <div class="numrow" id="c_num_2"><b style="color:#22D3EE">75&ndash;80% ACCEPTED</b><span>on Qwen3</span></div>
106
+ <div class="numrow" id="c_num_3"><b style="color:#FFFFFF">+1 GB VRAM</b><span>the only cost</span></div>
107
+ </div>''')
108
+ tw.append('tl.set("#c_num",{xPercent:-50,yPercent:-50},0);')
109
+ tw.append(f'tl.fromTo("#c_num",{{opacity:0,scale:0.9}},{{opacity:1,scale:1,duration:0.5,ease:"power3.out"}},{M(148.5):.2f});')
110
+ tw.append(f'tl.fromTo("#c_num_1",{{opacity:0,x:-30}},{{opacity:1,x:0,duration:0.4,ease:"power3.out"}},{M(150.18):.2f});')
111
+ tw.append(f'tl.fromTo("#c_num_2",{{opacity:0,x:-30}},{{opacity:1,x:0,duration:0.4,ease:"power3.out"}},{M(155.0):.2f});')
112
+ tw.append(f'tl.fromTo("#c_num_3",{{opacity:0,x:-30}},{{opacity:1,x:0,duration:0.4,ease:"power3.out"}},{M(160.1):.2f});')
113
+ tw.append(f'tl.to("#c_num",{{opacity:0,scale:0.96,y:-20,duration:0.4,ease:"power2.in"}},{M(167):.2f});')
114
+ add_sfx("whoosh.mp3",148.5); add_sfx("ding.mp3",150.18,0.6); add_sfx("ding.mp3",155.0,0.6); add_sfx("ding.mp3",160.1,0.6)
115
+
116
+ # === CH5 Install + beta chip ===
117
+ title_card("c_install","STEP 1","INSTALL LM STUDIO","DOWNLOAD FOR WINDOWS","#22D3EE",177.22,181.8); add_sfx("whoosh.mp3",177.22)
118
+ chip("ch_beta","GET THE BETA &rarr; v0.4.14","#22D3EE",205.54,213); add_sfx("pop.mp3",205.54)
119
+
120
+ # === CH6 Pick a model ===
121
+ title_card("c_model","STEP 2","PICK AN MTP MODEL","SEARCH: MTP","#22D3EE",223.3,227.8); add_sfx("whoosh.mp3",223.3)
122
+ add_sfx("keyboard.mp3",225.78,0.5)
123
+ chip("ch_gpu","8 GB GPU &rarr; 4B MTP MODEL","#A3E635",246,252.5); add_sfx("pop.mp3",246)
124
+
125
+ # === CH7 Test 1 MTP OFF ===
126
+ corner_badge("b_off","&#10007; MTP OFF","#F87171",255,279.4)
127
+ add_sfx("keyboard.mp3",264.98,0.5)
128
+ stat_pop("p_18","&asymp;18","tok/s &middot; MTP OFF","#F87171",276,279.4); add_sfx("impact.mp3",276,0.85)
129
+
130
+ # === CH8 Test 2 MTP ON ===
131
+ corner_badge("b_on","&#10003; MTP ON &middot; DRAFTS 3","#A3E635",279.6,332)
132
+ stat_pop("p_20","&asymp;20","tok/s &middot; +11%","#A3E635",317.8,326); add_sfx("impact.mp3",317.8,0.85); add_sfx("ding.mp3",318.2,0.6)
133
+
134
+ # === CH9 Real benchmark ===
135
+ counter("c_real","THE REAL TEST &middot; 500-WORD ESSAY",336,338.8,345.16,352.52,354.2)
136
+ add_sfx("whoosh.mp3",336); add_sfx("pop.mp3",338.8); add_sfx("impact.mp3",345.16,0.9); add_sfx("ding.mp3",352.52,0.7)
137
+
138
+ # === CH10 Outro ===
139
+ sponsor("sp_run","RunPod","GPUs I USE &middot; LINK IN DESCRIPTION","#22D3EE",369,377); add_sfx("whoosh.mp3",369)
140
+ sponsor("sp_host","Hostinger","HOSTING &amp; VPS &middot; LINK IN DESCRIPTION","#A3E635",377.5,385.5); add_sfx("whoosh.mp3",377.5)
141
+ center.append("subbtn")
142
+ body.append('<div class="subbtn" id="subbtn">▶ SUBSCRIBE</div>')
143
+ tw.append('tl.set("#subbtn",{xPercent:-50,yPercent:-50},0);')
144
+ tw.append(f'tl.fromTo("#subbtn",{{opacity:0,scale:0.5}},{{opacity:1,scale:1,duration:0.5,ease:"back.out(2.4)"}},{M(387):.2f});')
145
+ tw.append(f'tl.to("#subbtn",{{scale:1.08,duration:0.4,yoyo:true,repeat:3,ease:"sine.inOut"}},{M(388):.2f});')
146
+ add_sfx("ding.mp3",387,0.8)
147
+
148
+ # === intro whoosh ===
149
+ add_sfx("whoosh.mp3",0.1,0.5)
150
+
151
+ # ---------- ZOOM keyframes (src time, scale, dur, ease) ----------
152
+ # Baseline stays >=1.12 through browser sections (diagram + outro web) to crop the
153
+ # address bar / tab bar / taskbar. Punches to ~1.4 on the result readouts.
154
+ zk = [(6.2,1.28,2.0,"power2.inOut"),(19.4,1.13,1.6,"power2.inOut"),
155
+ (60,1.15,6,"sine.inOut"),(95,1.12,6,"sine.inOut"),(150,1.13,4,"sine.inOut"),
156
+ (177,1.12,1.5,"power2.inOut"),(255,1.11,1.5,"sine.inOut"),
157
+ (275.4,1.40,1.2,"power2.inOut"),(279.6,1.12,1.0,"power2.inOut"),
158
+ (287,1.18,1.5,"sine.inOut"),(317.2,1.40,1.0,"power2.inOut"),
159
+ (326,1.12,1.2,"power2.inOut"),(336,1.14,1.0,"power2.inOut"),(356,1.12,1.5,"power2.inOut")]
160
+ zoom_tw = ['tl.set(".zoom-wrap",{scale:1.0,transformOrigin:"50% 50%"},0);']
161
+ for t,s,d,e in zk:
162
+ zoom_tw.append(f'tl.to(".zoom-wrap",{{scale:{s},duration:{d},ease:"{e}"}},{M(t):.2f});')
163
+
164
+ # ---------- SFX elements ----------
165
+ sfx_els = "\n".join(
166
+ f' <audio id="sfx{ti}" src="../assets/sfx/{f}" data-start="{t:.2f}" data-track-index="{ti}" data-volume="{v}"></audio>'
167
+ for (f,t,v,ti) in sfx)
168
+
169
+ set_center = "\n ".join(tw[i] for i in range(0)) # centering already inline per element
170
+
171
+ HTML = f"""<!doctype html><html lang="en"><head><meta charset="utf-8"/>
172
+ <style>
173
+ *{{margin:0;padding:0;box-sizing:border-box;}}
174
+ #root{{position:relative;width:1920px;height:1080px;overflow:hidden;background:#0B0F14;font-family:"Inter",sans-serif;}}
175
+ .zoom-wrap{{position:absolute;inset:0;z-index:0;transform-origin:50% 45%;}}
176
+ .zoom-wrap video{{width:1920px;height:1080px;object-fit:cover;display:block;}}
177
+ .cap{{position:absolute;left:50%;bottom:90px;z-index:40;opacity:0;font-weight:900;font-size:56px;letter-spacing:1px;color:#fff;white-space:nowrap;text-shadow:0 4px 18px rgba(0,0,0,.85),0 2px 4px rgba(0,0,0,.9);}}
178
+ .glass{{background:rgba(255,255,255,0.07);backdrop-filter:blur(22px) saturate(130%);-webkit-backdrop-filter:blur(22px) saturate(130%);border:1px solid rgba(255,255,255,0.18);border-radius:26px;box-shadow:0 24px 60px rgba(0,0,0,.45);}}
179
+ .title-card{{position:absolute;left:50%;top:50%;z-index:25;opacity:0;padding:54px 80px;text-align:center;display:flex;flex-direction:column;align-items:center;gap:16px;}}
180
+ .kicker{{font-weight:700;font-size:30px;letter-spacing:8px;color:#9AA7B4;}}
181
+ .bigt{{font-weight:800;font-size:104px;color:#fff;letter-spacing:1px;line-height:1;}}
182
+ .uline{{height:8px;width:0;border-radius:6px;}}
183
+ .subt{{font-weight:700;font-size:40px;letter-spacing:3px;opacity:0;}}
184
+ .numrow{{display:flex;align-items:baseline;gap:22px;opacity:0;}}
185
+ .numrow b{{font-weight:800;font-size:56px;}}
186
+ .numrow span{{font-weight:600;font-size:30px;color:#9AA7B4;}}
187
+ .chip{{position:absolute;left:50%;top:70px;z-index:30;opacity:0;padding:18px 34px;font-weight:800;font-size:38px;color:#fff;white-space:nowrap;}}
188
+ .cbadge{{position:absolute;right:84px;top:48px;z-index:30;opacity:0;padding:13px 24px;border:2px solid;border-radius:16px;font-weight:800;font-size:32px;background:rgba(11,15,20,0.62);backdrop-filter:blur(10px);}}
189
+ .statpop{{position:absolute;left:50%;top:50%;z-index:28;opacity:0;padding:40px 64px;display:flex;flex-direction:column;align-items:center;gap:6px;}}
190
+ .sp_big{{font-weight:800;font-size:150px;line-height:.9;font-variant-numeric:tabular-nums;}}
191
+ .sp_small{{font-weight:700;font-size:34px;color:#9AA7B4;letter-spacing:2px;}}
192
+ .sponsor{{position:absolute;left:50%;top:50%;z-index:26;opacity:0;padding:48px 72px;text-align:center;display:flex;flex-direction:column;gap:12px;}}
193
+ .sp_name{{font-weight:800;font-size:88px;letter-spacing:1px;}}
194
+ .sp_tag{{font-weight:700;font-size:32px;color:#9AA7B4;letter-spacing:2px;}}
195
+ .subbtn{{position:absolute;left:50%;top:50%;z-index:30;opacity:0;padding:30px 60px;background:#F23A3A;color:#fff;font-weight:800;font-size:64px;border-radius:22px;box-shadow:0 16px 50px rgba(242,58,58,.5);letter-spacing:1px;}}
196
+ .hook-card{{position:absolute;left:50%;top:50%;z-index:20;opacity:0;width:760px;padding:46px 56px;display:flex;flex-direction:column;gap:20px;}}
197
+ .hook-label{{font-weight:700;font-size:24px;letter-spacing:5px;color:#9AA7B4;text-transform:uppercase;}}
198
+ .row{{display:flex;align-items:baseline;justify-content:space-between;opacity:0;}}
199
+ .row .tag{{font-weight:700;font-size:32px;letter-spacing:2px;}}
200
+ .row .num{{font-weight:800;font-size:108px;line-height:.9;font-variant-numeric:tabular-nums;}}
201
+ .row .unit{{font-weight:700;font-size:28px;color:#9AA7B4;margin-left:10px;}}
202
+ .badge{{position:absolute;right:-30px;top:-30px;opacity:0;font-weight:800;font-size:32px;color:#0B0F14;background:#A3E635;padding:14px 24px;border-radius:18px;box-shadow:0 12px 30px rgba(163,230,53,.45);}}
203
+ #c_real{{background:rgba(11,15,20,0.66);border-color:rgba(255,255,255,0.22);}}
204
+ #c_real .hook-label{{color:#C7D2DD;}}
205
+ </style></head><body>
206
+ <div id="root" data-composition-id="root" data-width="1920" data-height="1080" data-start="0" data-duration="{DUR}">
207
+ <div class="zoom-wrap"><video id="bg" src="base_full.mp4" data-start="0" data-duration="{DUR}" data-track-index="0" muted playsinline></video></div>
208
+ <audio id="voice" src="base_full.mp4" data-start="0" data-duration="{DUR}" data-track-index="1" data-volume="1"></audio>
209
+ {sfx_els}
210
+ {chr(10).join(body)}
211
+ <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
212
+ <script>
213
+ window.__timelines = window.__timelines || {{}};
214
+ const tl = gsap.timeline({{ paused: true }});
215
+ {chr(10)+' '.join(zoom_tw)}
216
+ {chr(10)+' '.join(tw)}
217
+ window.__timelines["root"] = tl;
218
+ </script>
219
+ </div></body></html>"""
220
+
221
+ (ROOT/"hf"/"index.html").write_text(HTML, encoding="utf-8")
222
+ print(f"wrote full index.html duration={DUR}s sfx={len(sfx)} elements~{len(body)}")