yukee1992 commited on
Commit
bb8cdaf
Β·
verified Β·
1 Parent(s): 194db07

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +47 -37
app.py CHANGED
@@ -189,22 +189,26 @@ def upload_to_dataset(file_path, project_id, filename, subfolder="videos"):
189
  return None
190
 
191
  def get_font_path(font_family):
192
- """Get font path from font family name - FIXED for subfolders"""
193
  font_family_lower = font_family.lower().replace(' ', '_')
194
  print(f"πŸ” Looking for font: {font_family}")
195
  print(f"πŸ“‹ Available fonts: {list(FONTS.keys())}")
196
 
197
- # Try exact match
198
  if font_family_lower in FONTS:
199
  path = FONTS[font_family_lower]["path"]
200
  print(f"βœ… Found exact match: {path}")
201
- # Verify file exists
202
  if os.path.exists(path):
203
  return path
204
- else:
205
- print(f"⚠️ File exists in FONTS but not on disk: {path}")
206
 
207
- # If not found, try to find by scanning directories
 
 
 
 
 
 
 
208
  print("πŸ” Scanning directories for font files...")
209
  for root, dirs, files in os.walk(FONTS_DIR):
210
  for file in files:
@@ -215,13 +219,37 @@ def get_font_path(font_family):
215
 
216
  print(f"❌ Font not found: {font_family}")
217
  return None
218
-
219
  # =============================================
220
  # ASS SUBTITLE METHOD - WORKS FOR CHINESE
221
  # =============================================
222
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
223
  def create_text_overlay(input_video, output_video, text_style):
224
- """Add text overlay using ASS subtitles - FIXED with full font path"""
225
  font_path = get_font_path(text_style.font_family)
226
  if not font_path:
227
  print(f"⚠️ Font not found: {text_style.font_family}")
@@ -229,11 +257,15 @@ def create_text_overlay(input_video, output_video, text_style):
229
 
230
  print(f"βœ… Using font: {font_path}")
231
 
 
 
 
 
232
  # Create working directory for ASS file
233
  work_dir = os.path.dirname(output_video)
234
  ass_file = os.path.join(work_dir, "subtitle.ass")
235
 
