simar007 commited on
Commit
03eb660
·
verified ·
1 Parent(s): ade8359

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +113 -62
app.py CHANGED
@@ -3,90 +3,141 @@ import whisper
3
  import os
4
  import yt_dlp
5
 
6
- # Load Whisper model
7
- model = whisper.load_model("base")
8
-
9
- # Load summarization model
10
- summarizer = pipeline("summarization", model="facebook/bart-large-cnn")
11
 
12
  def download_youtube_audio(url):
13
- yt = YouTube(url)
14
- audio = yt.streams.filter(only_audio=True).first()
15
- out_file = audio.download(filename="temp_audio")
16
- base, ext = os.path.splitext(out_file)
17
- audio_file = base + '.mp3'
18
- os.rename(out_file, audio_file)
19
- return audio_file
 
 
 
 
 
 
 
 
 
 
 
 
20
 
21
- def transcribe_and_summarize(youtube_url=None, video_file=None):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  try:
23
- # Get audio file
24
- if youtube_url:
25
  audio_path = download_youtube_audio(youtube_url)
26
- elif video_file:
 
27
  audio_path = video_file
28
  else:
29
- return "Please provide a YouTube URL or upload a video file."
30
 
31
- # Transcribe
32
- result = model.transcribe(audio_path)
33
  transcription = result["text"]
34
 
35
- # Summarize (split into chunks if too long)
36
- max_chunk = 1024
37
- text_chunks = [transcription[i:i+max_chunk] for i in range(0, len(transcription), max_chunk)]
38
- summaries = []
39
 
40
- for chunk in text_chunks[:3]: # Limit to first 3 chunks
41
- summary = summarizer(chunk, max_length=130, min_length=30, do_sample=False)
42
- summaries.append(summary[0]['summary_text'])
43
 
44
- summary = " ".join(summaries)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
 
46
- # Create downloadable text file
47
- output_text = f"TRANSCRIPTION:\n{'='*50}\n\n{transcription}\n\n\nSUMMARY:\n{'='*50}\n\n{summary}"
 
48
 
49
- # Clean up
50
- if youtube_url and os.path.exists(audio_path):
51
- os.remove(audio_path)
 
 
52
 
53
- return transcription, summary, output_text
 
54
 
55
  except Exception as e:
56
- return f"Error: {str(e)}", "", ""
 
 
57
 
58
- # Create Gradio interface
59
- with gr.Blocks(theme=gr.themes.Soft()) as demo:
60
- gr.Markdown("# 🎥 Video Transcription & Summary Generator")
61
- gr.Markdown("Upload a video or paste a YouTube link to get AI-powered transcription and summary")
62
-
63
- with gr.Tab("YouTube Link"):
64
- youtube_input = gr.Textbox(label="YouTube URL", placeholder="https://www.youtube.com/watch?v=...")
65
- youtube_btn = gr.Button("Process YouTube Video", variant="primary")
66
-
67
- with gr.Tab("Upload Video"):
68
- video_input = gr.Video(label="Upload Video File")
69
- upload_btn = gr.Button("Process Uploaded Video", variant="primary")
70
 
71
  with gr.Row():
72
  with gr.Column():
73
- transcription_output = gr.Textbox(label="Full Transcription", lines=10)
 
 
 
 
 
 
 
 
 
74
  with gr.Column():
75
- summary_output = gr.Textbox(label="AI Summary", lines=10)
76
-
77
- download_output = gr.File(label="Download Transcript")
78
-
79
- # Event handlers
80
- youtube_btn.click(
81
- fn=lambda url: transcribe_and_summarize(youtube_url=url),
82
- inputs=youtube_input,
83
- outputs=[transcription_output, summary_output, download_output]
84
- )
85
 
86
- upload_btn.click(
87
- fn=lambda video: transcribe_and_summarize(video_file=video),
88
- inputs=video_input,
89
- outputs=[transcription_output, summary_output, download_output]
90
  )
91
 
92
- demo.launch()
 
 
3
  import os
4
  import yt_dlp
5
 
6
+ # Load smaller Whisper model to save memory
7
+ print("Loading Whisper model...")
8
+ model = whisper.load_model("tiny")
 
 
9
 
10
  def download_youtube_audio(url):
11
+ """Download audio from YouTube using yt-dlp"""
12
+ try:
13
+ ydl_opts = {
14
+ 'format': 'bestaudio/best',
15
+ 'postprocessors': [{
16
+ 'key': 'FFmpegExtractAudio',
17
+ 'preferredcodec': 'mp3',
18
+ 'preferredquality': '192',
19
+ }],
20
+ 'outtmpl': 'temp_audio.%(ext)s',
21
+ 'quiet': True,
22
+ }
23
+
24
+ with yt_dlp.YoutubeDL(ydl_opts) as ydl:
25
+ ydl.download([url])
26
+
27
+ return "temp_audio.mp3"
28
+ except Exception as e:
29
+ raise Exception(f"Failed to download YouTube video: {str(e)}")
30
 
