lvvignesh2122 commited on
Commit
cce83a6
Β·
verified Β·
1 Parent(s): 749833a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +34 -27
app.py CHANGED
@@ -1,5 +1,7 @@
 
1
  import os
2
  import tempfile
 
3
  from pathlib import Path
4
  import gradio as gr
5
  import ffmpeg
@@ -16,6 +18,7 @@ def _format_timestamp(seconds: float) -> str:
16
  millis = ms_rem % 1000
17
  return f"{hours:02d}:{minutes:02d}:{secs:02d},{millis:03d}"
18
 
 
19
  def segments_to_srt(segments: list) -> str:
20
  lines = []
21
  for i, seg in enumerate(segments, start=1):
@@ -28,8 +31,9 @@ def segments_to_srt(segments: list) -> str:
28
  lines.append(block)
29
  return "\n".join(lines)
30
 
 
31
  # -------- Config --------
32
- MODEL_NAME = "Systran/faster-whisper-small" # optimized for HF CPU
33
  DEVICE = "cpu"
34
  OUTPUT_DIR = Path("outputs/subtitles")
35
  OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
@@ -38,6 +42,7 @@ print(f"Loading model {MODEL_NAME} on {DEVICE} ...")
38
  model = WhisperModel(MODEL_NAME, device=DEVICE)
39
  print("Model loaded.")
40
 
 
41
  # -------- Core functions --------
42
  def extract_audio(input_path: str, out_path: str):
43
  """Extracts mono 16 kHz WAV using ffmpeg"""
@@ -54,35 +59,36 @@ def extract_audio(input_path: str, out_path: str):
54
  msg = stderr.decode() if stderr else str(e)
55
  raise RuntimeError(f"ffmpeg error: {msg}")
56
 
 
57
  def transcribe_file_to_srt(file_obj, language: str = "en"):
58
  """Transcribe uploaded file to SRT; compatible with HF Spaces"""
59
  tmp_dir = Path(tempfile.mkdtemp(prefix="subgen_"))
60
- input_path = Path(file_obj.name)
61
 
 
 
62
  if not input_path.exists():
63
  input_path = tmp_dir / Path(file_obj.name).name
64
-
65
- if hasattr(file_obj, "read_bytes"):
66
- with open(input_path, "wb") as f:
67
- f.write(file_obj.read_bytes())
68
- else:
69
- with open(file_obj.name, "rb") as src, open(input_path, "wb") as dst:
70
- dst.write(src.read())
71
 
72
  # Extract audio and transcribe
73
  audio_path = tmp_dir / "audio.wav"
74
  extract_audio(str(input_path), str(audio_path))
75
-
76
  segments, _ = model.transcribe(str(audio_path), language=language)
77
  segs = [{"start": s.start, "end": s.end, "text": s.text} for s in segments]
78
  srt_text = segments_to_srt(segs)
79
 
 
80
  output_path = OUTPUT_DIR / f"{Path(file_obj.name).stem}.srt"
81
  with open(output_path, "w", encoding="utf-8") as f:
82
  f.write(srt_text)
83
-
84
  return str(output_path), "βœ… Subtitles generated successfully!"
85
 
 
86
  # -------- Gradio UI --------
87
  with gr.Blocks(title="AI Subtitle Generator") as demo:
88
  theme_state = gr.State("light")
@@ -97,37 +103,38 @@ with gr.Blocks(title="AI Subtitle Generator") as demo:
97
  else:
98
  bg = "linear-gradient(135deg, #fdfbfb, #ebedee)"
99
  color = "#000000"
100
- return gr.update(value=f"<style>body {{ background: {bg}; color: {color}; }}</style>")
 
 
101
 
102
  gr.HTML("<h1 style='text-align:center;'>🎬 AI Subtitle Generator</h1>")
103
- gr.HTML("<p style='text-align:center;'>Upload a video or audio file to generate English <b>.srt</b> subtitles.</p>")
 
 
 
104
  style_box = gr.HTML("")
105
  theme_btn = gr.Button("πŸŒ™ Toggle Light/Dark Mode")
106
 
107
  with gr.Row():
108
  input_file = gr.File(label="Upload video/audio file")
109
  output_file = gr.File(label="Download .srt file")
110
- status_box = gr.Textbox(label="Status", interactive=False)
 
111
 
112
  def on_click(file):
113
  srt_path, msg = transcribe_file_to_srt(file)
114
  return srt_path, msg
115
 
116
- def clear_fields():
117
- return None, None, ""
118
-
119
- theme_btn.click(toggle_theme, inputs=[theme_state], outputs=[theme_state]).then(
120
- apply_theme, inputs=[theme_state], outputs=[style_box]
121
- )
122
-
123
- with gr.Row():
124
- generate_btn = gr.Button("Generate Subtitles")
125
- clear_btn = gr.Button("🧹 Clear")
126
 
 
127
  generate_btn.click(on_click, inputs=[input_file], outputs=[output_file, status_box])
