Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -16,28 +16,35 @@ key_index = 0
|
|
16 |
|
17 |
def get_api_key():
|
18 |
global key_index
|
19 |
-
# Get the current API key and increment the index
|
20 |
api_key = YOUTUBE_API_KEYS[key_index]
|
21 |
key_index = (key_index + 1) % len(YOUTUBE_API_KEYS) # Rotate to the next key
|
22 |
return api_key
|
23 |
|
24 |
-
|
25 |
-
def youtube_search(query, max_results=50):
|
26 |
search_url = "https://www.googleapis.com/youtube/v3/search"
|
27 |
all_results = []
|
28 |
params = {
|
29 |
"part": "snippet",
|
30 |
"q": query,
|
31 |
"type": "video",
|
32 |
-
"maxResults": 50
|
|
|
33 |
}
|
34 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
try:
|
36 |
while len(all_results) < max_results:
|
37 |
params["key"] = get_api_key()
|
38 |
response = requests.get(search_url, params=params)
|
39 |
|
40 |
-
if response.status_code
|
41 |
print(f"Quota exceeded or forbidden for API key. Trying next key...")
|
42 |
continue
|
43 |
response.raise_for_status()
|
@@ -60,9 +67,8 @@ def youtube_search(query, max_results=50):
|
|
60 |
|
61 |
except requests.exceptions.RequestException as e:
|
62 |
print(f"Error during YouTube API request: {e}")
|
63 |
-
return []
|
64 |
|
65 |
-
# Function to display the video using the video URL
|
66 |
def show_video(video_url):
|
67 |
video_id = None
|
68 |
patterns = [
|
@@ -84,19 +90,18 @@ def show_video(video_url):
|
|
84 |
embed_url = f"https://www.youtube.com/embed/{video_id}"
|
85 |
|
86 |
html_code = f'''
|
87 |
-
<iframe width="
|
88 |
frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
89 |
allowfullscreen></iframe>
|
90 |
'''
|
91 |
return html_code
|
92 |
|
93 |
-
# Create the Gradio interface
|
94 |
with gr.Blocks(css="""
|
95 |
#search_output {
|
96 |
-
max-width:
|
97 |
}
|
98 |
#search_output img {
|
99 |
-
width: 150px !important;
|
100 |
height: 150px !important;
|
101 |
margin-right: 10px;
|
102 |
}
|
@@ -110,50 +115,81 @@ with gr.Blocks(css="""
|
|
110 |
padding-left: 20px;
|
111 |
font-size: 24px !important;
|
112 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
113 |
""") as demo:
|
114 |
gr.Markdown("## YouTube Video Search, Selection, and Playback")
|
115 |
-
video_ids_state = gr.State()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
116 |
|
117 |
with gr.Row():
|
118 |
with gr.Column(scale=3):
|
119 |
search_query_input = gr.Textbox(label="Search YouTube",
|
120 |
placeholder="Enter your search query here",
|
121 |
-
elem_id="search_query_input")
|
|
|
|
|
|
|
|
|
122 |
search_button = gr.Button("Search")
|
123 |
search_output = gr.Gallery(label="Search Results", columns=1, height="800px", elem_id="search_output")
|
124 |
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
133 |
gallery_items = []
|
134 |
video_ids = []
|
135 |
for item in search_results:
|
136 |
image_url = item['thumbnail_url']
|
137 |
title = item['title']
|
138 |
-
caption = f"{title}"
|
139 |
gallery_items.append((image_url, caption))
|
140 |
video_ids.append(item['video_id'])
|
141 |
return gallery_items, video_ids
|
142 |
|
143 |
-
# When a video is selected
|
144 |
def on_video_select(evt: gr.SelectData, video_ids):
|
145 |
index = evt.index
|
146 |
selected_video_id = video_ids[index]
|
147 |
video_url = f"https://www.youtube.com/watch?v={selected_video_id}"
|
148 |
return video_url
|
149 |
|
150 |
-
# Play the video
|
151 |
def play_video(video_url):
|
152 |
return show_video(video_url)
|
153 |
|
154 |
-
search_button.click(update_search_results, inputs=search_query_input, outputs=[search_output, video_ids_state])
|
155 |
search_output.select(on_video_select, inputs=video_ids_state, outputs=selected_video_link)
|
156 |
play_video_button.click(play_video, inputs=selected_video_link, outputs=video_output)
|
157 |
|
158 |
-
# Launch the Gradio interface
|
159 |
demo.launch()
|
|
|
16 |
|
17 |
def get_api_key():
|
18 |
global key_index
|
|
|
19 |
api_key = YOUTUBE_API_KEYS[key_index]
|
20 |
key_index = (key_index + 1) % len(YOUTUBE_API_KEYS) # Rotate to the next key
|
21 |
return api_key
|
22 |
|
23 |
+
def youtube_search(query, upload_date, video_type, duration, sort_by, max_results=50):
|
|
|
24 |
search_url = "https://www.googleapis.com/youtube/v3/search"
|
25 |
all_results = []
|
26 |
params = {
|
27 |
"part": "snippet",
|
28 |
"q": query,
|
29 |
"type": "video",
|
30 |
+
"maxResults": 50,
|
31 |
+
"order": sort_by
|
32 |
}
|
33 |
|
34 |
+
# Add filter parameters based on user selection
|
35 |
+
if upload_date:
|
36 |
+
params["publishedAfter"] = upload_date
|
37 |
+
if video_type and video_type != "All":
|
38 |
+
params["type"] = video_type.lower() # API expects lowercase values
|
39 |
+
if duration:
|
40 |
+
params["videoDuration"] = duration # Set duration parameter for filtering
|
41 |
+
|
42 |
try:
|
43 |
while len(all_results) < max_results:
|
44 |
params["key"] = get_api_key()
|
45 |
response = requests.get(search_url, params=params)
|
46 |
|
47 |
+
if response.status_code in [403, 429]:
|
48 |
print(f"Quota exceeded or forbidden for API key. Trying next key...")
|
49 |
continue
|
50 |
response.raise_for_status()
|
|
|
67 |
|
68 |
except requests.exceptions.RequestException as e:
|
69 |
print(f"Error during YouTube API request: {e}")
|
70 |
+
return []
|
71 |
|
|
|
72 |
def show_video(video_url):
|
73 |
video_id = None
|
74 |
patterns = [
|
|
|
90 |
embed_url = f"https://www.youtube.com/embed/{video_id}"
|
91 |
|
92 |
html_code = f'''
|
93 |
+
<iframe width="100%" height="562" src="{embed_url}"
|
94 |
frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
95 |
allowfullscreen></iframe>
|
96 |
'''
|
97 |
return html_code
|
98 |
|
|
|
99 |
with gr.Blocks(css="""
|
100 |
#search_output {
|
101 |
+
max-width: 1300px;
|
102 |
}
|
103 |
#search_output img {
|
104 |
+
width: 150px !important;
|
105 |
height: 150px !important;
|
106 |
margin-right: 10px;
|
107 |
}
|
|
|
115 |
padding-left: 20px;
|
116 |
font-size: 24px !important;
|
117 |
}
|
118 |
+
#video_container {
|
119 |
+
display: flex;
|
120 |
+
justify-content: center;
|
121 |
+
align-items: center;
|
122 |
+
max-width: 1500px;
|
123 |
+
margin: 0 auto;
|
124 |
+
padding: 20px;
|
125 |
+
background-color: #f9f9f9;
|
126 |
+
border-radius: 8px;
|
127 |
+
}
|
128 |
""") as demo:
|
129 |
gr.Markdown("## YouTube Video Search, Selection, and Playback")
|
130 |
+
video_ids_state = gr.State()
|
131 |
+
|
132 |
+
with gr.Row(elem_id="video_container"):
|
133 |
+
video_output = gr.HTML(label="Video Player", elem_id="video_output")
|
134 |
+
|
135 |
+
with gr.Row():
|
136 |
+
selected_video_link = gr.Textbox(label="Selected Video Link", interactive=False)
|
137 |
+
play_video_button = gr.Button("Play Video")
|
138 |
|
139 |
with gr.Row():
|
140 |
with gr.Column(scale=3):
|
141 |
search_query_input = gr.Textbox(label="Search YouTube",
|
142 |
placeholder="Enter your search query here",
|
143 |
+
elem_id="search_query_input")
|
144 |
+
upload_date_input = gr.Dropdown(label="Upload Date", choices=["", "Last Hour", "Today", "This Week", "This Month", "This Year"])
|
145 |
+
video_type_input = gr.Dropdown(label="Type", choices=["All", "Video", "Channel", "Playlist", "Movie"])
|
146 |
+
duration_input = gr.Dropdown(label="Duration", choices=["", "Short (<4 mins)", "Medium (4-20 mins)", "Long (>20 mins)"])
|
147 |
+
sort_by_input = gr.Dropdown(label="Sort By", choices=["relevance", "date", "viewCount", "rating"], value="relevance")
|
148 |
search_button = gr.Button("Search")
|
149 |
search_output = gr.Gallery(label="Search Results", columns=1, height="800px", elem_id="search_output")
|
150 |
|
151 |
+
def update_search_results(query, upload_date, video_type, duration, sort_by):
|
152 |
+
# Map the filter values to YouTube API parameters
|
153 |
+
upload_date_mapping = {
|
154 |
+
"Last Hour": "now-1h",
|
155 |
+
"Today": "now-1d",
|
156 |
+
"This Week": "now-7d",
|
157 |
+
"This Month": "now-30d",
|
158 |
+
"This Year": "now-365d"
|
159 |
+
}
|
160 |
+
|
161 |
+
duration_mapping = {
|
162 |
+
"Short (<4 mins)": "short",
|
163 |
+
"Medium (4-20 mins)": "medium",
|
164 |
+
"Long (>20 mins)": "long"
|
165 |
+
}
|
166 |
+
|
167 |
+
# Convert user-friendly values to API-compatible parameters
|
168 |
+
upload_date_param = upload_date_mapping.get(upload_date, "")
|
169 |
+
duration_param = duration_mapping.get(duration, "")
|
170 |
+
|
171 |
+
search_results = youtube_search(query, upload_date_param, video_type, duration_param, sort_by)
|
172 |
gallery_items = []
|
173 |
video_ids = []
|
174 |
for item in search_results:
|
175 |
image_url = item['thumbnail_url']
|
176 |
title = item['title']
|
177 |
+
caption = f"{title}"
|
178 |
gallery_items.append((image_url, caption))
|
179 |
video_ids.append(item['video_id'])
|
180 |
return gallery_items, video_ids
|
181 |
|
|
|
182 |
def on_video_select(evt: gr.SelectData, video_ids):
|
183 |
index = evt.index
|
184 |
selected_video_id = video_ids[index]
|
185 |
video_url = f"https://www.youtube.com/watch?v={selected_video_id}"
|
186 |
return video_url
|
187 |
|
|
|
188 |
def play_video(video_url):
|
189 |
return show_video(video_url)
|
190 |
|
191 |
+
search_button.click(update_search_results, inputs=[search_query_input, upload_date_input, video_type_input, duration_input, sort_by_input], outputs=[search_output, video_ids_state])
|
192 |
search_output.select(on_video_select, inputs=video_ids_state, outputs=selected_video_link)
|
193 |
play_video_button.click(play_video, inputs=selected_video_link, outputs=video_output)
|
194 |
|
|
|
195 |
demo.launch()
|