Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
|
@@ -189,17 +189,33 @@ def transcribe_to_srt(audio_file, language="hindi"):
|
|
| 189 |
|
| 190 |
return srt_content, preview, status
|
| 191 |
|
| 192 |
-
def process_video(video_file, language="hindi", progress=gr.Progress()):
|
| 193 |
"""Full video processing with subtitle burning"""
|
| 194 |
|
| 195 |
if not video_file:
|
| 196 |
return None, None, "Please upload a video"
|
| 197 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 198 |
output_dir = tempfile.mkdtemp()
|
| 199 |
print(f"\n{'='*60}")
|
| 200 |
print(f"VIDEO PROCESSING STARTED")
|
| 201 |
print(f"{'='*60}")
|
| 202 |
print(f" Output directory: {output_dir}")
|
|
|
|
| 203 |
print(f" Using: {'faster-whisper' if USE_FASTER_WHISPER else 'transformers pipeline'}")
|
| 204 |
print(f"{'='*60}\n")
|
| 205 |
|
|
@@ -250,6 +266,34 @@ def process_video(video_file, language="hindi", progress=gr.Progress()):
|
|
| 250 |
], check=True, capture_output=True)
|
| 251 |
print(f"✅ ASS created: {ass_path} ({os.path.getsize(ass_path)} bytes)")
|
| 252 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 253 |
# Step 5: Burn subtitles
|
| 254 |
progress(0.9, desc="Burning subtitles...")
|
| 255 |
print("\nStep 5: Burning subtitles into video...")
|
|
@@ -339,6 +383,15 @@ with gr.Blocks(theme=gr.themes.Soft(), title="Hindi Subtitle Generator") as demo
|
|
| 339 |
value="hindi",
|
| 340 |
label="Language"
|
| 341 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 342 |
video_btn = gr.Button("Generate Subtitles", variant="primary")
|
| 343 |
|
| 344 |
with gr.Column():
|
|
@@ -348,7 +401,7 @@ with gr.Blocks(theme=gr.themes.Soft(), title="Hindi Subtitle Generator") as demo
|
|
| 348 |
|
| 349 |
video_btn.click(
|
| 350 |
fn=process_video,
|
| 351 |
-
inputs=[video_input, video_lang],
|
| 352 |
outputs=[srt_output, video_output, status_output]
|
| 353 |
)
|
| 354 |
|
|
|
|
| 189 |
|
| 190 |
return srt_content, preview, status
|
| 191 |
|
| 192 |
+
def process_video(video_file, language="hindi", subtitle_position="bottom-center", progress=gr.Progress()):
|
| 193 |
"""Full video processing with subtitle burning"""
|
| 194 |
|
| 195 |
if not video_file:
|
| 196 |
return None, None, "Please upload a video"
|
| 197 |
|
| 198 |
+
# Position mapping: alignment and vertical margin
|
| 199 |
+
POSITION_MAP = {
|
| 200 |
+
"top-left": (7, 80),
|
| 201 |
+
"top-center": (8, 80),
|
| 202 |
+
"top-right": (9, 80),
|
| 203 |
+
"middle-left": (4, 0),
|
| 204 |
+
"middle-center": (5, 0),
|
| 205 |
+
"middle-right": (6, 0),
|
| 206 |
+
"bottom-left": (1, 50),
|
| 207 |
+
"bottom-center": (2, 50),
|
| 208 |
+
"bottom-right": (3, 50),
|
| 209 |
+
}
|
| 210 |
+
|
| 211 |
+
alignment, margin = POSITION_MAP.get(subtitle_position, (2, 50))
|
| 212 |
+
|
| 213 |
output_dir = tempfile.mkdtemp()
|
| 214 |
print(f"\n{'='*60}")
|
| 215 |
print(f"VIDEO PROCESSING STARTED")
|
| 216 |
print(f"{'='*60}")
|
| 217 |
print(f" Output directory: {output_dir}")
|
| 218 |
+
print(f" Subtitle position: {subtitle_position} (alignment={alignment}, margin={margin})")
|
| 219 |
print(f" Using: {'faster-whisper' if USE_FASTER_WHISPER else 'transformers pipeline'}")
|
| 220 |
print(f"{'='*60}\n")
|
| 221 |
|
|
|
|
| 266 |
], check=True, capture_output=True)
|
| 267 |
print(f"✅ ASS created: {ass_path} ({os.path.getsize(ass_path)} bytes)")
|
| 268 |
|
| 269 |
+
# Modify ASS file to change subtitle position
|
| 270 |
+
print(f"\nModifying subtitle position to: {subtitle_position}...")
|
| 271 |
+
with open(ass_path, 'r', encoding='utf-8') as f:
|
| 272 |
+
ass_content = f.read()
|
| 273 |
+
|
| 274 |
+
# Replace default style with custom position
|
| 275 |
+
# Format: Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour,
|
| 276 |
+
# Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle,
|
| 277 |
+
# Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
|
| 278 |
+
|
| 279 |
+
# Find and replace the style line
|
| 280 |
+
import re
|
| 281 |
+
style_pattern = r'Style: Default,[^,]+,\d+,[^,]+,[^,]+,[^,]+,[^,]+,-?\d+,-?\d+,-?\d+,-?\d+,\d+,\d+,\d+,\d+,\d+,\d+,\d+,\d+,\d+,\d+,\d+,\d+'
|
| 282 |
+
|
| 283 |
+
def replace_style(match):
|
| 284 |
+
parts = match.group(0).split(',')
|
| 285 |
+
# Replace alignment (index 17) and MarginV (index 20)
|
| 286 |
+
parts[17] = str(alignment)
|
| 287 |
+
parts[20] = str(margin)
|
| 288 |
+
return ','.join(parts)
|
| 289 |
+
|
| 290 |
+
ass_content = re.sub(style_pattern, replace_style, ass_content)
|
| 291 |
+
|
| 292 |
+
with open(ass_path, 'w', encoding='utf-8') as f:
|
| 293 |
+
f.write(ass_content)
|
| 294 |
+
|
| 295 |
+
print(f"✅ Subtitle position updated: {subtitle_position}")
|
| 296 |
+
|
| 297 |
# Step 5: Burn subtitles
|
| 298 |
progress(0.9, desc="Burning subtitles...")
|
| 299 |
print("\nStep 5: Burning subtitles into video...")
|
|
|
|
| 383 |
value="hindi",
|
| 384 |
label="Language"
|
| 385 |
)
|
| 386 |
+
subtitle_pos = gr.Dropdown(
|
| 387 |
+
[
|
| 388 |
+
"top-left", "top-center", "top-right",
|
| 389 |
+
"middle-left", "middle-center", "middle-right",
|
| 390 |
+
"bottom-left", "bottom-center", "bottom-right"
|
| 391 |
+
],
|
| 392 |
+
value="bottom-center",
|
| 393 |
+
label="Subtitle Position"
|
| 394 |
+
)
|
| 395 |
video_btn = gr.Button("Generate Subtitles", variant="primary")
|
| 396 |
|
| 397 |
with gr.Column():
|
|
|
|
| 401 |
|
| 402 |
video_btn.click(
|
| 403 |
fn=process_video,
|
| 404 |
+
inputs=[video_input, video_lang, subtitle_pos],
|
| 405 |
outputs=[srt_output, video_output, status_output]
|
| 406 |
)
|
| 407 |
|