mobenta commited on
Commit
18c7580
·
verified ·
1 Parent(s): 2202041

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +58 -64
app.py CHANGED
@@ -1,82 +1,76 @@
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')
6
 
7
- # Function to search YouTube videos using yt-dlp for better reliability
8
- def youtube_search(query, max_results=50):
9
- ydl_opts = {
10
- 'quiet': False,
11
- 'extract_flat': False, # Set to False to retrieve full details of each video
12
- 'logger': logging.getLogger(), # Use the logging module to capture yt-dlp logs
13
- 'simulate': True,
14
- 'noplaylist': True, # Avoid playlist entries
15
- 'ignoreerrors': True, # Continue on errors without stopping
16
- 'force_generic_extractor': False, # Use the best extractor available
17
- 'default_search': 'ytsearch', # Default search method
18
  }
19
- search_url = f"ytsearch{max_results}:{query}"
20
 
21
  logging.debug(f"Starting YouTube search for query: {query}")
22
 
23
  try:
24
- with yt_dlp.YoutubeDL(ydl_opts) as ydl:
25
- result = ydl.extract_info(search_url, download=False)
26
 
27
- if not result or 'entries' not in result:
28
- logging.warning("No entries found in search result.")
29
- return []
30
 
31
- entries = result['entries']
32
- logging.debug(f"Number of entries found: {len(entries)}")
33
 
34
- detailed_entries = []
35
- for entry in entries:
36
- # Collect and print each field separately
37
- print("\n==============================")
38
- print("Video Details:")
39
- print("==============================")
40
- print(f"ID: {entry.get('id', 'N/A')}")
41
- print(f"Title: {entry.get('title', 'N/A')}")
42
- print(f"Uploader: {entry.get('uploader', 'N/A')}")
43
- print(f"Uploader ID: {entry.get('uploader_id', 'N/A')}")
44
- print(f"Upload Date: {entry.get('upload_date', 'N/A')}")
45
- print(f"Description: {entry.get('description', 'N/A')}")
46
- print(f"Duration (seconds): {entry.get('duration', 'N/A')}")
47
- print(f"View Count: {entry.get('view_count', 'N/A')}")
48
- print(f"Like Count: {entry.get('like_count', 'N/A')}")
49
- print(f"Dislike Count: {entry.get('dislike_count', 'N/A')}")
50
- print(f"Comment Count: {entry.get('comment_count', 'N/A')}")
51
- print(f"Average Rating: {entry.get('average_rating', 'N/A')}")
52
- print(f"Thumbnail URL: {entry.get('thumbnail', 'N/A')}")
53
- print(f"Webpage URL: {entry.get('webpage_url', 'N/A')}")
54
- print(f"Channel URL: {entry.get('channel_url', 'N/A')}")
55
- print(f"Categories: {entry.get('categories', 'N/A')}")
56
- print(f"Tags: {entry.get('tags', 'N/A')}")
57
- print(f"Channel ID: {entry.get('channel_id', 'N/A')}")
58
- print(f"Age Restriction: {entry.get('age_limit', 'N/A')}")
59
- print(f"Is Live: {entry.get('is_live', 'N/A')}")
60
- print(f"FPS: {entry.get('fps', 'N/A')}")
61
- print(f"Resolution: {entry.get('resolution', 'N/A')}")
62
- print(f"Aspect Ratio: {entry.get('aspect_ratio', 'N/A')}")
63
- print(f"Video Codec: {entry.get('vcodec', 'N/A')}")
64
- print(f"Audio Codec: {entry.get('acodec', 'N/A')}")
65
- print("==============================\n")
66
 
67
- # Add the entry details to the list if needed
68
- detailed_entries.append(entry)
69
 
70
- return detailed_entries
71
 
72
- except yt_dlp.utils.DownloadError as e:
73
- logging.error(f"DownloadError occurred: {e}")
74
- except yt_dlp.utils.ExtractorError as e:
75
- logging.error(f"ExtractorError occurred: {e}")
76
  except Exception as e:
77
- logging.error(f"An unexpected error occurred: {e}")
78
-
79
- return []
80
 
81
- # Test the function with a sample query
82
- youtube_search("test video")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+ from bs4 import BeautifulSoup
3
+ import gradio as gr
4
  import logging
5
 
6
  # Configure logging for debugging purposes
7
  logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
8
 
9
+ # Function to search YouTube without using the API
10
+ def youtube_search(query, max_results=10):
11
+ # Create the YouTube search URL
12
+ search_url = f"https://www.youtube.com/results?search_query={query.replace(' ', '+')}"
13
+ headers = {
14
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36"
 
 
 
 
 
15
  }
 
16
 
17
  logging.debug(f"Starting YouTube search for query: {query}")
18
 
19
  try:
20
+ response = requests.get(search_url, headers=headers)
21
+ response.raise_for_status() # Raise an error for bad status codes
22
 
23
+ # Parse the HTML response using BeautifulSoup
24
+ soup = BeautifulSoup(response.text, "html.parser")
 
25
 
26
+ # Find all video entries
27
+ videos = soup.find_all("a", {"href": lambda x: x and "/watch?v=" in x}, limit=max_results)
28
 
29
+ gallery_items = []
30
+ for video in videos:
31
+ # Extract details
32
+ video_id = video['href'].split('=')[1]
33
+ video_title = video.get('title', 'No Title')
34
+ video_url = f"https://www.youtube.com{video['href']}"
35
+ thumbnail_url = f"https://i.ytimg.com/vi/{video_id}/hqdefault.jpg"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
 
37
+ # Append video details as a tuple for the gallery display
38
+ gallery_items.append((thumbnail_url, video_title, video_url))
39
 
40
+ return gallery_items, "" # Return the list of gallery items and no error message
41
 
42
+ except requests.exceptions.RequestException as e:
43
+ error_message = f"Request error occurred: {e}"
44
+ logging.error(error_message)
45
+ return [], error_message
46
  except Exception as e:
47
+ error_message = f"An unexpected error occurred: {e}"
48
+ logging.error(error_message)
49
+ return [], error_message
50
 
51
+ # Function to create a gallery for Gradio
52
+ def display_videos(query):
53
+ gallery_items, error_message = youtube_search(query)
54
+ if error_message:
55
+ return gr.update(value=[], label="Error: Unable to fetch videos"), error_message
56
+
57
+ # Display thumbnails and titles as gallery items
58
+ formatted_gallery = [(f"<img src='{item[0]}' width='250'/>", f"<a href='{item[2]}' target='_blank'>{item[1]}</a>") for item in gallery_items]
59
+ return formatted_gallery, ""
60
+
61
+ # Gradio interface
62
+ with gr.Blocks() as demo:
63
+ gr.Markdown("## YouTube Video Search (Without API)")
64
+ with gr.Row():
65
+ with gr.Column(scale=2):
66
+ search_input = gr.Textbox(label="Search YouTube", placeholder="Enter your search query here")
67
+ search_button = gr.Button("Search")
68
+ with gr.Column(scale=4):
69
+ search_output = gr.Gallery(label="Search Results", columns=2)
70
+ error_output = gr.Textbox(label="Error Message", interactive=False, visible=False)
71
+
72
+ # Define search button behavior
73
+ search_button.click(display_videos, inputs=search_input, outputs=[search_output, error_output])
74
+
75
+ # Launch the Gradio interface
76
+ demo.launch()