ChiBenevisamPas commited on
Commit
3d78fdd
·
verified ·
1 Parent(s): 017989c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +18 -199
app.py CHANGED
@@ -1,205 +1,24 @@
1
  import gradio as gr
2
- import moviepy.editor as mp
3
- import librosa
4
- from transformers import pipeline
5
- from concurrent.futures import ThreadPoolExecutor
6
- import tempfile
7
- import docx # To create Word documents
8
- from moviepy.video.tools.subtitles import SubtitlesClip
9
- from moviepy.editor import TextClip
10
- from pytube import YouTube # For downloading YouTube videos
11
 
12
- # Load Whisper model for speech-to-text (using smaller 'tiny' model for faster performance)
13
- asr = pipeline("automatic-speech-recognition", model="openai/whisper-tiny")
14
-
15
- # MarianMT or M2M100 for translation (multi-language)
16
- translator = pipeline("translation", model="facebook/m2m100_418M")
17
-
18
- # Store generated subtitles and translations
19
- subtitle_storage = {}
20
-
21
- # Supported languages with their codes
22
- languages = {
23
- "Persian": "fa",
24
- "French": "fr",
25
- "Spanish": "es",
26
- "German": "de",
27
- "Chinese": "zh",
28
- "Arabic": "ar",
29
- "Hindi": "hi",
30
- "Russian": "ru"
31
- }
32
-
33
- def download_video_from_link(link):
34
- """Download a video from a YouTube link and return the file path."""
35
- try:
36
- yt = YouTube(link)
37
- stream = yt.streams.filter(file_extension="mp4").first() # Downloading in mp4 format
38
- video_file = stream.download() # Download to the current directory
39
- return video_file
40
- except Exception as e:
41
- return f"Error downloading video: {e}"
42
-
43
- def transcribe_audio(chunk):
44
- """Transcribe a single audio chunk."""
45
- return asr(chunk)["text"]
46
-
47
- def add_subtitle(video):
48
- try:
49
- video_path = video if isinstance(video, str) else None
50
- if not video_path:
51
- return "No video provided!"
52
-
53
- video = mp.VideoFileClip(video_path)
54
- audio = video.audio
55
-
56
- # Extract audio to a temporary file
57
- with tempfile.NamedTemporaryFile(delete=False, suffix='.wav') as tmp_audio_file:
58
- audio.write_audiofile(tmp_audio_file.name, codec='pcm_s16le')
59
- waveform, sr = librosa.load(tmp_audio_file.name, sr=16000)
60
-
61
- # Transcribe in chunks (parallel)
62
- chunk_duration = 15 # seconds
63
- chunk_size = sr * chunk_duration
64
- chunks = [waveform[i:i + chunk_size] for i in range(0, len(waveform), chunk_size)]
65
-
66
- with ThreadPoolExecutor() as executor:
67
- transcriptions = list(executor.map(transcribe_audio, chunks))
68
-
69
- full_transcription = " ".join(transcriptions)
70
- subtitle_storage["original"] = full_transcription
71
- subtitle_storage["video_path"] = video_path
72
-
73
- return f"Subtitle added: {full_transcription[:100]}..." # Display first 100 characters
74
-
75
- except Exception as e:
76
- return f"Error in adding subtitle: {e}"
77
-
78
- def translate_subtitle(language):
79
- try:
80
- # Translate the stored subtitle
81
- original_subtitle = subtitle_storage.get("original")
82
- if not original_subtitle:
83
- return "No subtitle to translate!"
84
-
85
- # Translate using the selected language
86
- translated_subtitle = translator(
87
- original_subtitle,
88
- src_lang="en", # Source language (assuming the subtitle is in English)
89
- tgt_lang=languages[language] # Get the language code from the dropdown selection
90
- )[0]["translation_text"]
91
-
92
- subtitle_storage["translated"] = translated_subtitle # Store the translated subtitle
93
-
94
- return f"Subtitle translated to {language} successfully!"
95
 
