# 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()