lvvignesh2122 commited on
Commit
749833a
·
verified ·
1 Parent(s): 302d39c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +29 -50
app.py CHANGED
@@ -16,7 +16,6 @@ def _format_timestamp(seconds: float) -> str:
16
  millis = ms_rem % 1000
17
  return f"{hours:02d}:{minutes:02d}:{secs:02d},{millis:03d}"
18
 
19
-
20
  def segments_to_srt(segments: list) -> str:
21
  lines = []
22
  for i, seg in enumerate(segments, start=1):
@@ -29,21 +28,19 @@ def segments_to_srt(segments: list) -> str:
29
  lines.append(block)
30
  return "\n".join(lines)
31
 
32
-
33
  # -------- Config --------
34
- MODEL_NAME = "Systran/faster-whisper-small" # best for HF CPU
35
  DEVICE = "cpu"
36
  OUTPUT_DIR = Path("outputs/subtitles")
37
  OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
38
 
39
  print(f"Loading model {MODEL_NAME} on {DEVICE} ...")
40
  model = WhisperModel(MODEL_NAME, device=DEVICE)
41
- print("Model loaded successfully.")
42
-
43
 
44
  # -------- Core functions --------
45
  def extract_audio(input_path: str, out_path: str):
46
- """Extract mono 16kHz WAV using ffmpeg"""
47
  try:
48
  (
49
  ffmpeg
@@ -55,34 +52,37 @@ def extract_audio(input_path: str, out_path: str):
55
  except ffmpeg.Error as e:
56
  stderr = getattr(e, "stderr", None)
57
  msg = stderr.decode() if stderr else str(e)
58
- raise RuntimeError(f"FFmpeg error: {msg}")
59
-
60
 
61
  def transcribe_file_to_srt(file_obj, language: str = "en"):
62
- """Transcribe uploaded file to SRT (compatible with HF Spaces)."""
63
  tmp_dir = Path(tempfile.mkdtemp(prefix="subgen_"))
 
 
 
 
64
 
65
- # Ensure we can read uploaded file correctly
66
- input_path = tmp_dir / Path(file_obj.name).name
67
- with open(input_path, "wb") as f:
68
- f.write(file_obj.read())
 
 
69
 
70
  # Extract audio and transcribe
71
  audio_path = tmp_dir / "audio.wav"
72
  extract_audio(str(input_path), str(audio_path))
73
- segments, _ = model.transcribe(str(audio_path), language=language)
74
 
 
75
  segs = [{"start": s.start, "end": s.end, "text": s.text} for s in segments]
76
  srt_text = segments_to_srt(segs)
77
 
78
- # Save .srt file
79
  output_path = OUTPUT_DIR / f"{Path(file_obj.name).stem}.srt"
80
  with open(output_path, "w", encoding="utf-8") as f:
81
  f.write(srt_text)
82
 
83
  return str(output_path), "✅ Subtitles generated successfully!"
84
 
85
-
86
  # -------- Gradio UI --------
87
  with gr.Blocks(title="AI Subtitle Generator") as demo:
88
  theme_state = gr.State("light")
@@ -97,58 +97,37 @@ 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(
101
- value=f"<style>body {{ background: {bg}; color: {color}; }}</style>"
102
- )
103
 
104
  gr.HTML("<h1 style='text-align:center;'>🎬 AI Subtitle Generator</h1>")
105
- gr.HTML(
106
- "<p style='text-align:center;'>Upload a video or audio file to generate English <b>.srt</b> subtitles.</p>"
107
- )
108
-
109
  style_box = gr.HTML("")
110
  theme_btn = gr.Button("🌙 Toggle Light/Dark Mode")
111
 
112
  with gr.Row():
113
- input_file = gr.File(
114
- label="Upload video/audio file",
115
- file_types=None, # accept all, Gradio will still preview audio/video
116
- )
117
-
118
  output_file = gr.File(label="Download .srt file")
119
-
120
- status_box = gr.Textbox(label="Status", interactive=False)
121
 
122
  def on_click(file):
123
- if file is None:
124
- return None, "⚠️ Please upload a file first!"
125
  srt_path, msg = transcribe_file_to_srt(file)
126
  return srt_path, msg
127
 
128
- def clear_all():
129
  return None, None, ""
130
 
131
- theme_btn.click(
132
- toggle_theme, inputs=[theme_state], outputs=[theme_state]
133
- ).then(apply_theme, inputs=[theme_state], outputs=[style_box])
134
 
135
  with gr.Row():
136
- generate_btn = gr.Button("🎧 Generate Subtitles")
137
  clear_btn = gr.Button("🧹 Clear")
138
 
139
- generate_btn.click(
140
- on_click, inputs=[input_file], outputs=[output_file, status_box]
141
- )
142
-
143
- clear_btn.click(
144
- clear_all,
145
- inputs=[],
146
- outputs=[input_file, output_file, status_box],
147
- )
148
 
149
- gr.HTML(
150
- "<p style='text-align:center;font-size:14px;opacity:0.7;'>Powered by Faster-Whisper + Gradio UI</p>"
151
- )
152
 
153
  if __name__ == "__main__":
154
- demo.queue().launch()
 
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
  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)
36
 
37
  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"""
44
  try:
45
  (
46
  ffmpeg
 
52
  except ffmpeg.Error as e:
53
  stderr = getattr(e, "stderr", None)
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
  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()