236
- # Color mapping
237
  color_map = {
238
  "white": "FFFFFF", "black": "000000", "red": "FF0000",
239
  "green": "00FF00", "blue": "0000FF", "yellow": "FFFF00",
@@ -263,27 +295,12 @@ def create_text_overlay(input_video, output_video, text_style):
263
  margin_r = text_style.margin if alignment in [3,6,9] else 0
264
  margin_v = text_style.margin
265
 
266
- # IMPORTANT: For ASS, we need to use the actual font filename
267
- # But FFmpeg needs the font to be accessible via fontconfig
268
- # Let's create a fontconfig configuration file
269
-
270
  font_dir = os.path.dirname(font_path)
271
- font_file = os.path.basename(font_path)
272
- font_name = os.path.splitext(font_file)[0]
273
-
274
- # Create a fontconfig configuration file
275
  fc_config = f"""<?xml version="1.0"?>
276
  <!DOCTYPE fontconfig SYSTEM "fonts.dtd">
277
  <fontconfig>
278
  <dir>{font_dir}</dir>
279
- <match target="pattern">
280
- <test qual="any" name="family">
281
- <string>{font_name}</string>
282
- </test>
283
- <edit name="family" mode="assign" binding="same">
284
- <string>{font_name}</string>
285
- </edit>
286
- </match>
287
  </fontconfig>"""
288
 
289
  fc_file = os.path.join(work_dir, "fonts.conf")
@@ -293,7 +310,7 @@ def create_text_overlay(input_video, output_video, text_style):
293
  # Set environment variable for fontconfig
294
  os.environ['FONTCONFIG_FILE'] = fc_file
295
 
296
- # Create ASS file content
297
  ass_content = f"""[Script Info]
298
  ; Script generated by Video Styling Space
299
  ScriptType: v4.00+
@@ -303,7 +320,7 @@ ScaledBorderAndShadow: yes
303
 
304
  [V4+ Styles]
305
  Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
306
- Style: Default,{font_name},{text_style.font_size},&H00{font_color_hex},&H000000FF,&H00000000,&H{bg_alpha:02X}{bg_color_hex},0,0,0,0,100,100,0,0,1,1,0,{alignment},{margin_l},{margin_r},{margin_v},1
307
 
308
  [Events]
309
  Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
@@ -313,14 +330,9 @@ Dialogue: 0,0:00:00.00,0:00:10.00,Default,,0,0,0,,{text_style.text}"""
313
  with open(ass_file, 'w', encoding='utf-8') as f:
314
  f.write(ass_content)
315
 
316
- print(f"πŸ“ Created ASS subtitle file")
317
- print(f"πŸ“ Fontconfig file created at: {fc_file}")
318
-
319
- # First, test if the font is recognized by fontconfig
320
- fc_list = subprocess.run(['fc-list', ':' + font_name], capture_output=True, text=True)
321
- print(f"πŸ“‹ Fontconfig lookup: {fc_list.stdout}")
322
 
323
- # Use FFmpeg with the ASS file
324
  cmd = [
325
  'ffmpeg', '-y',
326
  '-i', input_video,
@@ -335,10 +347,8 @@ Dialogue: 0,0:00:00.00,0:00:10.00,Default,,0,0,0,,{text_style.text}"""
335
  if result.returncode != 0:
336
  print(f"❌ FFmpeg error: {result.stderr}")
337
 
338
- # Try alternative: use drawtext with direct font path
339
  print("πŸ”„ Trying alternative drawtext method...")
340
-
341
- # Position mapping for drawtext
342
  drawtext_pos = {
343
  "bottom-left": "x=20:y=h-th-20",
344
  "bottom-center": "x=(w-tw)/2:y=h-th-20",
 
189
  return None
190
 
191
  def get_font_path(font_family):
192
+ """Get font path from font family name - IMPROVED"""
193
  font_family_lower = font_family.lower().replace(' ', '_')
194
  print(f"πŸ” Looking for font: {font_family}")
195
  print(f"πŸ“‹ Available fonts: {list(FONTS.keys())}")
196
 
197
+ # Try exact match with our font keys
198
  if font_family_lower in FONTS:
199
  path = FONTS[font_family_lower]["path"]
200
  print(f"βœ… Found exact match: {path}")
 
201
  if os.path.exists(path):
202
  return path
 
 
203
 
204
+ # Try partial matches with font keys
205
+ for key, font_info in FONTS.items():
206
+ if font_family_lower in key or font_family_lower in font_info["name"].lower():
207
+ path = font_info["path"]
208
+ print(f"βœ… Found partial match: {key} -> {path}")
209
+ return path
210
+
211
+ # Scan directories for font files
212
  print("πŸ” Scanning directories for font files...")
213
  for root, dirs, files in os.walk(FONTS_DIR):
214
  for file in files:
 
219
 
220
  print(f"❌ Font not found: {font_family}")
221
  return None
222
+
223
  # =============================================
224
  # ASS SUBTITLE METHOD - WORKS FOR CHINESE
225
  # =============================================
226
 
227
+ def get_font_family_name(font_path):
228
+ """Extract font family name from font file using fontTools"""
229
+ try:
230
+ from fontTools import ttLib
231
+ font = ttLib.TTFont(font_path)
232
+
233
+ # Look for family name (nameID 1)
234
+ for record in font['name'].names:
235
+ if record.nameID == 1: # Font Family name
236
+ try:
237
+ if record.platformID == 3 and record.platEncID == 1: # Windows Unicode
238
+ return record.string.decode('utf-16-be')
239
+ else:
240
+ return record.string.decode('utf-8', errors='ignore')
241
+ except:
242
+ continue
243
+
244
+ # Fallback: use filename without extension
245
+ return os.path.splitext(os.path.basename(font_path))[0]
246
+ except Exception as e:
247
+ print(f"⚠️ Could not extract font family name: {e}")
248
+ # Fallback to filename
249
+ return os.path.splitext(os.path.basename(font_path))[0]
250
+
251
  def create_text_overlay(input_video, output_video, text_style):
252
+ """Add text overlay using ASS subtitles - FIXED with proper font family name"""
253
  font_path = get_font_path(text_style.font_family)
254
  if not font_path:
255
  print(f"⚠️ Font not found: {text_style.font_family}")
 
257
 
258
  print(f"βœ… Using font: {font_path}")
259
 
260
+ # Get the actual font family name from the font file
261
+ font_family_name = get_font_family_name(font_path)
262
+ print(f"πŸ“ Font family name: {font_family_name}")
263
+
264
  # Create working directory for ASS file
265
  work_dir = os.path.dirname(output_video)
266
  ass_file = os.path.join(work_dir, "subtitle.ass")
267
 
268
+ # Color mapping (same as before)
269
  color_map = {
270
  "white": "FFFFFF", "black": "000000", "red": "FF0000",
271
  "green": "00FF00", "blue": "0000FF", "yellow": "FFFF00",
 
295
  margin_r = text_style.margin if alignment in [3,6,9] else 0
296
  margin_v = text_style.margin
297
 
298
+ # Create fontconfig configuration (optional, but helpful)
 
 
 
299
  font_dir = os.path.dirname(font_path)
 
 
 
 
300
  fc_config = f"""<?xml version="1.0"?>
301
  <!DOCTYPE fontconfig SYSTEM "fonts.dtd">
302
  <fontconfig>
303
  <dir>{font_dir}</dir>
 
 
 
 
 
 
 
 
304
  </fontconfig>"""
305
 
306
  fc_file = os.path.join(work_dir, "fonts.conf")
 
310
  # Set environment variable for fontconfig
311
  os.environ['FONTCONFIG_FILE'] = fc_file
312
 
313
+ # Create ASS file content - USE THE ACTUAL FONT FAMILY NAME
314
  ass_content = f"""[Script Info]
315
  ; Script generated by Video Styling Space
316
  ScriptType: v4.00+
 
320
 
321
  [V4+ Styles]
322
  Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
323
+ Style: Default,{font_family_name},{text_style.font_size},&H00{font_color_hex},&H000000FF,&H00000000,&H{bg_alpha:02X}{bg_color_hex},0,0,0,0,100,100,0,0,1,1,0,{alignment},{margin_l},{margin_r},{margin_v},1
324
 
325
  [Events]
326
  Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
 
330
  with open(ass_file, 'w', encoding='utf-8') as f:
331
  f.write(ass_content)
332
 
333
+ print(f"πŸ“ Created ASS subtitle file with font family: {font_family_name}")
 
 
 
 
 
334
 
335
+ # Run FFmpeg
336
  cmd = [
337
  'ffmpeg', '-y',
338
  '-i', input_video,
 
347
  if result.returncode != 0:
348
  print(f"❌ FFmpeg error: {result.stderr}")
349
 
350
+ # Try alternative drawtext method as fallback
351
  print("πŸ”„ Trying alternative drawtext method...")
 
 
352
  drawtext_pos = {
353
  "bottom-left": "x=20:y=h-th-20",
354
  "bottom-center": "x=(w-tw)/2:y=h-th-20",