AnalysisWithMSR commited on
Commit
9823a49
·
verified ·
1 Parent(s): adbbdc0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +87 -57
app.py CHANGED
@@ -1,21 +1,25 @@
1
- import os
2
- import gradio as gr
3
  import yt_dlp
4
  import whisper
5
  from pydub import AudioSegment
 
6
  from transformers import pipeline
7
  from youtube_transcript_api import YouTubeTranscriptApi
8
- from urllib.parse import urlparse, parse_qs
9
  import openai
10
  import json
11
- import tempfile
12
- import re
13
- import torch
14
- from googleapiclient.discovery import build # Add the import for Google API client
15
 
 
 
 
 
16
 
17
- # Function to extract YouTube video ID
18
  def extract_video_id(url):
 
19
  try:
20
  parsed_url = urlparse(url)
21
  if "youtube.com" in parsed_url.netloc:
@@ -23,15 +27,15 @@ def extract_video_id(url):
23
  return query_params.get('v', [None])[0]
24
  elif "youtu.be" in parsed_url.netloc:
25
  return parsed_url.path.strip("/")
26
- return None
27
- except Exception:
 
28
  return None
29
 
30
-
31
- # Function to get video duration
32
  def get_video_duration(video_id, api_key):
 
33
  try:
34
- youtube = build("youtube", "v3", developerKey=api_key)
35
  request = youtube.videos().list(part="contentDetails", id=video_id)
36
  response = request.execute()
37
  if response["items"]:
@@ -41,39 +45,79 @@ def get_video_duration(video_id, api_key):
41
  minutes = int(match.group(2)) if match.group(2) else 0
42
  seconds = int(match.group(3)) if match.group(3) else 0
43
  return hours * 60 + minutes + seconds / 60
 
 
 
44
  return None
45
- except Exception:
46
- return None
47
-
48
 
49
- # Download and transcribe with Whisper
50
  def download_and_transcribe_with_whisper(youtube_url):
51
  try:
52
  with tempfile.TemporaryDirectory() as temp_dir:
53
  temp_audio_file = os.path.join(temp_dir, "audio.mp3")
54
-
55
  ydl_opts = {
56
  'format': 'bestaudio/best',
57
  'outtmpl': temp_audio_file,
58
  'extractaudio': True,
 
59
  }
60
 
 
61
  with yt_dlp.YoutubeDL(ydl_opts) as ydl:
62
  ydl.download([youtube_url])
63
 
 
64
  audio = AudioSegment.from_file(temp_audio_file)
65
  wav_file = os.path.join(temp_dir, "audio.wav")
66
  audio.export(wav_file, format="wav")
67
 
 
68
  model = whisper.load_model("large")
69
  result = model.transcribe(wav_file)
70
- return result['text']
71
- except Exception:
 
 
72
  return None
73
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
 
75
- # Function to summarize using Hugging Face
76
  def summarize_text_huggingface(text):
 
77
  summarizer = pipeline("summarization", model="facebook/bart-large-cnn", device=0 if torch.cuda.is_available() else -1)
78
  max_input_length = 1024
79
  chunk_overlap = 100
@@ -87,10 +131,7 @@ def summarize_text_huggingface(text):
87
  ]
88
  return " ".join(summaries)
89
 
90
-
91
- # Function to generate optimized content with OpenAI
92
- def generate_optimized_content(api_key, summarized_transcript):
93
- openai.api_key = api_key
94
  prompt = f"""
95
  Analyze the following summarized YouTube video transcript and:
96
  1. Extract the top 10 keywords.
@@ -109,6 +150,7 @@ def generate_optimized_content(api_key, summarized_transcript):
109
  "tags": ["tag1", "tag2", ..., "tag10"]
110
  }}
111
  """
 
112
  try:
113
  response = openai.ChatCompletion.create(
114
  model="gpt-3.5-turbo",
@@ -118,39 +160,27 @@ def generate_optimized_content(api_key, summarized_transcript):
118
  ]
