File size: 4,685 Bytes
f2cbb62
 
 
78f752c
f2cbb62
03eb660
 
 
f2cbb62
 
03eb660
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f2cbb62
03eb660
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f2cbb62
03eb660
 
f2cbb62
03eb660
 
f2cbb62
 
03eb660
f2cbb62
03eb660
 
f2cbb62
 
03eb660
 
f2cbb62
03eb660
 
f2cbb62
03eb660
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f2cbb62
03eb660
 
 
f2cbb62
03eb660
 
 
 
 
f2cbb62
03eb660
 
f2cbb62
 
03eb660
 
 
f2cbb62
b575f03
03eb660
 
 
 
f2cbb62
 
 
03eb660
 
 
 
 
 
 
 
 
 
f2cbb62
03eb660
 
 
 
b575f03
03eb660
 
b575f03
03eb660
 
f2cbb62
03eb660
 
 
 
f2cbb62
 
b575f03
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
import gradio as gr
import whisper
import os
import yt_dlp

# Load smaller Whisper model to save memory
print("Loading Whisper model...")
model = whisper.load_model("tiny")

def download_youtube_audio(url):
    """Download audio from YouTube using yt-dlp"""
    try:
        ydl_opts = {
            'format': 'bestaudio/best',
            'postprocessors': [{
                'key': 'FFmpegExtractAudio',
                'preferredcodec': 'mp3',
                'preferredquality': '192',
            }],
            'outtmpl': 'temp_audio.%(ext)s',
            'quiet': True,
        }
        
        with yt_dlp.YoutubeDL(ydl_opts) as ydl:
            ydl.download([url])
        
        return "temp_audio.mp3"
    except Exception as e:
        raise Exception(f"Failed to download YouTube video: {str(e)}")

def simple_summarize(text, max_sentences=5):
    """Simple extractive summary"""
    sentences = text.replace('!', '.').replace('?', '.').split('.')
    sentences = [s.strip() for s in sentences if len(s.strip()) > 20]
    
    if len(sentences) <= max_sentences:
        return '. '.join(sentences) + '.'
    
    summary_sentences = [sentences[0]]
    step = len(sentences) // (max_sentences - 1)
    
    for i in range(1, max_sentences):
        idx = min(i * step, len(sentences) - 1)
        summary_sentences.append(sentences[idx])
    
    return '. '.join(summary_sentences) + '.'

def transcribe_video(youtube_url, video_file, progress=gr.Progress()):
    """Main transcription function"""
    audio_path = None
    
    try:
        if youtube_url and youtube_url.strip():
            progress(0.2, desc="Downloading YouTube audio...")
            audio_path = download_youtube_audio(youtube_url)
        elif video_file is not None:
            progress(0.2, desc="Processing uploaded video...")
            audio_path = video_file
        else:
            return "❌ Error", "Please provide a YouTube URL or upload a video file.", "", None
        
        progress(0.5, desc="Transcribing audio...")
        result = model.transcribe(audio_path, fp16=False)
        transcription = result["text"]
        
        if not transcription or len(transcription) < 10:
            return "❌ Error", "Transcription failed or audio had no speech.", "", None
        
        progress(0.8, desc="Generating summary...")
        summary = simple_summarize(transcription, max_sentences=5)
        
        progress(0.9, desc="Creating download file...")
        output_text = f"""VIDEO TRANSCRIPTION & SUMMARY
{"="*60}

FULL TRANSCRIPTION:
{transcription}

{"="*60}

SUMMARY:
{summary}

{"="*60}
Generated by Video Transcription App
"""
        
        output_file = "transcript_output.txt"
        with open(output_file, "w", encoding="utf-8") as f:
            f.write(output_text)
        
        if youtube_url and audio_path and os.path.exists(audio_path):
            try:
                os.remove(audio_path)
            except:
                pass
        
        progress(1.0, desc="Done!")
        return "βœ… Success", transcription, summary, output_file
        
    except Exception as e:
        error_msg = f"Error: {str(e)}"
        print(error_msg)
        return "❌ Error", error_msg, "", None

with gr.Blocks(title="Video Transcription") as demo:
    gr.Markdown("""
    # πŸŽ₯ Video Transcription & Summary Generator
    Upload a video file or paste a YouTube link to get AI-powered transcription and summary.
    """)
    
    with gr.Row():
        with gr.Column():
            gr.Markdown("### Input")
            youtube_input = gr.Textbox(
                label="YouTube URL (Optional)",
                placeholder="https://www.youtube.com/watch?v=...",
                lines=1
            )
            gr.Markdown("**OR**")
            video_input = gr.Video(label="Upload Video File (Optional)")
            process_btn = gr.Button("πŸš€ Process Video", variant="primary", size="lg")
        
        with gr.Column():
            gr.Markdown("### Output")
            status_output = gr.Textbox(label="Status", interactive=False)
            
            with gr.Accordion("Full Transcription", open=True):
                transcription_output = gr.Textbox(label="", lines=10, max_lines=20)
            
            with gr.Accordion("Summary", open=True):
                summary_output = gr.Textbox(label="", lines=5)
            
            download_output = gr.File(label="πŸ“₯ Download Complete Transcript")
    
    process_btn.click(
        fn=transcribe_video,
        inputs=[youtube_input, video_input],
        outputs=[status_output, transcription_output, summary_output, download_output]
    )

demo.launch()