Artificial-superintelligence commited on
Commit
9392609
·
verified ·
1 Parent(s): 8d4309d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +166 -129
app.py CHANGED
@@ -1,5 +1,5 @@
1
  import streamlit as st
2
- from moviepy.editor import VideoFileClip, AudioFileClip, TextClip, CompositeVideoClip
3
  import whisper
4
  from translate import Translator
5
  from gtts import gTTS
@@ -7,20 +7,17 @@ import tempfile
7
  import os
8
  import numpy as np
9
  from datetime import timedelta
10
- import json
11
- from indic_transliteration import sanscript
12
- from indic_transliteration.sanscript import transliterate
13
- import azure.cognitiveservices.speech as speechsdk
14
- import ffmpeg
15
 
16
  # Set page configuration
17
  st.set_page_config(
18
- page_title="translate",
19
  page_icon="🎬",
20
  layout="wide"
21
  )
22
 
23
- # Custom CSS to improve the interface
24
  st.markdown("""
25
  <style>
26
  .stButton>button {
@@ -36,7 +33,7 @@ st.markdown("""
36
  </style>
37
  """, unsafe_allow_html=True)
38
 
39
- # Tamil-specific voice configurations
40
  TAMIL_VOICES = {
41
  'Female 1': {'name': 'ta-IN-PallaviNeural', 'style': 'normal'},
42
  'Female 2': {'name': 'ta-IN-PallaviNeural', 'style': 'formal'},
@@ -66,37 +63,36 @@ def load_whisper_model():
66
  """Load Whisper model with caching"""
67
  return whisper.load_model("base")
68
 
69
- class TamilDubber:
70
  def __init__(self):
 
71
  self.whisper_model = load_whisper_model()
72
- self.temp_dir = tempfile.mkdtemp()
73
-
74
- def create_temp_file(self, suffix):
75
- """Create a temporary file in the temp directory"""
76
- return os.path.join(self.temp_dir, f"temp_{os.urandom(8).hex()}{suffix}")
77
 
78
  def cleanup(self):
79
- """Clean up temporary files"""
80
- import shutil
81
  try:
82
  shutil.rmtree(self.temp_dir)
83
  except Exception as e:
84
  st.warning(f"Cleanup warning: {e}")
85
 
86
- def extract_audio(self, video_path):
87
- """Extract audio and transcribe using Whisper"""
88
  try:
89
- video = VideoFileClip(video_path)
90
- audio_path = self.create_temp_file(".wav")
91
- video.audio.write_audiofile(audio_path, fps=16000)
92
-
93
- # Transcribe using Whisper
94
- result = self.whisper_model.transcribe(audio_path)
95
- return result["segments"], video.duration
96
-
 
97
  except Exception as e:
98
- st.error(f"Error in audio extraction: {e}")
99
- raise
100
 
101
  def translate_segments(self, segments):
102
  """Translate segments to Tamil"""
@@ -124,128 +120,173 @@ class TamilDubber:
124
  "end": segment["end"],
125
  "duration": segment["end"] - segment["start"]
126
  })
127
-
128
  return translated_segments
129
 
130
- def generate_audio(self, text, voice_style="normal"):
131
  """Generate Tamil audio using gTTS"""
132
  try:
133
- temp_path = self.create_temp_file(".mp3")
134
  tts = gTTS(text=text, lang='ta', slow=False)
135
- tts.save(temp_path)
136
- return temp_path
137
  except Exception as e:
138
- st.error(f"Error in audio generation: {e}")
139
- raise
140
 
141
- def create_subtitles(self, segments, output_path):
142
- """Generate SRT subtitles"""
143
- try:
144
- with open(output_path, 'w', encoding='utf-8') as f:
145
- for idx, segment in enumerate(segments, 1):
146
- start_time = str(timedelta(seconds=int(segment["start"])))
147
- end_time = str(timedelta(seconds=int(segment["end"])))
148
- f.write(f"{idx}\n")
149
- f.write(f"{start_time} --> {end_time}\n")
150
- f.write(f"{segment['text']}\n\n")
151
- except Exception as e:
152
- st.error(f"Error creating subtitles: {e}")
153
- raise
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154
 
155
  def main():
156
  st.title("Tamil Movie Dubbing System")
157
  st.markdown("""
158
- 👋 Welcome to the Tamil Movie Dubbing System! This tool helps you:
159
  - 🎥 Convert English videos to Tamil
160
  - 🗣️ Generate Tamil voiceovers
161
  - 📝 Add Tamil subtitles
162
  """)
163
 
164
- st.sidebar.header("டப்பிங் அமைப்புகள்") # Dubbing Settings in Tamil
165
-
166
- # File uploader with clear instructions
167
- st.info("Please upload a video file (MP4, MOV, or AVI format)")
168
  video_file = st.file_uploader("Upload Video File", type=['mp4', 'mov', 'avi'])
169
 
170
  if not video_file:
171
- st.warning("Please upload a video to begin the dubbing process.")
172
  return
173
-
174
- # Settings in sidebar
175
- with st.sidebar:
176
- st.subheader("Voice Settings")
 
177
  voice_type = st.selectbox("Select Voice", list(TAMIL_VOICES.keys()))
 
 
 
178
 
179
- st.subheader("Subtitle Settings")
180
- generate_subtitles = st.checkbox("Generate Tamil Subtitles", value=True)
181
- if generate_subtitles:
182
  subtitle_size = st.slider("Subtitle Size", 16, 32, 24)
 
183
  subtitle_color = st.color_picker("Subtitle Color", "#FFFFFF")
184
-
185
- # Main process
186
- if st.button("Start Tamil Dubbing"):
187
  try:
188
- dubber = TamilDubber()
189
-
190
- # Create progress containers
191
- progress_bar = st.progress(0)
192
- status_text = st.empty()
193
-
194
- try:
195
- # Save uploaded video
196
- temp_video_path = dubber.create_temp_file(".mp4")
197
- with open(temp_video_path, "wb") as f:
198
- f.write(video_file.read())
199
-
200
- # Extract audio and transcribe
201
- status_text.text("📥 Extracting audio and transcribing...")
202
- segments, video_duration = dubber.extract_audio(temp_video_path)
203
- progress_bar.progress(0.25)
204
-
205
- # Translate segments
206
- status_text.text("🔄 Translating to Tamil...")
207
- translated_segments = dubber.translate_segments(segments)
208
- progress_bar.progress(0.50)
209
-
210
- # Generate Tamil audio
211
- status_text.text("🔊 Generating Tamil audio...")
212
- video = VideoFileClip(temp_video_path)
213
 
214
- audio_segments = []
215
- for idx, segment in enumerate(translated_segments):
216
- audio_path = dubber.generate_audio(segment["text"])
217
- audio_segments.append({
218
- "audio": AudioFileClip(audio_path),
219
- "start": segment["start"]
220
- })
221
- progress_bar.progress(0.50 + (0.25 * (idx + 1) / len(translated_segments)))
222
-
223
- # Create final video
224
- status_text.text("🎬 Creating final video...")
225
- output_path = dubber.create_temp_file(".mp4")
226
 
227
- # Add subtitles if enabled
228
- if generate_subtitles:
229
- srt_path = dubber.create_temp_file(".srt")
230
- dubber.create_subtitles(translated_segments, srt_path)
231
-
232
- # Use ffmpeg to add subtitles
233
- stream = ffmpeg.input(temp_video_path)
234
- stream = ffmpeg.output(stream, output_path,
235
- vf=f'subtitles={srt_path}:force_style=\'FontSize={subtitle_size},PrimaryColour={subtitle_color}\'',
236
- acodec='aac')
237
- ffmpeg.run(stream, overwrite_output=True)
238
- else:
239
- # Just copy the video if no subtitles
240
- video.write_videofile(output_path)
241
-
242
- progress_bar.progress(1.0)
243
- status_text.text("✅ Dubbing completed!")
244
-
245
- # Display result
246
- st.success("டப்பிங் வெற்றிகரமாக முடிந்தது!") # Dubbing completed successfully in Tamil
247
  st.video(output_path)
248
-
249
  # Download button
250
  with open(output_path, "rb") as f:
251
  st.download_button(
@@ -254,14 +295,10 @@ def main():
254
  file_name="tamil_dubbed_video.mp4",
255
  mime="video/mp4"
256
  )
257
-
258
- finally:
259
- # Cleanup
260
- dubber.cleanup()
261
 
262
  except Exception as e:
263
- st.error(f"An error occurred: {str(e)}")
264
- st.error("Please try again with a different video or check if the video format is supported.")
265
 
266
  if __name__ == "__main__":
267
  main()
 
1
  import streamlit as st
2
+ from moviepy.editor import VideoFileClip, AudioFileClip, TextClip, CompositeVideoClip, concatenate_audioclips
3
  import whisper
4
  from translate import Translator
5
  from gtts import gTTS
 
7
  import os
8
  import numpy as np
9
  from datetime import timedelta
10
+ import shutil
11
+ from pathlib import Path
 
 
 
12
 
13
  # Set page configuration
14
  st.set_page_config(
15
+ page_title="Tamil Movie Dubber",
16
  page_icon="🎬",
17
  layout="wide"
18
  )
19
 
20
+ # Custom CSS
21
  st.markdown("""
22
  <style>
23
  .stButton>button {
 
33
  </style>
34
  """, unsafe_allow_html=True)
35
 
36
+ # Tamil voice configurations
37
  TAMIL_VOICES = {
38
  'Female 1': {'name': 'ta-IN-PallaviNeural', 'style': 'normal'},
39
  'Female 2': {'name': 'ta-IN-PallaviNeural', 'style': 'formal'},
 
63
  """Load Whisper model with caching"""
64
  return whisper.load_model("base")
65
 
66
+ class VideoProcessor:
67
  def __init__(self):
68
+ self.temp_dir = Path(tempfile.mkdtemp())
69
  self.whisper_model = load_whisper_model()
70
+
71
+ def create_temp_path(self, suffix):
72
+ """Create a temporary file path"""
73
+ return str(self.temp_dir / f"temp_{os.urandom(4).hex()}{suffix}")
 
74
 
75
  def cleanup(self):
76
+ """Clean up temporary directory"""
 
77
  try:
78
  shutil.rmtree(self.temp_dir)
79
  except Exception as e:
80
  st.warning(f"Cleanup warning: {e}")
81
 
82
+ def transcribe_video(self, video_path):
83
+ """Transcribe video audio using Whisper"""
84
  try:
85
+ with VideoFileClip(video_path) as video:
86
+ # Extract audio to temporary file
87
+ audio_path = self.create_temp_path(".wav")
88
+ video.audio.write_audiofile(audio_path, fps=16000, verbose=False, logger=None)
89
+
90
+ # Transcribe using Whisper
91
+ result = self.whisper_model.transcribe(audio_path)
92
+ return result["segments"], video.duration
93
+
94
  except Exception as e:
95
+ raise Exception(f"Transcription error: {str(e)}")
 
96
 
97
  def translate_segments(self, segments):
98
  """Translate segments to Tamil"""
 
120
  "end": segment["end"],
121
  "duration": segment["end"] - segment["start"]
122
  })
123
+
124
  return translated_segments
125
 
126
+ def generate_tamil_audio(self, text):
127
  """Generate Tamil audio using gTTS"""
128
  try:
129
+ audio_path = self.create_temp_path(".mp3")
130
  tts = gTTS(text=text, lang='ta', slow=False)
131
+ tts.save(audio_path)
132
+ return audio_path
133
  except Exception as e:
134
+ raise Exception(f"Audio generation error: {str(e)}")
 
135
 
136
+ def create_subtitle_clip(self, txt, fontsize, color, size):
137
+ """Create a subtitle clip"""
138
+ return TextClip(
139
+ txt=txt,
140
+ fontsize=fontsize,
141
+ color=color,
142
+ bg_color='rgba(0,0,0,0.5)',
143
+ size=size,
144
+ method='caption'
145
+ )
146
+
147
+ def process_video(video_data, voice_type, generate_subtitles=True, subtitle_size=24, subtitle_color='white'):
148
+ """Main video processing function"""
149
+ processor = VideoProcessor()
150
+
151
+ try:
152
+ # Save uploaded video to temporary file
153
+ input_path = processor.create_temp_path(".mp4")
154
+ with open(input_path, "wb") as f:
155
+ f.write(video_data)
156
+
157
+ # Load video
158
+ video = VideoFileClip(input_path)
159
+
160
+ # Create progress tracking
161
+ progress_text = st.empty()
162
+ progress_bar = st.progress(0)
163
+
164
+ # Step 1: Transcribe
165
+ progress_text.text("Transcribing video...")
166
+ segments, duration = processor.transcribe_video(input_path)
167
+ progress_bar.progress(0.25)
168
+
169
+ # Step 2: Translate
170
+ progress_text.text("Translating to Tamil...")
171
+ translated_segments = processor.translate_segments(segments)
172
+ progress_bar.progress(0.50)
173
+
174
+ # Step 3: Generate audio
175
+ progress_text.text("Generating Tamil audio...")
176
+ subtitle_clips = []
177
+ audio_clips = []
178
+
179
+ for i, segment in enumerate(translated_segments):
180
+ # Generate audio
181
+ audio_path = processor.generate_tamil_audio(segment["text"])
182
+ audio_clip = AudioFileClip(audio_path)
183
+ audio_clips.append(audio_clip.set_start(segment["start"]))
184
+
185
+ # Create subtitle if enabled
186
+ if generate_subtitles:
187
+ subtitle_clip = processor.create_subtitle_clip(
188
+ segment["text"],
189
+ subtitle_size,
190
+ subtitle_color,
191
+ (video.w, None)
192
+ )
193
+ subtitle_clip = (subtitle_clip
194
+ .set_position(('center', 'bottom'))
195
+ .set_start(segment["start"])
196
+ .set_duration(segment["duration"]))
197
+ subtitle_clips.append(subtitle_clip)
198
+
199
+ progress_bar.progress(0.50 + (0.4 * (i + 1) / len(translated_segments)))
200
+
201
+ # Step 4: Combine everything
202
+ progress_text.text("Creating final video...")
203
+
204
+ # Combine audio clips
205
+ final_audio = CompositeVideoClip([*audio_clips])
206
+
207
+ # Create final video
208
+ if generate_subtitles:
209
+ final_video = CompositeVideoClip([video, *subtitle_clips])
210
+ else:
211
+ final_video = video
212
+
213
+ # Set audio
214
+ final_video = final_video.set_audio(final_audio)
215
+
216
+ # Write final video
217
+ output_path = processor.create_temp_path(".mp4")
218
+ final_video.write_videofile(
219
+ output_path,
220
+ codec='libx264',
221
+ audio_codec='aac',
222
+ temp_audiofile=processor.create_temp_path(".m4a"),
223
+ remove_temp=True,
224
+ verbose=False,
225
+ logger=None
226
+ )
227
+
228
+ progress_bar.progress(1.0)
229
+ progress_text.text("Processing complete!")
230
+
231
+ return output_path
232
+
233
+ except Exception as e:
234
+ raise Exception(f"Video processing error: {str(e)}")
235
+
236
+ finally:
237
+ # Cleanup
238
+ processor.cleanup()
239
 
240
  def main():
241
  st.title("Tamil Movie Dubbing System")
242
  st.markdown("""
243
+ 👋 Welcome! This tool helps you:
244
  - 🎥 Convert English videos to Tamil
245
  - 🗣️ Generate Tamil voiceovers
246
  - 📝 Add Tamil subtitles
247
  """)
248
 
249
+ # File uploader
 
 
 
250
  video_file = st.file_uploader("Upload Video File", type=['mp4', 'mov', 'avi'])
251
 
252
  if not video_file:
253
+ st.warning("Please upload a video to begin.")
254
  return
255
+
256
+ # Settings
257
+ col1, col2 = st.columns(2)
258
+
259
+ with col1:
260
  voice_type = st.selectbox("Select Voice", list(TAMIL_VOICES.keys()))
261
+
262
+ with col2:
263
+ generate_subtitles = st.checkbox("Generate Subtitles", value=True)
264
 
265
+ if generate_subtitles:
266
+ col3, col4 = st.columns(2)
267
+ with col3:
268
  subtitle_size = st.slider("Subtitle Size", 16, 32, 24)
269
+ with col4:
270
  subtitle_color = st.color_picker("Subtitle Color", "#FFFFFF")
271
+
272
+ # Process video
273
+ if st.button("Start Dubbing"):
274
  try:
275
+ with st.spinner("Processing video..."):
276
+ output_path = process_video(
277
+ video_file.read(),
278
+ voice_type,
279
+ generate_subtitles,
280
+ subtitle_size if generate_subtitles else 24,
281
+ subtitle_color if generate_subtitles else 'white'
282
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
283
 
284
+ # Show success message
285
+ st.success("டப்பிங் வெற்றிகரமாக முடிந்தது!")
 
 
 
 
 
 
 
 
 
 
286
 
287
+ # Display video
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
288
  st.video(output_path)
289
+
290
  # Download button
291
  with open(output_path, "rb") as f:
292
  st.download_button(
 
295
  file_name="tamil_dubbed_video.mp4",
296
  mime="video/mp4"
297
  )
 
 
 
 
298
 
299
  except Exception as e:
300
+ st.error(f"Processing failed: {str(e)}")
301
+ st.error("Please try uploading a different video or check if the format is supported.")
302
 
303
  if __name__ == "__main__":
304
  main()