Spaces:
Runtime error
Runtime error
File size: 4,527 Bytes
6856097 718a117 6856097 718a117 6856097 718a117 6856097 718a117 6856097 718a117 6856097 718a117 6856097 718a117 6856097 718a117 6856097 718a117 6856097 718a117 6856097 718a117 6856097 718a117 6856097 718a117 6856097 718a117 6856097 718a117 6856097 718a117 6856097 718a117 6856097 718a117 6856097 718a117 6856097 718a117 6856097 718a117 6856097 718a117 6856097 | 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 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | import gradio as gr
import cv2
import random
import os
import tempfile
import numpy as np
import yt_dlp
def get_random_frame(youtube_url):
"""
Downloads a video from YouTube and returns a random frame.
"""
if not youtube_url:
raise gr.Error("Please provide a valid YouTube URL.")
# Create a temporary directory for the download
temp_dir = tempfile.mkdtemp()
try:
# Configure yt-dlp options
ydl_opts = {
'format': 'best[ext=mp4]/best', # Prefer MP4 for better OpenCV compatibility
'outtmpl': os.path.join(temp_dir, '%(id)s.%(ext)s'),
'quiet': True,
'no_warnings': True,
}
# Download video info first to check validity
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
try:
info = ydl.extract_info(youtube_url, download=False)
if 'duration' not in info:
raise gr.Error("Could not retrieve video duration. The video might be private or a live stream.")
except Exception as e:
raise gr.Error(f"Invalid YouTube URL or Video unavailable: {str(e)}")
# Download the video
ydl.params['quiet'] = False # Show progress
info = ydl.extract_info(youtube_url, download=True)
video_path = ydl.prepare_filename(info)
# Open the video file using OpenCV
cap = cv2.VideoCapture(video_path)
if not cap.isOpened():
raise gr.Error("Could not open the video file after downloading.")
# Get total number of frames
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
if total_frames == 0:
raise gr.Error("Video has no frames.")
# Select a random frame index
random_frame_idx = random.randint(0, total_frames - 1)
# Set the frame position
cap.set(cv2.CAP_PROP_POS_FRAMES, random_frame_idx)
# Read the frame
ret, frame = cap.read()
cap.release()
if not ret:
raise gr.Error("Failed to read the selected frame.")
# Convert BGR (OpenCV default) to RGB (Gradio/Image default)
frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
return frame_rgb
except gr.Error:
raise
except Exception as e:
raise gr.Error(f"An unexpected error occurred: {str(e)}")
finally:
# Clean up temporary files
import shutil
if os.path.exists(temp_dir):
shutil.rmtree(temp_dir, ignore_errors=True)
# Gradio 6 Application
with gr.Blocks() as demo:
# Header with required link
gr.HTML("""
<div style="text-align: center; margin-bottom: 20px;">
<h1>YouTube Frame Randomizer</h1>
<p>Enter a YouTube URL to extract a random frame from the video.</p>
<a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" style="color: #007bff; text-decoration: none; font-weight: bold;">Built with anycoder</a>
</div>
""")
with gr.Row():
with gr.Column(scale=1):
url_input = gr.Textbox(
label="YouTube URL",
placeholder="https://www.youtube.com/watch?v=...",
lines=1
)
randomize_btn = gr.Button("Get Random Frame", variant="primary", size="lg")
gr.Markdown("""
### How it works:
1. Paste a YouTube link.
2. Click the button.
3. The app downloads the video (this may take a moment).
4. A random timestamp is selected and the frame is displayed.
""")
with gr.Column(scale=2):
output_image = gr.Image(
label="Random Frame",
type="numpy",
interactive=False
)
# Event listener
randomize_btn.click(
fn=get_random_frame,
inputs=url_input,
outputs=output_image,
api_visibility="public"
)
# Launch the app with Gradio 6 syntax
# Note: theme, css, and footer_links are now parameters of demo.launch()
demo.launch(
theme=gr.themes.Soft(
primary_hue="blue",
secondary_hue="cyan",
),
footer_links=[
{"label": "Gradio", "url": "https://gradio.app"},
{"label": "Hugging Face", "url": "https://huggingface.co"},
{"label": "Built with anycoder", "url": "https://huggingface.co/spaces/akhaliq/anycoder"}
]
) |