File size: 3,957 Bytes
a87079f
 
 
 
 
 
ceca54f
a87079f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ceca54f
a87079f
 
 
 
 
 
 
 
 
 
 
 
ceca54f
a87079f
 
 
 
 
 
 
 
ceca54f
 
 
 
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
import whisper
import gradio as gr
import tempfile
import os
from pathlib import Path

MODEL_SIZE = "medium"  # Switched from "small" to "medium"

class GradioSRTGenerator:
    def __init__(self):
        print(f"Loading Whisper model: {MODEL_SIZE}")
        self.model = whisper.load_model(MODEL_SIZE)
        print("Model loaded successfully")

    @staticmethod
    def format_time(seconds: float) -> str:
        """Convert seconds to SRT time format (HH:MM:SS,mmm)"""
        hours = int(seconds // 3600)
        minutes = int((seconds % 3600) // 60)
        secs = int(seconds % 60)
        millis = int((seconds - int(seconds)) * 1000)
        return f"{hours:02d}:{minutes:02d}:{secs:02d},{millis:03d}"

    def build_srt_file(self, segments, srt_path: str):
        """Write Whisper segments into an SRT file at srt_path."""
        with open(srt_path, "w", encoding="utf-8") as srt_file:
            for i, seg in enumerate(segments, start=1):
                start_time = self.format_time(seg["start"])
                end_time = self.format_time(seg["end"])
                text = seg["text"].strip()
                srt_file.write(f"{i}\n")
                srt_file.write(f"{start_time} --> {end_time}\n")
                srt_file.write(f"{text}\n\n")

    def generate_srt(self, video_path, progress=gr.Progress()):
        """
        Transcribe the uploaded video and produce an SRT file.
        Returns: (path_to_srt, status_message)
        """
        if not video_path:
            return None, "⚠️ Please upload a video first."

        try:
            progress(0.1, desc="Transcribing audio with Whisper...")
            result = self.model.transcribe(video_path, task="translate")
            progress(0.6, desc="Building SRT file...")

            # Create a temporary file to hold the SRT
            with tempfile.NamedTemporaryFile(delete=False, suffix=".srt", mode="w", encoding="utf-8") as tmp:
                srt_path = tmp.name

            # Write segments into that SRT
            self.build_srt_file(result["segments"], srt_path)
            progress(1.0, desc="βœ… SRT ready!")

            return srt_path, "βœ… Transcription complete. Download your SRT below."

        except Exception as e:
            return None, f"❌ Error during transcription: {str(e)}"


def create_ui():
    generator = GradioSRTGenerator()

    with gr.Blocks(theme=gr.themes.Base(primary_hue="blue", secondary_hue="indigo")) as app:
        gr.Markdown(
            """
            # πŸ“ Video β†’ SRT Generator (Queued)

            Only one transcription job will run at a time; additional users will be placed in a queue.
            Upload any supported video file (MP4, MOV, AVI, MKV, etc.) and click **Generate SRT**. 
            Whisper will transcribe and produce an SRT subtitle file you can download immediately.
            """
        )

        with gr.Row():
            with gr.Column():
                input_video = gr.Video(label="Upload Video")
                generate_btn = gr.Button("🎯 Generate SRT", variant="primary")
                status_text = gr.Textbox(label="Status", interactive=False, show_copy_button=True)

            with gr.Column():
                srt_download = gr.File(label="Download SRT", interactive=False, visible=False)

        # Bind the button and wrap the handler in .queue()
        generate_btn.click(
            fn=generator.generate_srt,
            inputs=[input_video],
            outputs=[srt_download, status_text],
            api_name="generate_srt"
        ).queue()  # ensures this function is queued if another request is running

    # Add a queue to the entire Blocks app with exactly 1 worker
    app.queue(concurrency_count=1, max_size=10)
    return app

app = create_ui()

if __name__ == "__main__":
    app.launch(
        server_name="0.0.0.0",  # bind to all interfaces (important for Docker)
        server_port=7860        # default Gradio port
    )