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

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +128 -143
app.py CHANGED
@@ -12,27 +12,29 @@ from indic_transliteration import sanscript
12
  from indic_transliteration.sanscript import transliterate
13
  import azure.cognitiveservices.speech as speechsdk
14
  import ffmpeg
15
- from PIL import Image
16
- import imageio
17
 
18
- # Configure MoviePy to use imageio for reading images
19
- imageio.plugins.ffmpeg.download()
 
 
 
 
20
 
21
- # Configure ImageMagick policy to allow PDF and text file handling
22
- def configure_imagemagick():
23
- """Configure ImageMagick policy to allow text operations"""
24
- policy_file = "/etc/ImageMagick-6/policy.xml"
25
- if os.path.exists(policy_file):
26
- try:
27
- with open(policy_file, 'r') as f:
28
- policy_content = f.read()
29
- # Modify policy to allow text file handling
30
- policy_content = policy_content.replace('rights="none" pattern="@*"', 'rights="read|write" pattern="@*"')
31
- with open(policy_file, 'w') as f:
32
- f.write(policy_content)
33
- except Exception as e:
34
- st.warning(f"Unable to configure ImageMagick policy: {e}")
35
- st.info("You may need to run this application with sudo privileges to modify ImageMagick policy")
36
 
37
  # Tamil-specific voice configurations
38
  TAMIL_VOICES = {
@@ -59,42 +61,39 @@ class TamilTextProcessor:
59
  text = ' '.join(text.split())
60
  return text
61
 
 
 
 
 
 
62
  class TamilDubber:
63
  def __init__(self):
64
- try:
65
- self.whisper_model = whisper.load_model("base")
66
- except Exception as e:
67
- st.error(f"Error loading Whisper model: {e}")
68
- raise
69
- self.temp_files = []
70
-
71
- def __enter__(self):
72
- return self
73
 
74
- def __exit__(self, exc_type, exc_val, exc_tb):
75
- self.cleanup()
 
76
 
77
  def cleanup(self):
78
- for temp_file in self.temp_files:
79
- if os.path.exists(temp_file):
80
- try:
81
- os.remove(temp_file)
82
- except Exception:
83
- pass
84
-
85
- def create_temp_file(self, suffix):
86
- temp_file = tempfile.mktemp(suffix=suffix)
87
- self.temp_files.append(temp_file)
88
- return temp_file
89
 
90
  def extract_audio(self, video_path):
91
  """Extract audio and transcribe using Whisper"""
92
  try:
93
  video = VideoFileClip(video_path)
94
  audio_path = self.create_temp_file(".wav")
95
- video.audio.write_audiofile(audio_path)
 
 
96
  result = self.whisper_model.transcribe(audio_path)
97
  return result["segments"], video.duration
 
98
  except Exception as e:
99
  st.error(f"Error in audio extraction: {e}")
100
  raise
@@ -118,6 +117,7 @@ class TamilDubber:
118
  })
119
  except Exception as e:
120
  st.warning(f"Translation warning for segment: {str(e)}")
 
