File size: 4,045 Bytes
8f5a1d1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# 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()