basyx commited on
Commit
66b8fff
·
verified ·
1 Parent(s): ca2a8c6

Create caption_director.py

Browse files
Files changed (1) hide show
  1. utils/caption_director.py +231 -0
utils/caption_director.py ADDED
@@ -0,0 +1,231 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ caption_director.py
3
+ ---------------------------------------
4
+ AI Caption Intelligence System
5
+
6
+ Responsibilities:
7
+ - Convert transcript → styled caption segments
8
+ - Decide emphasis words
9
+ - Break text into readable chunks
10
+ - Optimize for TikTok/Reels retention
11
+ - Support hook-style captions
12
+
13
+ INPUT:
14
+ words = [
15
+ {"word": "hello", "start": 0.2, "end": 0.5},
16
+ ...
17
+ ]
18
+
19
+ OUTPUT:
20
+ caption blocks:
21
+ [
22
+ {
23
+ "text": "THIS IS CRAZY",
24
+ "start": 0.2,
25
+ "end": 2.1,
26
+ "style": "hook"
27
+ }
28
+ ]
29
+ """
30
+
31
+ import re
32
+
33
+
34
+ # -----------------------------
35
+ # CONFIG
36
+ # -----------------------------
37
+
38
+ MAX_WORDS_PER_CAPTION = 6
39
+ HOOK_KEYWORDS = [
40
+ "listen", "wait", "you", "this", "crazy",
41
+ "insane", "important", "stop", "secret"
42
+ ]
43
+
44
+
45
+ # -----------------------------
46
+ # UTIL: CLEAN TEXT
47
+ # -----------------------------
48
+
49
+ def clean_word(word):
50
+ return re.sub(r"[^a-zA-Z0-9']", "", word).lower()
51
+
52
+
53
+ # -----------------------------
54
+ # DETECT EMPHASIS
55
+ # -----------------------------
56
+
57
+ def is_emphasis(word):
58
+ w = clean_word(word)
59
+ return w in HOOK_KEYWORDS or len(word) > 8
60
+
61
+
62
+ # -----------------------------
63
+ # GROUP WORDS INTO CAPTIONS
64
+ # -----------------------------
65
+
66
+ def group_words(words):
67
+ captions = []
68
+ buffer = []
69
+
70
+ for w in words:
71
+ buffer.append(w)
72
+
73
+ if len(buffer) >= MAX_WORDS_PER_CAPTION:
74
+ captions.append(buffer)
75
+ buffer = []
76
+
77
+ if buffer:
78
+ captions.append(buffer)
79
+
80
+ return captions
81
+
82
+
83
+ # -----------------------------
84
+ # BUILD CAPTION BLOCK
85
+ # -----------------------------
86
+
87
+ def build_caption_block(group):
88
+ text = []
89
+ start = group[0]["start"]
90
+ end = group[-1]["end"]
91
+
92
+ emphasis_count = 0
93
+
94
+ for w in group:
95
+ word = w["word"]
96
+
97
+ if is_emphasis(word):
98
+ text.append(word.upper())
99
+ emphasis_count += 1
100
+ else:
101
+ text.append(word)
102
+
103
+ caption_text = " ".join(text)
104
+
105
+ style = "hook" if emphasis_count > 0 else "normal"
106
+
107
+ return {
108
+ "text": caption_text,
109
+ "start": start,
110
+ "end": end,
111
+ "style": style
112
+ }
113
+
114
+
115
+ # -----------------------------
116
+ # MAIN DIRECTOR
117
+ # -----------------------------
118
+
119
+ def caption_director(words):
120
+ """
121
+ Main caption intelligence engine
122
+ """
123
+
124
+ if not words:
125
+ return []
126
+
127
+ grouped = group_words(words)
128
+
129
+ captions = []
130
+
131
+ for group in grouped:
132
+ captions.append(build_caption_block(group))
133
+
134
+ return captions
135
+
136
+
137
+ # -----------------------------
138
+ # HOOK CAPTION GENERATOR
139
+ # -----------------------------
140
+
141
+ def generate_hook_caption(words):
142
+ """
143
+ Extracts first high-impact caption
144
+ """
145
+
146
+ for w in words[:20]:
147
+ if is_emphasis(w["word"]):
148
+ return {
149
+ "text": w["word"].upper(),
150
+ "start": w["start"],
151
+ "end": w["end"],
152
+ "style": "hook"
153
+ }
154
+
155
+ return None
156
+
157
+
158
+ # -----------------------------
159
+ # AUTO CAPTION PIPELINE
160
+ # -----------------------------
161
+
162
+ def auto_captions(words):
163
+ """
164
+ Full pipeline:
165
+ - detect hook
166
+ - generate captions
167
+ """
168
+
169
+ captions = caption_director(words)
170
+
171
+ hook = generate_hook_caption(words)
172
+
173
+ if hook:
174
+ captions.insert(0, hook)
175
+
176
+ return captions
177
+
178
+
179
+ # -----------------------------
180
+ # STYLE DECISION ENGINE
181
+ # -----------------------------
182
+
183
+ def decide_style(caption):
184
+ text = caption["text"]
185
+
186
+ if caption["style"] == "hook":
187
+ return "large_bold_center"
188
+
189
+ if len(text) > 40:
190
+ return "small_multi_line"
191
+
192
+ if text.isupper():
193
+ return "emphasis"
194
+
195
+ return "standard"
196
+
197
+
198
+ # -----------------------------
199
+ # EXPORT HELPERS
200
+ # -----------------------------
201
+
202
+ def format_for_render(captions):
203
+ """
204
+ Converts captions into render-friendly format
205
+ """
206
+
207
+ formatted = []
208
+
209
+ for c in captions:
210
+ formatted.append({
211
+ "text": c["text"],
212
+ "start": c["start"],
213
+ "end": c["end"],
214
+ "style": decide_style(c)
215
+ })
216
+
217
+ return formatted
218
+
219
+
220
+ # -----------------------------
221
+ # PUBLIC API
222
+ # -----------------------------
223
+
224
+ def process_captions(words):
225
+ """
226
+ Full external API
227
+ """
228
+
229
+ captions = auto_captions(words)
230
+
231
+ return format_for_render(captions)