31
+ def simple_summarize(text, max_sentences=5):
32
+ """Simple extractive summary"""
33
+ sentences = text.replace('!', '.').replace('?', '.').split('.')
34
+ sentences = [s.strip() for s in sentences if len(s.strip()) > 20]
35
+
36
+ if len(sentences) <= max_sentences:
37
+ return '. '.join(sentences) + '.'
38
+
39
+ summary_sentences = [sentences[0]]
40
+ step = len(sentences) // (max_sentences - 1)
41
+
42
+ for i in range(1, max_sentences):
43
+ idx = min(i * step, len(sentences) - 1)
44
+ summary_sentences.append(sentences[idx])
45
+
46
+ return '. '.join(summary_sentences) + '.'
47
+
48
+ def transcribe_video(youtube_url, video_file, progress=gr.Progress()):
49
+ """Main transcription function"""
50
+ audio_path = None
51
+
52
  try:
53
+ if youtube_url and youtube_url.strip():
54
+ progress(0.2, desc="Downloading YouTube audio...")
55
  audio_path = download_youtube_audio(youtube_url)
56
+ elif video_file is not None:
57
+ progress(0.2, desc="Processing uploaded video...")
58
  audio_path = video_file
59
  else:
60
+ return "❌ Error", "Please provide a YouTube URL or upload a video file.", "", None
61
 
62
+ progress(0.5, desc="Transcribing audio...")
63
+ result = model.transcribe(audio_path, fp16=False)
64
  transcription = result["text"]
65
 
66
+ if not transcription or len(transcription) < 10:
67
+ return "❌ Error", "Transcription failed or audio had no speech.", "", None
 
 
68
 
69
+ progress(0.8, desc="Generating summary...")
70
+ summary = simple_summarize(transcription, max_sentences=5)
 
71
 
72
+ progress(0.9, desc="Creating download file...")
73
+ output_text = f"""VIDEO TRANSCRIPTION & SUMMARY
74
+ {"="*60}
75
+
76
+ FULL TRANSCRIPTION:
77
+ {transcription}
78
+
79
+ {"="*60}
80
+
81
+ SUMMARY:
82
+ {summary}
83
+
84
+ {"="*60}
85
+ Generated by Video Transcription App
86
+ """
87
 
88
+ output_file = "transcript_output.txt"
89
+ with open(output_file, "w", encoding="utf-8") as f:
90
+ f.write(output_text)
91
 
92
+ if youtube_url and audio_path and os.path.exists(audio_path):
93
+ try:
94
+ os.remove(audio_path)
95
+ except:
96
+ pass
97
 
98
+ progress(1.0, desc="Done!")
99
+ return "✅ Success", transcription, summary, output_file
100
 
101
  except Exception as e:
102
+ error_msg = f"Error: {str(e)}"
103
+ print(error_msg)
104
+ return "❌ Error", error_msg, "", None
105
 
106
+ with gr.Blocks(theme=gr.themes.Soft(), title="Video Transcription") as demo:
107
+ gr.Markdown("""
108
+ # 🎥 Video Transcription & Summary Generator
109
+ Upload a video file or paste a YouTube link to get AI-powered transcription and summary.
110
+ """)
 
 
 
 
 
 
 
111
 
112
  with gr.Row():
113
  with gr.Column():
114
+ gr.Markdown("### Input")
115
+ youtube_input = gr.Textbox(
116
+ label="YouTube URL (Optional)",
117
+ placeholder="https://www.youtube.com/watch?v=...",
118
+ lines=1
119
+ )
120
+ gr.Markdown("**OR**")
121
+ video_input = gr.Video(label="Upload Video File (Optional)")
122
+ process_btn = gr.Button("🚀 Process Video", variant="primary", size="lg")
123
+
124
  with gr.Column():
125
+ gr.Markdown("### Output")
126
+ status_output = gr.Textbox(label="Status", interactive=False)
127
+
128
+ with gr.Accordion("Full Transcription", open=True):
129
+ transcription_output = gr.Textbox(label="", lines=10, show_copy_button=True)
130
+
131
+ with gr.Accordion("Summary", open=True):
132
+ summary_output = gr.Textbox(label="", lines=5, show_copy_button=True)
133
+
134
+ download_output = gr.File(label="📥 Download Complete Transcript")
135
 
136
+ process_btn.click(
137
+ fn=transcribe_video,
138
+ inputs=[youtube_input, video_input],
139
+ outputs=[status_output, transcription_output, summary_output, download_output]
140
  )
141
 
142
+ if __name__ == "__main__":
143
+ demo.launch()