121
  translated_segments.append({
122
  "text": segment["text"],
123
  "start": segment["start"],
@@ -152,131 +152,116 @@ class TamilDubber:
152
  st.error(f"Error creating subtitles: {e}")
153
  raise
154
 
155
- def create_subtitle_clip(self, txt, size, color):
156
- """Create subtitle clip with proper configuration"""
157
- try:
158
- return TextClip(
159
- txt=txt,
160
- font='DejaVu-Sans', # Use a system font that supports Tamil
161
- fontsize=size,
162
- color=color,
163
- stroke_color='black',
164
- stroke_width=1,
165
- method='caption', # Use caption method instead of label
166
- size=(720, None) # Set width, let height adjust automatically
167
- )
168
- except Exception as e:
169
- st.error(f"Error creating subtitle clip: {e}")
170
- raise
171
-
172
  def main():
173
- # Configure ImageMagick at startup
174
- configure_imagemagick()
175
-
176
  st.title("Tamil Movie Dubbing System")
 
 
 
 
 
 
 
177
  st.sidebar.header("டப்பிங் அமைப்புகள்") # Dubbing Settings in Tamil
178
 
179
- # File uploader
 
180
  video_file = st.file_uploader("Upload Video File", type=['mp4', 'mov', 'avi'])
 
181
  if not video_file:
 
182
  return
183
 
184
- # Settings
185
- voice_type = st.selectbox("Select Voice", list(TAMIL_VOICES.keys()))
186
-
187
- with st.expander("Advanced Settings"):
 
 
188
  generate_subtitles = st.checkbox("Generate Tamil Subtitles", value=True)
189
- subtitle_size = st.slider("Subtitle Size", 16, 32, 24)
190
- subtitle_color = st.color_picker("Subtitle Color", "#FFFFFF")
 
191
 
 
192
  if st.button("Start Tamil Dubbing"):
193
  try:
194
- with st.spinner("Processing video..."):
195
- with TamilDubber() as dubber:
196
- # Save uploaded video
197
- temp_video_path = dubber.create_temp_file(".mp4")
198
- with open(temp_video_path, "wb") as f:
199
- f.write(video_file.read())
 
 
 
 
 
200
 
201
- # Progress tracking
202
- progress_bar = st.progress(0)
203
- status_text = st.empty()
 
204
 
205
- # Extract audio and transcribe
206
- status_text.text("Extracting audio and transcribing...")
207
- segments, video_duration = dubber.extract_audio(temp_video_path)
208
- progress_bar.progress(0.25)
209
 
210
- # Translate segments
211
- status_text.text("Translating to Tamil...")
212
- translated_segments = dubber.translate_segments(segments)
213
- progress_bar.progress(0.50)
 
 
 
 
 
 
 
 
214
 
215
- # Generate Tamil audio
216
- status_text.text("Generating Tamil audio...")
217
- output_segments = []
218
- video = VideoFileClip(temp_video_path)
 
 
 
 
219
 
220
- for idx, segment in enumerate(translated_segments):
221
- audio_path = dubber.generate_audio(segment["text"])
222
- output_segments.append({
223
- "audio": audio_path,
224
- "start": segment["start"],
225
- "end": segment["end"]
226
- })
227
- progress_bar.progress(0.50 + (0.25 * (idx + 1) / len(translated_segments)))
 
228
 
229
- # Create final video
230
- status_text.text("Creating final video...")
231
- output_path = dubber.create_temp_file(".mp4")
232
-
233
- # Add subtitles if enabled
234
- if generate_subtitles:
235
- subtitle_clips = []
236
- for segment in translated_segments:
237
- try:
238
- clip = dubber.create_subtitle_clip(
239
- segment["text"],
240
- subtitle_size,
241
- subtitle_color
242
- )
243
- clip = clip.set_position(('center', 'bottom'))
244
- clip = clip.set_start(segment["start"])
245
- clip = clip.set_duration(segment["duration"])
246
- subtitle_clips.append(clip)
247
- except Exception as e:
248
- st.warning(f"Skipping subtitle for segment due to error: {e}")
249
 
250
- final_video = CompositeVideoClip([video] + subtitle_clips)
251
- else:
252
- final_video = video
253
 
254
- # Write final video with proper codec settings
255
- final_video.write_videofile(
256
- output_path,
257
- codec='libx264',
258
- audio_codec='aac',
259
- fps=video.fps,
260
- threads=4,
261
- preset='medium'
262
  )
263
- progress_bar.progress(1.0)
264
-
265
- # Display result
266
- st.success("டப்பிங் வெற்றிகரமாக முடிந்தது!") # Dubbing completed successfully in Tamil
267
- st.video(output_path)
268
-
269
- # Download button
270
- with open(output_path, "rb") as f:
271
- st.download_button(
272
- "Download Dubbed Video",
273
- f,
274
- file_name="tamil_dubbed_video.mp4",
275
- mime="video/mp4"
276
- )
277
 
 
 
 
 
278
  except Exception as e:
279
  st.error(f"An error occurred: {str(e)}")
 
280
 
281
  if __name__ == "__main__":
282
  main()
 
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 {
27
+ width: 100%;
28
+ border-radius: 5px;
29
+ height: 3em;
30
+ background-color: #FF4B4B;
31
+ color: white;
32
+ }
33
+ .stProgress .st-bo {
34
+ background-color: #FF4B4B;
35
+ }
36
+ </style>
37
+ """, unsafe_allow_html=True)
38
 
39
  # Tamil-specific voice configurations
40
  TAMIL_VOICES = {
 
61
  text = ' '.join(text.split())
62
  return text
63
 
64
+ @st.cache_resource
65
+ 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
 
117
  })
118
  except Exception as e:
119
  st.warning(f"Translation warning for segment: {str(e)}")
120
+ # Keep original text if translation fails
121
  translated_segments.append({
122
  "text": segment["text"],
123
  "start": segment["start"],
 
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(
252
+ "⬇️ Download Dubbed Video",
253
+ f,
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()