Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -1,7 +1,5 @@
|
|
1 |
import yt_dlp
|
2 |
import logging
|
3 |
-
import gradio as gr
|
4 |
-
import re
|
5 |
|
6 |
# Configure logging for debugging purposes
|
7 |
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
|
@@ -22,128 +20,51 @@ def youtube_search(query, max_results=50):
|
|
22 |
try:
|
23 |
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
|
24 |
result = ydl.extract_info(search_url, download=False)
|
25 |
-
gallery_items = []
|
26 |
detailed_entries = []
|
27 |
|
28 |
if 'entries' in result:
|
29 |
logging.debug(f"Number of entries found: {len(result['entries'])}")
|
30 |
for entry in result['entries']:
|
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 |
-
print(f"Audio Codec: {entry.get('acodec', 'N/A')}")
|
65 |
-
print("==============================\n")
|
66 |
-
|
67 |
-
gallery_items.append((thumbnail_url, video_id, video_title))
|
68 |
-
detailed_entries.append(entry)
|
69 |
else:
|
70 |
logging.warning("No entries found in search result.")
|
71 |
-
return
|
72 |
except Exception as e:
|
73 |
error_message = f"Error during YouTube yt-dlp request: {e}"
|
74 |
logging.error(error_message)
|
75 |
-
return []
|
76 |
-
|
77 |
-
# Function to display the video using the video URL
|
78 |
-
def show_video(video_url):
|
79 |
-
video_id = None
|
80 |
-
patterns = [
|
81 |
-
r"youtube\.com/watch\?v=([^&?\/]+)",
|
82 |
-
r"youtube\.com/embed/([^&?\/]+)",
|
83 |
-
r"youtube\.com/v/([^&?\/]+)",
|
84 |
-
r"youtu\.be/([^&?\/]+)"
|
85 |
-
]
|
86 |
-
|
87 |
-
for pattern in patterns:
|
88 |
-
match = re.search(pattern, video_url)
|
89 |
-
if match:
|
90 |
-
video_id = match.group(1)
|
91 |
-
logging.debug(f"Extracted video ID: {video_id}")
|
92 |
-
break
|
93 |
-
|
94 |
-
if not video_id:
|
95 |
-
logging.error("Invalid YouTube URL. Please enter a valid YouTube video link.")
|
96 |
-
return "Invalid YouTube URL. Please enter a valid YouTube video link."
|
97 |
-
|
98 |
-
embed_url = f"https://www.youtube.com/embed/{video_id}"
|
99 |
-
logging.debug(f"Embed URL generated: {embed_url}")
|
100 |
-
|
101 |
-
html_code = f'''
|
102 |
-
<iframe width="560" height="315" src="{embed_url}"
|
103 |
-
frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
104 |
-
allowfullscreen></iframe>
|
105 |
-
'''
|
106 |
-
return html_code
|
107 |
-
|
108 |
-
# Create the Gradio interface
|
109 |
-
with gr.Blocks() as demo:
|
110 |
-
gr.Markdown("## YouTube Video Search, Selection, and Playback")
|
111 |
-
|
112 |
-
with gr.Row():
|
113 |
-
with gr.Column(scale=3):
|
114 |
-
search_query_input = gr.Textbox(label="Search YouTube", placeholder="Enter your search query here")
|
115 |
-
search_button = gr.Button("Search")
|
116 |
-
search_output = gr.Gallery(label="Search Results", columns=5, height="1500px")
|
117 |
-
error_output = gr.Textbox(label="Error Message", interactive=False, visible=False)
|
118 |
-
|
119 |
-
with gr.Column(scale=2):
|
120 |
-
selected_video_link = gr.Textbox(label="Selected Video Link", interactive=False)
|
121 |
-
play_video_button = gr.Button("Play Video")
|
122 |
-
video_output = gr.HTML(label="Video Player")
|
123 |
-
|
124 |
-
# Define search button behavior
|
125 |
-
def update_search_results(query):
|
126 |
-
gallery_items, error_message = youtube_search(query)
|
127 |
-
if error_message:
|
128 |
-
return [], error_message, gr.update(visible=True)
|
129 |
-
gallery_items_display = [(item[0], item[1]) for item in gallery_items]
|
130 |
-
return gallery_items_display, "", gr.update(visible=False)
|
131 |
-
|
132 |
-
# Update the selected video link field when a video is clicked in the gallery
|
133 |
-
def on_video_select(evt: gr.SelectData):
|
134 |
-
selected_video_id = evt.value["caption"]
|
135 |
-
video_url = f"https://www.youtube.com/watch?v={selected_video_id}"
|
136 |
-
logging.debug(f"Video selected: {video_url}")
|
137 |
-
return video_url
|
138 |
-
|
139 |
-
# Play the video when the Play Video button is clicked
|
140 |
-
def play_video(video_url):
|
141 |
-
logging.debug(f"Playing video with URL: {video_url}")
|
142 |
-
return show_video(video_url)
|
143 |
-
|
144 |
-
search_button.click(update_search_results, inputs=search_query_input, outputs=[search_output, error_output, error_output])
|
145 |
-
search_output.select(on_video_select, inputs=None, outputs=selected_video_link)
|
146 |
-
play_video_button.click(play_video, inputs=selected_video_link, outputs=video_output)
|
147 |
|
148 |
-
#
|
149 |
-
|
|
|
1 |
import yt_dlp
|
2 |
import logging
|
|
|
|
|
3 |
|
4 |
# Configure logging for debugging purposes
|
5 |
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
|
|
|
20 |
try:
|
21 |
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
|
22 |
result = ydl.extract_info(search_url, download=False)
|
|
|
23 |
detailed_entries = []
|
24 |
|
25 |
if 'entries' in result:
|
26 |
logging.debug(f"Number of entries found: {len(result['entries'])}")
|
27 |
for entry in result['entries']:
|
28 |
+
# Collect and print each field separately
|
29 |
+
print("\n==============================")
|
30 |
+
print("Video Details:")
|
31 |
+
print("==============================")
|
32 |
+
print(f"ID: {entry.get('id', 'N/A')}")
|
33 |
+
print(f"Title: {entry.get('title', 'N/A')}")
|
34 |
+
print(f"Uploader: {entry.get('uploader', 'N/A')}")
|
35 |
+
print(f"Uploader ID: {entry.get('uploader_id', 'N/A')}")
|
36 |
+
print(f"Upload Date: {entry.get('upload_date', 'N/A')}")
|
37 |
+
print(f"Description: {entry.get('description', 'N/A')}")
|
38 |
+
print(f"Duration (seconds): {entry.get('duration', 'N/A')}")
|
39 |
+
print(f"View Count: {entry.get('view_count', 'N/A')}")
|
40 |
+
print(f"Like Count: {entry.get('like_count', 'N/A')}")
|
41 |
+
print(f"Dislike Count: {entry.get('dislike_count', 'N/A')}")
|
42 |
+
print(f"Comment Count: {entry.get('comment_count', 'N/A')}")
|
43 |
+
print(f"Average Rating: {entry.get('average_rating', 'N/A')}")
|
44 |
+
print(f"Thumbnail URL: {entry.get('thumbnail', 'N/A')}")
|
45 |
+
print(f"Webpage URL: {entry.get('webpage_url', 'N/A')}")
|
46 |
+
print(f"Channel URL: {entry.get('channel_url', 'N/A')}")
|
47 |
+
print(f"Categories: {entry.get('categories', 'N/A')}")
|
48 |
+
print(f"Tags: {entry.get('tags', 'N/A')}")
|
49 |
+
print(f"Channel ID: {entry.get('channel_id', 'N/A')}")
|
50 |
+
print(f"Age Restriction: {entry.get('age_limit', 'N/A')}")
|
51 |
+
print(f"Is Live: {entry.get('is_live', 'N/A')}")
|
52 |
+
print(f"FPS: {entry.get('fps', 'N/A')}")
|
53 |
+
print(f"Resolution: {entry.get('resolution', 'N/A')}")
|
54 |
+
print(f"Aspect Ratio: {entry.get('aspect_ratio', 'N/A')}")
|
55 |
+
print(f"Video Codec: {entry.get('vcodec', 'N/A')}")
|
56 |
+
print(f"Audio Codec: {entry.get('acodec', 'N/A')}")
|
57 |
+
print("==============================\n")
|
58 |
+
|
59 |
+
# Add the entry details to the list if needed
|
60 |
+
detailed_entries.append(entry)
|
|
|
|
|
|
|
|
|
|
|
61 |
else:
|
62 |
logging.warning("No entries found in search result.")
|
63 |
+
return detailed_entries
|
64 |
except Exception as e:
|
65 |
error_message = f"Error during YouTube yt-dlp request: {e}"
|
66 |
logging.error(error_message)
|
67 |
+
return []
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
68 |
|
69 |
+
# Test the function with a sample query
|
70 |
+
youtube_search("test video")
|