Spaces:
Runtime error
Runtime error
# First, make sure you have the required libraries installed: | |
# pip install gradio requests | |
import gradio as gr | |
import requests | |
import re | |
from PIL import Image | |
from io import BytesIO | |
def extract_video_id(url): | |
""" | |
Extracts the YouTube video ID from a variety of URL formats. | |
""" | |
# This regex covers standard, shortened, and embed URLs | |
regex = r"(?:https?:\/\/)?(?:www\.)?(?:youtube\.com\/(?:[^\/\n\s]+\/\S+\/|(?:v|e(?:mbed)?)\/|\S*?[?&]v=)|youtu\.be\/)([a-zA-Z0-9_-]{11})" | |
match = re.search(regex, url) | |
if match: | |
return match.group(1) | |
return None | |
def get_youtube_thumbnail(url): | |
""" | |
Fetches the highest quality thumbnail for a given YouTube URL. | |
""" | |
if not url or not url.strip(): | |
# Raise a Gradio error if the input is empty | |
raise gr.Error("Please enter a YouTube URL.") | |
video_id = extract_video_id(url) | |
if video_id: | |
# URLs for different thumbnail qualities | |
thumbnail_urls = [ | |
f"https://img.youtube.com/vi/{video_id}/maxresdefault.jpg", # Max resolution | |
f"https://img.youtube.com/vi/{video_id}/sddefault.jpg", # Standard definition | |
f"https://img.youtube.com/vi/{video_id}/hqdefault.jpg", # High quality | |
f"https://img.youtube.com/vi/{video_id}/0.jpg" # Default | |
] | |
for thumb_url in thumbnail_urls: | |
try: | |
response = requests.get(thumb_url, timeout=5) | |
# Raise an exception for bad status codes (4xx or 5xx) | |
response.raise_for_status() | |
# Open the image to check if it's a valid image and not the "unavailable" placeholder | |
img = Image.open(BytesIO(response.content)) | |
# YouTube returns a 120x90 placeholder if a specific resolution is not found. | |
# We check the width to ensure we get a real thumbnail. | |
if img.width > 121: | |
return img # Return the first valid, high-quality image found | |
except requests.exceptions.RequestException as e: | |
# This handles network errors, timeouts, etc. | |
print(f"Could not fetch {thumb_url}. Error: {e}") | |
continue # Try the next URL | |
except Exception as e: | |
# This handles errors with opening the image | |
print(f"Error processing image from {thumb_url}. Error: {e}") | |
continue | |
# If all URLs fail, raise an error | |
raise gr.Error("Could not retrieve thumbnail. The video may be private, deleted, or the URL is incorrect.") | |
else: | |
# If the regex fails to find an ID, the URL is invalid | |
raise gr.Error("Invalid YouTube URL. Please check the link and try again.") | |
# --- Gradio App Interface --- | |
with gr.Blocks(theme=gr.themes.Soft()) as demo: | |
gr.Markdown( | |
""" | |
# 🎬 YouTube Thumbnail Downloader | |
Paste any YouTube video link below to instantly grab its highest-quality thumbnail. | |
You can then right-click the image to save it. | |
""" | |
) | |
with gr.Row(): | |
url_input = gr.Textbox( | |
label="YouTube Video URL", | |
placeholder="e.g., https://www.youtube.com/watch?v=dQw4w9WgXcQ", | |
scale=4, | |
) | |
submit_btn = gr.Button("Get Thumbnail", variant="primary", scale=1) | |
image_output = gr.Image(label="Thumbnail Preview", type="pil", interactive=False) | |
# --- Event Listeners --- | |
submit_btn.click( | |
fn=get_youtube_thumbnail, | |
inputs=url_input, | |
outputs=image_output, | |
api_name="get_thumbnail" | |
) | |
# Add examples for users to try | |
gr.Examples( | |
examples=[ | |
"https://www.youtube.com/watch?v=3JZ_D3ELwOQ", | |
"https://www.youtube.com/watch?v=LXb3EKWsInQ", | |
"https://youtu.be/i_LwzRVP7bg" | |
], | |
inputs=url_input, | |
outputs=image_output, | |
fn=get_youtube_thumbnail | |
) | |
# Launch the application | |
if __name__ == "__main__": | |
demo.launch() |