119
  )
120
  response_content = response['choices'][0]['message']['content']
121
- return json.loads(response_content)
122
- except Exception:
123
- return None
124
-
125
 
126
- # Main Gradio function
127
- def process_video(youtube_url, youtube_api_key, openai_api_key):
128
- video_id = extract_video_id(youtube_url)
129
- if not video_id:
130
- return "Invalid YouTube URL.", "", ""
131
-
132
- video_length = get_video_duration(video_id, youtube_api_key)
133
- if not video_length:
134
- return "Error fetching video duration.", "", ""
135
-
136
- transcript = download_and_transcribe_with_whisper(youtube_url)
137
  if not transcript:
138
- return "Error fetching transcript.", "", ""
139
 
140
  summary = summarize_text_huggingface(transcript)
141
- optimized_content = generate_optimized_content(openai_api_key, summary)
142
-
143
- return summary, json.dumps(optimized_content, indent=4), transcript
144
-
145
-
146
- # Gradio Interface
147
- youtube_api_key = os.getenv("YOUTUBE_API_KEY")
148
- openai_api_key = os.getenv("OPENAI_API_KEY")
149
-
150
- gr.Interface(
151
- fn=lambda youtube_url: process_video(youtube_url, youtube_api_key, openai_api_key),
152
- inputs="text",
153
- outputs=["text", "text", "text"],
154
- title="YouTube Transcript Summarizer",
155
- description="Enter a YouTube URL to extract, summarize, and optimize content.",
156
- ).launch()
 
1
+ import googleapiclient.discovery
2
+ import re
3
  import yt_dlp
4
  import whisper
5
  from pydub import AudioSegment
6
+ import tempfile
7
  from transformers import pipeline
8
  from youtube_transcript_api import YouTubeTranscriptApi
9
+ import torch
10
  import openai
11
  import json
12
+ from urllib.parse import urlparse, parse_qs
13
+ import os
14
+ import gradio as gr
 
15
 
16
+ # Ensure your API keys are set as environment variables
17
+ youtube_api_key = os.getenv("YOUTUBE_API_KEY")
18
+ openai_api_key = os.getenv("OPENAI_API_KEY")
19
+ openai.api_key = openai_api_key
20
 
 
21
  def extract_video_id(url):
22
+ """Extracts the video ID from a YouTube URL."""
23
  try:
24
  parsed_url = urlparse(url)
25
  if "youtube.com" in parsed_url.netloc:
 
27
  return query_params.get('v', [None])[0]
28
  elif "youtu.be" in parsed_url.netloc:
29
  return parsed_url.path.strip("/")
30
+ else:
31
+ return None
32
+ except Exception as e:
33
  return None
34
 
 
 
35
  def get_video_duration(video_id, api_key):
36
+ """Fetches the video duration in minutes."""
37
  try:
38
+ youtube = googleapiclient.discovery.build("youtube", "v3", developerKey=api_key)
39
  request = youtube.videos().list(part="contentDetails", id=video_id)
40
  response = request.execute()
41
  if response["items"]:
 
45
  minutes = int(match.group(2)) if match.group(2) else 0
46
  seconds = int(match.group(3)) if match.group(3) else 0
47
  return hours * 60 + minutes + seconds / 60
48
+ else:
49
+ return None
50
+ except Exception as e:
51
  return None
 
 
 
52
 
 
53
  def download_and_transcribe_with_whisper(youtube_url):
54
  try:
55
  with tempfile.TemporaryDirectory() as temp_dir:
56
  temp_audio_file = os.path.join(temp_dir, "audio.mp3")
57
+
58
  ydl_opts = {
59
  'format': 'bestaudio/best',
60
  'outtmpl': temp_audio_file,
61
  'extractaudio': True,
62
+ 'audioquality': 1,
63
  }
64
 
