Spaces:
Paused
Paused
Update app.py
Browse files
app.py
CHANGED
|
@@ -632,22 +632,29 @@ def create_text_overlay(input_video, output_video, text_style):
|
|
| 632 |
work_dir = os.path.dirname(output_video)
|
| 633 |
ass_file = os.path.join(work_dir, "subtitle.ass")
|
| 634 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 635 |
# Get font color and convert from RRGGBB to BBGGRR for ASS
|
| 636 |
font_color_rgb = COLOR_MAP.get(text_style.color.lower(), "FFFFFF")
|
| 637 |
# Convert RGB to BGR (swap first two and last two characters)
|
| 638 |
font_color_bgr = font_color_rgb[4:6] + font_color_rgb[2:4] + font_color_rgb[0:2]
|
| 639 |
print(f"π¨ Font color: {text_style.color} -> RGB={font_color_rgb} -> BGR={font_color_bgr}")
|
| 640 |
|
| 641 |
-
# Parse background color
|
| 642 |
bg_parts = text_style.bg_color.split('@')
|
| 643 |
bg_color_name = bg_parts[0].lower()
|
| 644 |
bg_opacity = float(bg_parts[1]) if len(bg_parts) > 1 else 0.5
|
| 645 |
-
# Clamp opacity between 0 and 1
|
| 646 |
bg_opacity = max(0, min(1, bg_opacity))
|
| 647 |
bg_color_rgb = COLOR_MAP.get(bg_color_name, "000000")
|
| 648 |
# Convert RGB to BGR for background
|
| 649 |
bg_color_bgr = bg_color_rgb[4:6] + bg_color_rgb[2:4] + bg_color_rgb[0:2]
|
| 650 |
-
# Alpha
|
| 651 |
bg_alpha = int((1 - bg_opacity) * 255)
|
| 652 |
print(f"π¨ BG color: {bg_color_name} -> RGB={bg_color_rgb} -> BGR={bg_color_bgr}, Opacity={bg_opacity}, Alpha={bg_alpha}")
|
| 653 |
|
|
@@ -680,7 +687,7 @@ def create_text_overlay(input_video, output_video, text_style):
|
|
| 680 |
os.environ['FONTCONFIG_FILE'] = fc_file
|
| 681 |
|
| 682 |
# Create ASS file content with solid rectangle background
|
| 683 |
-
# BorderStyle=3 gives
|
| 684 |
ass_content = f"""[Script Info]
|
| 685 |
; Script generated by Video Styling Space
|
| 686 |
ScriptType: v4.00+
|
|
@@ -709,52 +716,54 @@ Dialogue: 0,0:00:00.00,0:00:10.00,Default,,0,0,0,,{text_style.text}"""
|
|
| 709 |
print(f"π Created ASS subtitle file with font family: {font_family_name}")
|
| 710 |
print(f"π Style line: BorderStyle=3, Outline={text_style.padding}, BackColor=&H{bg_alpha:02X}{bg_color_bgr}")
|
| 711 |
|
| 712 |
-
#
|
| 713 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 714 |
'ffmpeg', '-y',
|
| 715 |
'-i', input_video,
|
| 716 |
-
'-vf', f"
|
| 717 |
'-c:a', 'copy',
|
| 718 |
output_video
|
| 719 |
]
|
| 720 |
|
| 721 |
-
print(f"π¬ Running
|
| 722 |
-
result = subprocess.run(
|
| 723 |
|
| 724 |
-
if result.returncode
|
| 725 |
-
print(f"
|
| 726 |
-
|
| 727 |
-
|
| 728 |
-
print("
|
| 729 |
-
|
| 730 |
-
"bottom-left": "x=20:y=h-th-20",
|
| 731 |
-
"bottom-center": "x=(w-tw)/2:y=h-th-20",
|
| 732 |
-
"bottom-right": "x=w-tw-20:y=h-th-20",
|
| 733 |
-
"center": "x=(w-tw)/2:y=(h-th)/2",
|
| 734 |
-
"top-left": "x=20:y=20",
|
| 735 |
-
"top-center": "x=(w-tw)/2:y=20",
|
| 736 |
-
"top-right": "x=w-tw-20:y=20"
|
| 737 |
-
}
|
| 738 |
-
position = drawtext_pos.get(text_style.position, "x=(w-tw)/2:y=(h-th)/2")
|
| 739 |
|
| 740 |
-
|
|
|
|
| 741 |
'ffmpeg', '-y',
|
| 742 |
'-i', input_video,
|
| 743 |
-
'-vf', f"
|
| 744 |
'-c:a', 'copy',
|
| 745 |
output_video
|
| 746 |
]
|
| 747 |
|
| 748 |
-
result2 = subprocess.run(
|
| 749 |
if result2.returncode == 0:
|
| 750 |
-
print(f"β
|
| 751 |
return True
|
| 752 |
else:
|
| 753 |
-
print(f"β
|
| 754 |
return False
|
| 755 |
-
|
| 756 |
-
print(f"β
Video styled successfully with ASS subtitles")
|
| 757 |
-
return True
|
| 758 |
|
| 759 |
# =============================================
|
| 760 |
# DEBUG ENDPOINTS
|
|
|
|
| 632 |
work_dir = os.path.dirname(output_video)
|
| 633 |
ass_file = os.path.join(work_dir, "subtitle.ass")
|
| 634 |
|
| 635 |
+
# Color mapping
|
| 636 |
+
COLOR_MAP = {
|
| 637 |
+
"white": "FFFFFF", "black": "000000", "red": "FF0000",
|
| 638 |
+
"green": "00FF00", "blue": "0000FF", "yellow": "FFFF00",
|
| 639 |
+
"gold": "FFD700", "purple": "800080", "magenta": "FF00FF",
|
| 640 |
+
"cyan": "00FFFF", "orange": "FFA500", "pink": "FFC0CB"
|
| 641 |
+
}
|
| 642 |
+
|
| 643 |
# Get font color and convert from RRGGBB to BBGGRR for ASS
|
| 644 |
font_color_rgb = COLOR_MAP.get(text_style.color.lower(), "FFFFFF")
|
| 645 |
# Convert RGB to BGR (swap first two and last two characters)
|
| 646 |
font_color_bgr = font_color_rgb[4:6] + font_color_rgb[2:4] + font_color_rgb[0:2]
|
| 647 |
print(f"π¨ Font color: {text_style.color} -> RGB={font_color_rgb} -> BGR={font_color_bgr}")
|
| 648 |
|
| 649 |
+
# Parse background color
|
| 650 |
bg_parts = text_style.bg_color.split('@')
|
| 651 |
bg_color_name = bg_parts[0].lower()
|
| 652 |
bg_opacity = float(bg_parts[1]) if len(bg_parts) > 1 else 0.5
|
|
|
|
| 653 |
bg_opacity = max(0, min(1, bg_opacity))
|
| 654 |
bg_color_rgb = COLOR_MAP.get(bg_color_name, "000000")
|
| 655 |
# Convert RGB to BGR for background
|
| 656 |
bg_color_bgr = bg_color_rgb[4:6] + bg_color_rgb[2:4] + bg_color_rgb[0:2]
|
| 657 |
+
# Alpha: 0 = opaque, 255 = transparent
|
| 658 |
bg_alpha = int((1 - bg_opacity) * 255)
|
| 659 |
print(f"π¨ BG color: {bg_color_name} -> RGB={bg_color_rgb} -> BGR={bg_color_bgr}, Opacity={bg_opacity}, Alpha={bg_alpha}")
|
| 660 |
|
|
|
|
| 687 |
os.environ['FONTCONFIG_FILE'] = fc_file
|
| 688 |
|
| 689 |
# Create ASS file content with solid rectangle background
|
| 690 |
+
# BorderStyle=3 gives solid box, Outline controls padding
|
| 691 |
ass_content = f"""[Script Info]
|
| 692 |
; Script generated by Video Styling Space
|
| 693 |
ScriptType: v4.00+
|
|
|
|
| 716 |
print(f"π Created ASS subtitle file with font family: {font_family_name}")
|
| 717 |
print(f"π Style line: BorderStyle=3, Outline={text_style.padding}, BackColor=&H{bg_alpha:02X}{bg_color_bgr}")
|
| 718 |
|
| 719 |
+
# Try drawtext method first (more reliable for backgrounds)
|
| 720 |
+
print("π¬ Using drawtext method for reliable backgrounds...")
|
| 721 |
+
drawtext_pos = {
|
| 722 |
+
"bottom-left": "x=20:y=h-th-20",
|
| 723 |
+
"bottom-center": "x=(w-tw)/2:y=h-th-20",
|
| 724 |
+
"bottom-right": "x=w-tw-20:y=h-th-20",
|
| 725 |
+
"center": "x=(w-tw)/2:y=(h-th)/2",
|
| 726 |
+
"top-left": "x=20:y=20",
|
| 727 |
+
"top-center": "x=(w-tw)/2:y=20",
|
| 728 |
+
"top-right": "x=w-tw-20:y=20"
|
| 729 |
+
}
|
| 730 |
+
position = drawtext_pos.get(text_style.position, "x=(w-tw)/2:y=(h-th)/2")
|
| 731 |
+
|
| 732 |
+
# Use the actual color name for drawtext
|
| 733 |
+
drawtext_cmd = [
|
| 734 |
'ffmpeg', '-y',
|
| 735 |
'-i', input_video,
|
| 736 |
+
'-vf', f"drawtext=text='{text_style.text}':fontfile={font_path}:fontsize={text_style.font_size}:fontcolor={text_style.color}:{position}:box=1:boxcolor={bg_color_name}@{bg_opacity}:boxborderw={text_style.padding}",
|
| 737 |
'-c:a', 'copy',
|
| 738 |
output_video
|
| 739 |
]
|
| 740 |
|
| 741 |
+
print(f"π¬ Running drawtext command...")
|
| 742 |
+
result = subprocess.run(drawtext_cmd, capture_output=True, text=True)
|
| 743 |
|
| 744 |
+
if result.returncode == 0:
|
| 745 |
+
print(f"β
Drawtext method succeeded with solid background")
|
| 746 |
+
return True
|
| 747 |
+
else:
|
| 748 |
+
print(f"β Drawtext failed: {result.stderr}")
|
| 749 |
+
print("π Falling back to ASS method...")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 750 |
|
| 751 |
+
# Try ASS method as fallback
|
| 752 |
+
cmd = [
|
| 753 |
'ffmpeg', '-y',
|
| 754 |
'-i', input_video,
|
| 755 |
+
'-vf', f"ass={ass_file}",
|
| 756 |
'-c:a', 'copy',
|
| 757 |
output_video
|
| 758 |
]
|
| 759 |
|
| 760 |
+
result2 = subprocess.run(cmd, capture_output=True, text=True)
|
| 761 |
if result2.returncode == 0:
|
| 762 |
+
print(f"β
ASS method succeeded")
|
| 763 |
return True
|
| 764 |
else:
|
| 765 |
+
print(f"β ASS method also failed: {result2.stderr}")
|
| 766 |
return False
|
|
|
|
|
|
|
|
|
|
| 767 |
|
| 768 |
# =============================================
|
| 769 |
# DEBUG ENDPOINTS
|