96
- except Exception as e:
97
- return f"Error in translating subtitle: {e}"
98
-
99
- def download_word():
100
- try:
101
- # Save translated subtitles to a Word document
102
- translated_subtitle = subtitle_storage.get("translated")
103
- if not translated_subtitle:
104
- return "No translated subtitle to save!"
105
-
106
- # Prepare the document
107
- doc = docx.Document()
108
- doc.add_heading('Translated Subtitles', 0)
109
-
110
- # Create timestamps and subtitles
111
- for i in range(0, len(translated_subtitle), 50):
112
- start_time = (i // 50) * 5 # Each subtitle lasts for 5 seconds
113
- subtitle_text = translated_subtitle[i:i + 50] # Get the next 50 characters
114
-
115
- # Add a formatted string with timestamp and subtitle to the document
116
- doc.add_paragraph(f"{start_time}s - {subtitle_text}")
117
-
118
- file_path = "translated_subtitles.docx"
119
- doc.save(file_path)
120
-
121
- # Return the file for download
122
- return file_path # Return the file path to allow Gradio to serve it as a downloadable file
123
 
124
- except Exception as e:
125
- return f"Error in saving subtitles as Word: {e}"
126
-
127
- def download_video():
128
- try:
129
- original_subtitle = subtitle_storage.get("original")
130
- translated_subtitle = subtitle_storage.get("translated")
131
-
132
- if not original_subtitle or not translated_subtitle:
133
- return "No subtitles to overlay on video!"
134
-
135
- video_path = subtitle_storage.get("video_path")
136
- video = mp.VideoFileClip(video_path)
137
 
138
- # Generate subtitle text without ImageMagick (using TextClip with a basic font)
139
- generator = lambda txt: TextClip(txt, font="Arial-Bold", fontsize=24, color="white", method='label') # Use 'label'
140
-
141
- subs = []
142
- subtitle_length = 5 # seconds each subtitle will be displayed
143
- for i in range(0, len(translated_subtitle), 50):
144
- start_time = (i // 50) * subtitle_length
145
- end_time = start_time + subtitle_length # Each subtitle lasts for 'subtitle_length' seconds
146
- subtitle_text = translated_subtitle[i:i + 50]
147
- subs.append(((start_time, end_time), subtitle_text))
148
-
149
- subtitles = SubtitlesClip(subs, generator)
150
-
151
- subtitled_video = mp.CompositeVideoClip([video, subtitles.set_position(('center', 'bottom'))])
152
-
153
- output_video_path = "subtitled_video.mp4"
154
- subtitled_video.write_videofile(output_video_path)
155
-
156
- return f"Subtitled video is ready for download: {output_video_path}"
157
-
158
- except Exception as e:
159
- return f"Error in generating subtitled video: {e}"
160
-
161
- # Gradio UI Interface
162
- with gr.Blocks() as demo:
163
- # Title
164
- gr.Markdown("<h1 style='text-align: center;'>Video Subtitle Translator</h1>")
165
-
166
- # Video Upload or URL Input
167
- with gr.Row():
168
- video_input = gr.Video(label="Upload Video")
169
- video_url_input = gr.Textbox(label="Or Enter Video URL")
170
- download_video_button = gr.Button("Download Video from URL")
171
- download_status = gr.Textbox(label="Download Status")
172
-
173
- download_video_button.click(download_video_from_link, inputs=video_url_input, outputs=download_status)
174
-
175
- # Add Subtitle
176
- with gr.Row():
177
- add_subtitle_button = gr.Button("Add Subtitle")
178
- subtitle_status = gr.Textbox(label="Subtitle Status")
179
-
180
- add_subtitle_button.click(add_subtitle, inputs=video_input, outputs=subtitle_status)
181
-
182
- # Translate Subtitle
183
- with gr.Row():
184
- language_dropdown = gr.Dropdown(choices=list(languages.keys()), label="Choose Target Language", value="Persian")
185
- translate_button = gr.Button("Translate Subtitle")
186
- translate_status = gr.Textbox(label="Translation Status")
187
-
188
- translate_button.click(translate_subtitle, inputs=language_dropdown, outputs=translate_status) # Update inputs
189
-
190
- # Download as Word
191
- with gr.Row():
192
- download_word_button = gr.Button("Download as Word") # Renamed the button to avoid conflict
193
- download_word_status = gr.File(label="Download Translated Word File") # File output for Word download
194
-
195
- download_word_button.click(download_word, inputs=None, outputs=download_word_status)
196
-
197
- # Download Subtitled Video
198
- with gr.Row():
199
- download_video_button2 = gr.Button("Download Subtitled Video") # Renamed the button to avoid conflict
200
- download_video_status = gr.Textbox(label="Download Video Status")
201
-
202
- download_video_button2.click(download_video, inputs=None, outputs=download_video_status)
203
 
204
- # Launch the Gradio app
205
- demo.launch()
 
1
  import gradio as gr
2
+ from moviepy.editor import VideoFileClip
 
 
 
 
 
 
 
 
3
 
4
+ # Function to process and return the video
5
+ def display_video(video_file):
6
+ # Load the video using MoviePy (optional for processing)
7
+ clip = VideoFileClip(video_file)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
 
9
+ # Optionally, you can print video details or process it
10
+ print(f"Duration: {clip.duration} seconds")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
 
12
+ # Return the video file to be displayed in Gradio
13
+ return video_file
 
 
 
 
 
 
 
 
 
 
 
14
 
15
+ # Create the Gradio interface
16
+ interface = gr.Interface(
17
+ fn=display_video,
18
+ inputs=gr.Video(label="Upload your video"),
19
+ outputs=gr.Video(label="Uploaded Video"),
20
+ title="Video Uploader",
21
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
 
23
+ # Launch the interface
24
+ interface.launch()