python 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("""
Enter a YouTube URL to extract a random frame from the video.
Built with anycoder