GLAkavya commited on
Commit
eba6779
Β·
verified Β·
1 Parent(s): f97d5c9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +30 -16
app.py CHANGED
@@ -167,40 +167,54 @@ def ken_burns(pil, duration_sec=6, fps=30, style="premium"):
167
  # CAPTIONS β€” burn into existing video via ffmpeg
168
  # ══════════════════════════════════════════════════════════════════
169
  def add_captions_ffmpeg(video_path, caption, duration_sec, style):
170
- """Burn animated captions using ffmpeg drawtext."""
 
 
 
171
  words=caption.strip().split()
172
  mid=max(1,len(words)//2)
173
- line1=" ".join(words[:mid])
174
- line2=" ".join(words[mid:]) if len(words)>1 else line1
175
 
176
  colors={"premium":"FFD232","energetic":"3CC8FF","fun":"FF78C8"}
177
  col=colors.get(style,"FFFFFF")
178
-
179
- # ffmpeg drawtext with fade-in animation
180
- # line1: shows 1.0s β†’ 3.5s, line2: 3.8s β†’ 6.5s
181
  out=video_path.replace(".mp4","_cap.mp4")
 
182
  font_paths=[
183
  "/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf",
184
  "/usr/share/fonts/truetype/liberation/LiberationSans-Bold.ttf",
185
  "/usr/share/fonts/truetype/freefont/FreeSansBold.ttf",
186
  ]
187
- font=""
188
  for p in font_paths:
189
- if os.path.exists(p): font=f":fontfile='{p}'"; break
190
 
191
- def drawtext(text, start, end):
192
- fade_dur=0.4
 
193
  return (
194
  f"drawtext=text='{text}'{font}"
195
- f":fontsize=44:fontcolor=#{col}"
196
- f":x=(w-text_w)/2:y=h-130"
197
- f":box=1:boxcolor=black@0.55:boxborderw=14"
198
  f":enable='between(t,{start},{end})'"
199
- f":alpha='if(lt(t,{start+fade_dur}),(t-{start})/{fade_dur},"
200
- f"if(gt(t,{end-fade_dur}),({end}-t)/{fade_dur},1))'"
201
  )
202
 
203
- vf=f"{drawtext(line1,1.0,3.5)},{drawtext(line2,3.8,min(6.5,duration_sec-0.3))}"
 
 
 
 
 
 
 
 
 
 
 
 
 
204
 
205
  ret=os.system(f'ffmpeg -y -i "{video_path}" -vf "{vf}" -c:a copy "{out}" -loglevel error')
206
  return out if (ret==0 and os.path.exists(out)) else video_path
 
167
  # CAPTIONS β€” burn into existing video via ffmpeg
168
  # ══════════════════════════════════════════════════════════════════
169
  def add_captions_ffmpeg(video_path, caption, duration_sec, style):
170
+ """Burn animated captions + hashtag tag + shop-now CTA using ffmpeg drawtext."""
171
+ import re
172
+ def clean(t): return re.sub(r"[^A-Za-z0-9 !.,-]","",t).strip()
173
+
174
  words=caption.strip().split()
175
  mid=max(1,len(words)//2)
176
+ line1=clean(" ".join(words[:mid]))
177
+ line2=clean(" ".join(words[mid:])) if len(words)>1 else line1
178
 
179
  colors={"premium":"FFD232","energetic":"3CC8FF","fun":"FF78C8"}
180
  col=colors.get(style,"FFFFFF")
 
 
 
181
  out=video_path.replace(".mp4","_cap.mp4")
182
+
183
  font_paths=[
184
  "/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf",
185
  "/usr/share/fonts/truetype/liberation/LiberationSans-Bold.ttf",
186
  "/usr/share/fonts/truetype/freefont/FreeSansBold.ttf",
187
  ]
188
+ font=""; font_reg=""
189
  for p in font_paths:
190
+ if os.path.exists(p): font=f":fontfile='{p}'"; font_reg=font; break
191
 
192
+ def dt(text, start, end, y, size=42, color=None, box_alpha="0.60"):
193
+ c = color or col
194
+ fd=0.4
195
  return (
196
  f"drawtext=text='{text}'{font}"
197
+ f":fontsize={size}:fontcolor=#{c}"
198
+ f":x=(w-text_w)/2:y={y}"
199
+ f":box=1:boxcolor=black@{box_alpha}:boxborderw=14"
200
  f":enable='between(t,{start},{end})'"
201
+ f":alpha='if(lt(t,{start+fd}),(t-{start})/{fd},if(gt(t,{end-fd}),({end}-t)/{fd},1))'"
 
202
  )
203
 
204
+ end2 = min(duration_sec-0.2, 6.5)
205
+
206
+ # 1. Main captions β€” inside frame, above bars
207
+ cap1 = dt(line1, 1.0, 3.5, "h-190")
208
+ cap2 = dt(line2, 3.8, end2, "h-190")
209
+
210
+ # 2. "Shop Now" CTA β€” appears at 4.5s, small, bottom center
211
+ cta_colors={"premium":"FF9900","energetic":"FF4444","fun":"AA44FF"}
212
+ cta = dt("Shop Now >", 4.5, end2, "h-130", size=32, color=cta_colors.get(style,"FF9900"), box_alpha="0.70")
213
+
214
+ # 3. Hashtag top-left β€” appears early
215
+ tag = dt("#NewCollection", 0.5, 3.0, "60", size=28, color="FFFFFF", box_alpha="0.40")
216
+
217
+ vf = ",".join([cap1, cap2, cta, tag])
218
 
219
  ret=os.system(f'ffmpeg -y -i "{video_path}" -vf "{vf}" -c:a copy "{out}" -loglevel error')
220
  return out if (ret==0 and os.path.exists(out)) else video_path