abdullah637 commited on
Commit
50f5d61
·
verified ·
1 Parent(s): 7fa527d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +71 -49
app.py CHANGED
@@ -1,24 +1,25 @@
 
1
  import gradio as gr
2
  from moviepy.editor import VideoFileClip
3
- import os
4
  import whisper
5
  import torch
 
 
6
  from transformers import M2M100ForConditionalGeneration, M2M100Tokenizer
 
7
 
8
- # Load Whisper model (use 'small' for faster transcription)
9
- model = whisper.load_model("small")
10
 
11
  # Load M2M-100 model & tokenizer
12
- m2m_model_name = "facebook/m2m100_418M" # Use "facebook/m2m100_1.2B" for better accuracy
13
  tokenizer = M2M100Tokenizer.from_pretrained(m2m_model_name)
14
  translator_model = M2M100ForConditionalGeneration.from_pretrained(m2m_model_name)
15
 
16
- # Move model to GPU if available
17
  device = "cuda" if torch.cuda.is_available() else "cpu"
18
  translator_model.to(device)
19
 
20
- # Supported languages for translation (must match M2M-100 language codes)
21
  TRANSLATION_LANGUAGES = {
 
22
  "Urdu": "ur",
23
  "French": "fr",
24
  "Spanish": "es",
@@ -29,77 +30,98 @@ TRANSLATION_LANGUAGES = {
29
  }
30
 
31
  def translate_text_m2m(text_list, target_lang):
32
- """ Translates a list of English texts into the target language using M2M-100. """
33
- tokenizer.src_lang = "en"
 
34
 
35
- # Tokenize and translate in batches
36
  inputs = tokenizer(text_list, return_tensors="pt", padding=True, truncation=True).to(device)
37
  outputs = translator_model.generate(**inputs, forced_bos_token_id=tokenizer.get_lang_id(target_lang))
38
 
39
- # Decode output
40
- translated_texts = tokenizer.batch_decode(outputs, skip_special_tokens=True)
41
- return translated_texts
42
 
43
  def generate_translated_subtitles(video_path, target_language):
44
- # Extract audio from video
45
  video = VideoFileClip(video_path)
46
  audio_path = "temp_audio.wav"
47
  video.audio.write_audiofile(audio_path)
48
 
49
- # Transcribe (without translation) using Whisper
50
  result = model.transcribe(audio_path, language="en")
51
-
52
- # Clean up temporary audio file
53
  os.remove(audio_path)
54
 
55
- # Extract all subtitle texts for batch translation
56
  texts = [segment['text'] for segment in result['segments']]
57
-
58
- # Translate using M2M-100
59
  translated_texts = translate_text_m2m(texts, TRANSLATION_LANGUAGES[target_language])
60
 
61
- # Format subtitles in .srt format
62
- srt_content = ""
63
- for index, (segment, translated_text) in enumerate(zip(result['segments'], translated_texts)):
64
- start_time = segment['start']
65
- end_time = segment['end']
66
-
67
- # Convert seconds to SRT time format (HH:MM:SS,mmm)
68
- def format_time(seconds):
69
- hours = int(seconds // 3600)
70
- minutes = int((seconds % 3600) // 60)
71
- seconds = seconds % 60
72
- milliseconds = int((seconds - int(seconds)) * 1000)
73
- return f"{hours:02}:{minutes:02}:{int(seconds):02},{milliseconds:03}"
74
-
75
- srt_content += f"{index + 1}\n"
76
- srt_content += f"{format_time(start_time)} --> {format_time(end_time)}\n"
77
- srt_content += f"{translated_text}\n\n"
78
-
79
- # Save the .srt file
80
  srt_filename = f"subtitles_{TRANSLATION_LANGUAGES.get(target_language, 'en')}.srt"
81
- with open(srt_filename, "w", encoding="utf-8") as srt_file:
82
- srt_file.write(srt_content)
83
 
84
- return srt_content, srt_filename
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
 
86
 
87
- def video_to_translated_subtitles(video, target_language):
88
- subtitles, srt_filename = generate_translated_subtitles(video, target_language)
89
- return subtitles, srt_filename # Return translated subtitles and file path
 
 
 
 
90
 
91
  iface = gr.Interface(
92
  fn=video_to_translated_subtitles,
93
  inputs=[
94
  gr.Video(label="Upload English Video"),
95
- gr.Dropdown(choices=list(TRANSLATION_LANGUAGES.keys()), label="Translate to", value="Urdu")
 
96
  ],
97
  outputs=[
98
- gr.Textbox(label="Translated Subtitles", lines=10),
99
- gr.DownloadButton(label="Download .srt File")
100
  ],
101
- title="Video to Translated Subtitles (Offline M2M-100)",
102
- description="Upload an English video, select a language, and get translated subtitles offline."
103
  )
104
 
105
  iface.launch(share=True)
 
1
+ import os
2
  import gradio as gr
3
  from moviepy.editor import VideoFileClip
 
4
  import whisper
5
  import torch
6
+ import subprocess
7
+ import shutil
8
  from transformers import M2M100ForConditionalGeneration, M2M100Tokenizer
9
+ import whisper
10
 
11
+ model = whisper.load_model("base")
 
12
 
13
  # Load M2M-100 model & tokenizer
14
+ m2m_model_name = "facebook/m2m100_418M"
15
  tokenizer = M2M100Tokenizer.from_pretrained(m2m_model_name)
16
  translator_model = M2M100ForConditionalGeneration.from_pretrained(m2m_model_name)
17
 
 
18
  device = "cuda" if torch.cuda.is_available() else "cpu"
19
  translator_model.to(device)
20
 
 
21
  TRANSLATION_LANGUAGES = {
22
+ "English (No Translation)": "en",
23
  "Urdu": "ur",
24
  "French": "fr",
25
  "Spanish": "es",
 
30
  }
31
 
32
  def translate_text_m2m(text_list, target_lang):
33
+ """Translates a list of English texts into the target language using M2M-100."""
34
+ if target_lang == "en":
35
+ return text_list # No translation needed
36
 
37
+ tokenizer.src_lang = "en"
38
  inputs = tokenizer(text_list, return_tensors="pt", padding=True, truncation=True).to(device)
39
  outputs = translator_model.generate(**inputs, forced_bos_token_id=tokenizer.get_lang_id(target_lang))
40
 
41
+ return tokenizer.batch_decode(outputs, skip_special_tokens=True)
 
 
42
 
43
  def generate_translated_subtitles(video_path, target_language):
44
+ """Extracts audio, transcribes it with Whisper, translates subtitles, and saves an SRT file."""
45
  video = VideoFileClip(video_path)
46
  audio_path = "temp_audio.wav"
47
  video.audio.write_audiofile(audio_path)
48
 
49
+ # Transcribe with Whisper
50
  result = model.transcribe(audio_path, language="en")
 
 
51
  os.remove(audio_path)
52
 
 
53
  texts = [segment['text'] for segment in result['segments']]
 
 
54
  translated_texts = translate_text_m2m(texts, TRANSLATION_LANGUAGES[target_language])
55
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
  srt_filename = f"subtitles_{TRANSLATION_LANGUAGES.get(target_language, 'en')}.srt"
 
 
57
 
58
+ # UTF-8 encoding
59
+ with open(srt_filename, "w", encoding="utf-8-sig") as srt_file:
60
+ for index, (segment, translated_text) in enumerate(zip(result['segments'], translated_texts)):
61
+ start_time, end_time = segment['start'], segment['end']
62
+
63
+ def format_time(seconds):
64
+ hours = int(seconds // 3600)
65
+ minutes = int((seconds % 3600) // 60)
66
+ seconds = seconds % 60
67
+ milliseconds = int((seconds - int(seconds)) * 1000)
68
+ return f"{hours:02}:{minutes:02}:{int(seconds):02},{milliseconds:03}"
69
+
70
+ srt_file.write(f"{index + 1}\n")
71
+ srt_file.write(f"{format_time(start_time)} --> {format_time(end_time)}\n")
72
+ srt_file.write(f"{translated_text}\n\n")
73
+
74
+ return srt_filename
75
+
76
+ def burn_subtitles_on_video(video_path, srt_path):
77
+ """Uses ffmpeg to burn subtitles into the video."""
78
+ new_video_path = "input_video.mp4"
79
+ new_srt_path = "subtitles.srt"
80
+ output_video = "video_with_subtitles.mp4"
81
+
82
+ shutil.copy(video_path, new_video_path)
83
+ shutil.copy(srt_path, new_srt_path)
84
+
85
+ command = [
86
+ "ffmpeg",
87
+ "-y",
88
+ "-i", "input_video.mp4",
89
+ "-vf", "subtitles=subtitles.srt:force_style='Fontfile=/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf,Fontsize=24,PrimaryColour=&HFFFFFF&'",
90
+ "-c:a", "copy",
91
+ "video_with_subtitles.mp4"
92
+ ]
93
+
94
+
95
+ try:
96
+ result = subprocess.run(command, check=True, capture_output=True, text=True)
97
+ print("FFmpeg Output:", result.stdout)
98
+ print("FFmpeg Error:", result.stderr)
99
+ return output_video
100
+ except subprocess.CalledProcessError as e:
101
+ print("FFmpeg Error:", e.stderr)
102
+ return None
103
 
104
 
105
+ def video_to_translated_subtitles(video, target_language, output_type):
106
+ """Processes video: generates subtitles, translates (if needed), burns subtitles, and returns files."""
107
+ srt_filename = generate_translated_subtitles(video, target_language)
108
+ if output_type == "SRT File":
109
+ return srt_filename
110
+ burned_video = burn_subtitles_on_video(video, srt_filename)
111
+ return burned_video
112
 
113
  iface = gr.Interface(
114
  fn=video_to_translated_subtitles,
115
  inputs=[
116
  gr.Video(label="Upload English Video"),
117
+ gr.Dropdown(choices=list(TRANSLATION_LANGUAGES.keys()), label="Translate to", value="English (No Translation)"),
118
+ gr.Radio(["SRT File", "Burned-in Subtitles"], label="Select Output Type"),
119
  ],
120
  outputs=[
121
+ gr.DownloadButton(label="Download File"),
 
122
  ],
123
+ title="Video to Subtitles (With Translation)",
124
+ description="Upload an English video, and get subtitles in your desired language."
125
  )
126
 
127
  iface.launch(share=True)