65
+ # Download audio using yt-dlp
66
  with yt_dlp.YoutubeDL(ydl_opts) as ydl:
67
  ydl.download([youtube_url])
68
 
69
+ # Convert to wav for Whisper
70
  audio = AudioSegment.from_file(temp_audio_file)
71
  wav_file = os.path.join(temp_dir, "audio.wav")
72
  audio.export(wav_file, format="wav")
73
 
74
+ # Run Whisper transcription
75
  model = whisper.load_model("large")
76
  result = model.transcribe(wav_file)
77
+ transcript = result['text']
78
+ return transcript
79
+
80
+ except Exception as e:
81
  return None
82
 
83
+ def get_transcript_from_youtube_api(video_id, video_length):
84
+ """Fetches transcript using YouTube API if available."""
85
+ try:
86
+ transcript_list = YouTubeTranscriptApi.list_transcripts(video_id)
87
+
88
+ for transcript in transcript_list:
89
+ if not transcript.is_generated:
90
+ segments = transcript.fetch()
91
+ return " ".join(segment['text'] for segment in segments)
92
+
93
+ if video_length > 15:
94
+ auto_transcript = transcript_list.find_generated_transcript(['en'])
95
+ if auto_transcript:
96
+ segments = auto_transcript.fetch()
97
+ return " ".join(segment['text'] for segment in segments)
98
+
99
+ return None
100
+
101
+ except Exception as e:
102
+ return None
103
+
104
+ def get_transcript(youtube_url):
105
+ """Gets transcript from YouTube API or Whisper if unavailable."""
106
+ video_id = extract_video_id(youtube_url)
107
+ if not video_id:
108
+ return "Invalid or unsupported YouTube URL."
109
+
110
+ video_length = get_video_duration(video_id, youtube_api_key)
111
+ if video_length is not None:
112
+ transcript = get_transcript_from_youtube_api(video_id, video_length)
113
+ if transcript:
114
+ return transcript
115
+ return download_and_transcribe_with_whisper(youtube_url)
116
+ else:
117
+ return "Error fetching video duration."
118
 
 
119
  def summarize_text_huggingface(text):
120
+ """Summarizes text using a Hugging Face summarization model."""
121
  summarizer = pipeline("summarization", model="facebook/bart-large-cnn", device=0 if torch.cuda.is_available() else -1)
122
  max_input_length = 1024
123
  chunk_overlap = 100
 
131
  ]
132
  return " ".join(summaries)
133
 
134
+ def generate_optimized_content(summarized_transcript):
 
 
 
135
  prompt = f"""
136
  Analyze the following summarized YouTube video transcript and:
137
  1. Extract the top 10 keywords.
 
150
  "tags": ["tag1", "tag2", ..., "tag10"]
151
  }}
152
  """
153
+
154
  try:
155
  response = openai.ChatCompletion.create(
156
  model="gpt-3.5-turbo",
 
160
  ]
161
  )
162
  response_content = response['choices'][0]['message']['content']
163
+ content = json.loads(response_content)
164
+ return content
165
+ except Exception as e:
166
+ return {"error": str(e)}
167
 
168
+ def process_video(youtube_url):
169
+ transcript = get_transcript(youtube_url)
 
 
 
 
 
 
 
 
 
170
  if not transcript:
171
+ return "Could not fetch the transcript. Please try another video."
172
 
173
  summary = summarize_text_huggingface(transcript)
174
+ optimized_content = generate_optimized_content(summary)
175
+ return optimized_content
176
+
177
+ iface = gr.Interface(
178
+ fn=process_video,
179
+ inputs=gr.Textbox(label="Enter a YouTube video URL"),
180
+ outputs=gr.JSON(label="Optimized Content"),
181
+ title="YouTube Video Optimization Tool",
182
+ description="Enter a YouTube URL to generate optimized titles, descriptions, and tags."
183
+ )
184
+
185
+ if __name__ == "__main__":
186
+ iface.launch()