128
- clear_btn.click(fn=clear_fields, outputs=[input_file, output_file, status_box])
129
 
130
- gr.HTML("<p style='text-align:center;font-size:14px;opacity:0.7;'>Powered by Faster-Whisper + Gradio UI</p>")
 
 
131
 
132
  if __name__ == "__main__":
133
- demo.launch()
 
1
+ # app.py
2
  import os
3
  import tempfile
4
+ import uuid
5
  from pathlib import Path
6
  import gradio as gr
7
  import ffmpeg
 
18
  millis = ms_rem % 1000
19
  return f"{hours:02d}:{minutes:02d}:{secs:02d},{millis:03d}"
20
 
21
+
22
  def segments_to_srt(segments: list) -> str:
23
  lines = []
24
  for i, seg in enumerate(segments, start=1):
 
31
  lines.append(block)
32
  return "\n".join(lines)
33
 
34
+
35
  # -------- Config --------
36
+ MODEL_NAME = "Systran/faster-whisper-small" # good for HF CPU
37
  DEVICE = "cpu"
38
  OUTPUT_DIR = Path("outputs/subtitles")
39
  OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
 
42
  model = WhisperModel(MODEL_NAME, device=DEVICE)
43
  print("Model loaded.")
44
 
45
+
46
  # -------- Core functions --------
47
  def extract_audio(input_path: str, out_path: str):
48
  """Extracts mono 16 kHz WAV using ffmpeg"""
 
59
  msg = stderr.decode() if stderr else str(e)
60
  raise RuntimeError(f"ffmpeg error: {msg}")
61
 
62
+
63
  def transcribe_file_to_srt(file_obj, language: str = "en"):
64
  """Transcribe uploaded file to SRT; compatible with HF Spaces"""
65
  tmp_dir = Path(tempfile.mkdtemp(prefix="subgen_"))
 
66
 
67
+ # Handle Hugging Face NamedString / Path
68
+ input_path = Path(file_obj.name)
69
  if not input_path.exists():
70
  input_path = tmp_dir / Path(file_obj.name).name
71
+ if hasattr(file_obj, "read_bytes"):
72
+ with open(input_path, "wb") as f:
73
+ f.write(file_obj.read_bytes())
74
+ else:
75
+ with open(file_obj.name, "rb") as src, open(input_path, "wb") as dst:
76
+ dst.write(src.read())
 
77
 
78
  # Extract audio and transcribe
79
  audio_path = tmp_dir / "audio.wav"
80
  extract_audio(str(input_path), str(audio_path))
 
81
  segments, _ = model.transcribe(str(audio_path), language=language)
82
  segs = [{"start": s.start, "end": s.end, "text": s.text} for s in segments]
83
  srt_text = segments_to_srt(segs)
84
 
85
+ # Save .srt file
86
  output_path = OUTPUT_DIR / f"{Path(file_obj.name).stem}.srt"
87
  with open(output_path, "w", encoding="utf-8") as f:
88
  f.write(srt_text)
 
89
  return str(output_path), "βœ… Subtitles generated successfully!"
90
 
91
+
92
  # -------- Gradio UI --------
93
  with gr.Blocks(title="AI Subtitle Generator") as demo:
94
  theme_state = gr.State("light")
 
103
  else:
104
  bg = "linear-gradient(135deg, #fdfbfb, #ebedee)"
105
  color = "#000000"
106
+ return gr.update(
107
+ value=f"<style>body {{ background: {bg}; color: {color}; }}</style>"
108
+ )
109
 
110
  gr.HTML("<h1 style='text-align:center;'>🎬 AI Subtitle Generator</h1>")
111
+ gr.HTML(
112
+ "<p style='text-align:center;'>Upload a video or audio file to generate English <b>.srt</b> subtitles.</p>"
113
+ )
114
+
115
  style_box = gr.HTML("")
116
  theme_btn = gr.Button("πŸŒ™ Toggle Light/Dark Mode")
117
 
118
  with gr.Row():
119
  input_file = gr.File(label="Upload video/audio file")
120
  output_file = gr.File(label="Download .srt file")
121
+
122
+ status_box = gr.Textbox(label="Status", interactive=False)
123
 
124
  def on_click(file):
125
  srt_path, msg = transcribe_file_to_srt(file)
126
  return srt_path, msg
127
 
128
+ theme_btn.click(
129
+ toggle_theme, inputs=[theme_state], outputs=[theme_state]
130
+ ).then(apply_theme, inputs=[theme_state], outputs=[style_box])
 
 
 
 
 
 
 
131
 
132
+ generate_btn = gr.Button("Generate Subtitles")
133
  generate_btn.click(on_click, inputs=[input_file], outputs=[output_file, status_box])
 
134
 
135
+ gr.HTML(
136
+ "<p style='text-align:center;font-size:14px;opacity:0.7;'>Powered by Faster-Whisper + Gradio UI</p>"
137
+ )
138
 
139
  if __name__ == "__main__":
140
+ demo.launch()