File size: 6,533 Bytes
c9612c1
 
a5ff31f
c9612c1
e70c3e8
73c9093
be55105
 
 
 
c9612c1
be55105
 
c9612c1
 
 
 
be55105
 
 
38fcd18
 
 
 
 
 
 
 
 
 
 
 
e70c3e8
 
 
 
be55105
0e83a05
be55105
 
 
 
0e83a05
 
 
 
be55105
58f4eed
be55105
 
73c9093
be55105
73c9093
be55105
73c9093
 
 
 
5ebcbb6
be55105
 
 
 
c9612c1
be55105
 
c9612c1
be55105
 
 
 
 
 
 
 
 
 
 
0e83a05
c9612c1
be55105
 
 
0e83a05
 
be55105
c9612c1
be55105
0e83a05
be55105
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0e83a05
be55105
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
import gradio as gr
import moviepy.editor as mp
import librosa
from transformers import pipeline
from concurrent.futures import ThreadPoolExecutor
import tempfile
import docx  # To create Word documents
from moviepy.video.tools.subtitles import SubtitlesClip
from moviepy.editor import TextClip
import os

# Load Whisper model for speech-to-text (using smaller 'tiny' model for faster performance)
asr = pipeline("automatic-speech-recognition", model="openai/whisper-tiny")  # Use 'whisper-tiny' for faster transcription

# MarianMT or M2M100 for translation (multi-language)
translator = pipeline("translation", model="facebook/m2m100_418M")

# Store generated subtitles and translations
subtitle_storage = {}

# Supported languages with their codes
languages = {
    "Persian (fa)": "fa",
    "French (fr)": "fr",
    "Spanish (es)": "es",
    "German (de)": "de",
    "Chinese (zh)": "zh",
    "Arabic (ar)": "ar",
    "Hindi (hi)": "hi",
    "Russian (ru)": "ru"
}

def transcribe_audio(chunk):
    """Transcribe a single audio chunk."""
    return asr(chunk)["text"]

def add_subtitle(video):
    try:
        # Load video and extract audio for processing
        video_path = video.name if video else None
        if not video_path:
            return "No video provided!"
        
        video = mp.VideoFileClip(video_path)
        audio = video.audio

        # Use a temporary file for audio extraction
        with tempfile.NamedTemporaryFile(delete=True, suffix='.wav') as tmp_audio_file:
            audio.write_audiofile(tmp_audio_file.name, codec='pcm_s16le')
            waveform, sr = librosa.load(tmp_audio_file.name, sr=16000)

            # Transcribe in chunks (parallel)
            chunk_duration = 15  # seconds
            chunk_size = sr * chunk_duration
            chunks = [waveform[i:i + chunk_size] for i in range(0, len(waveform), chunk_size) if len(waveform[i:i + chunk_size]) > 0]

            with ThreadPoolExecutor() as executor:
                transcriptions = list(executor.map(transcribe_audio, chunks))

            full_transcription = " ".join(transcriptions)
            subtitle_storage["original"] = full_transcription  # Store the original subtitle
            
        return f"Subtitle added: {full_transcription[:100]}..."  # Display first 100 characters

    except Exception as e:
        return f"Error in adding subtitle: {e}"

def translate_subtitle(video):
    try:
        # Translate the stored subtitle
        original_subtitle = subtitle_storage.get("original")
        if not original_subtitle:
            return "No subtitle to translate!"
        
        translated_subtitle = translator(
            original_subtitle, 
            src_lang="en",  # Source language (assuming the subtitle is in English)
            tgt_lang=languages["Persian (fa)"]  # Set to the target language, here Persian
        )[0]["translation_text"]

        subtitle_storage["translated"] = translated_subtitle  # Store the translated subtitle
        
        return "Subtitle translated successfully!"
    
    except Exception as e:
        return f"Error in translating subtitle: {e}"

def download_word():
    try:
        # Save translated subtitles to a Word document
        translated_subtitle = subtitle_storage.get("translated")
        if not translated_subtitle:
            return "No translated subtitle to save!"
        
        doc = docx.Document()
        doc.add_heading('Translated Subtitles', 0)
        doc.add_paragraph(translated_subtitle)
        
        file_path = "translated_subtitles.docx"
        doc.save(file_path)

        return f"Translated subtitles saved as Word document: {file_path}"
    
    except Exception as e:
        return f"Error in saving subtitles as Word: {e}"

def download_video():
    try:
        # Add subtitles to the video
        original_subtitle = subtitle_storage.get("original")
        translated_subtitle = subtitle_storage.get("translated")

        if not original_subtitle or not translated_subtitle:
            return "No subtitles to overlay on video!"

        video_path = subtitle_storage.get("video_path")
        video = mp.VideoFileClip(video_path)

        # Function to generate subtitle text
        generator = lambda txt: TextClip(txt, font='Arial', fontsize=24, color='white')

        # Simulated subtitle time intervals for simplicity
        subs = [(i * 5, i * 5 + 5, translated_subtitle[i:i+50]) for i in range(0, len(translated_subtitle), 50)]

        # Create subtitle clips
        subtitles = SubtitlesClip(subs, generator)

        # Overlay subtitles on video
        subtitled_video = mp.CompositeVideoClip([video, subtitles.set_position(('center', 'bottom'))])

        output_video_path = "subtitled_video.mp4"
        subtitled_video.write_videofile(output_video_path)

        return f"Subtitled video is ready for download: {output_video_path}"
    
    except Exception as e:
        return f"Error in generating subtitled video: {e}"

# Gradio UI Interface
with gr.Blocks() as demo:
    # Title
    gr.Markdown("<h1 style='text-align: center;'>Video Subtitle Translator</h1>")
    
    # Video Upload
    with gr.Row():
        video_input = gr.Video(label="Upload Video")
        upload_button = gr.Button("Upload Video")
        upload_status = gr.Textbox(label="Upload Status")
    
    upload_button.click(add_subtitle, inputs=video_input, outputs=upload_status)
    
    # Add Subtitle
    with gr.Row():
        add_subtitle_button = gr.Button("Add Subtitle")
        subtitle_status = gr.Textbox(label="Subtitle Status")
    
    add_subtitle_button.click(add_subtitle, inputs=video_input, outputs=subtitle_status)
    
    # Translate Subtitle
    with gr.Row():
        translate_button = gr.Button("Translate Subtitle")
        translate_status = gr.Textbox(label="Translation Status")
    
    translate_button.click(translate_subtitle, inputs=video_input, outputs=translate_status)
    
    # Download as Word
    with gr.Row():
        download_button = gr.Button("Download as Word")
        download_status = gr.Textbox(label="Download Status")
    
    download_button.click(download_word, inputs=None, outputs=download_status)
    
    # Download Subtitled Video
    with gr.Row():
        download_video_button = gr.Button("Download Subtitled Video")
        download_video_status = gr.Textbox(label="Download Video Status")
    
    download_video_button.click(download_video, inputs=None, outputs=download_video_status)

# Launch the Gradio app
demo.launch()