import streamlit as st from openai import OpenAI import requests from PIL import Image from io import BytesIO import re import urllib.parse # Set up the page st.set_page_config( page_title="AI Thumbnail Generator", page_icon="đŸŽŦ", layout="wide" ) st.title("đŸŽŦ AI Video Thumbnail Generator") st.write("Generate engaging thumbnails for your videos using OpenAI's DALL-E 3") # Sidebar for API key with st.sidebar: st.header("🔑 Configuration") openai_api_key = st.text_input("OpenAI API Key", type="password") if openai_api_key: client = OpenAI(api_key=openai_api_key) st.success("API Key loaded!") else: st.warning("Enter your OpenAI API key to continue") client = None def extract_video_info(url): """Extract video information from URL using web scraping""" video_info = {"platform": "unknown", "title": "", "id": "", "description": "", "extraction_success": False} try: # Identify platform first if 'facebook.com' in url or 'fb.watch' in url: video_info["platform"] = "facebook" # Extract video ID from Facebook URL patterns fb_patterns = [ r'facebook\.com/.*?/videos/(\d+)', r'facebook\.com/watch/?\?v=(\d+)', r'facebook\.com/share/v/([a-zA-Z0-9]+)', r'fb\.watch/([a-zA-Z0-9_-]+)' ] for pattern in fb_patterns: match = re.search(pattern, url) if match: video_info["id"] = match.group(1) break st.warning("🔒 Facebook videos require special handling. Please use **Manual Description mode** for best results.") return video_info elif 'instagram.com' in url: video_info["platform"] = "instagram" # Extract Instagram post/reel ID ig_patterns = [ r'instagram\.com/p/([a-zA-Z0-9_-]+)', r'instagram\.com/reel/([a-zA-Z0-9_-]+)', r'instagram\.com/tv/([a-zA-Z0-9_-]+)' ] for pattern in ig_patterns: match = re.search(pattern, url) if match: video_info["id"] = match.group(1) break st.warning("🔒 Instagram videos require login access. Please use **Manual Description mode** for best results.") return video_info elif 'tiktok.com' in url: video_info["platform"] = "tiktok" # Extract TikTok video ID tiktok_match = re.search(r'tiktok\.com/.*?/video/(\d+)', url) if tiktok_match: video_info["id"] = tiktok_match.group(1) st.warning("🔒 TikTok videos have access restrictions. Please use **Manual Description mode** for best results.") return video_info elif 'twitter.com' in url or 'x.com' in url: video_info["platform"] = "twitter" # Extract tweet ID twitter_patterns = [ r'twitter\.com/.*?/status/(\d+)', r'x\.com/.*?/status/(\d+)' ] for pattern in twitter_patterns: match = re.search(pattern, url) if match: video_info["id"] = match.group(1) break st.warning("🔒 Twitter/X videos have access restrictions. Please use **Manual Description mode** for best results.") return video_info # For supported platforms, continue with web scraping headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' } response = requests.get(url, headers=headers, timeout=10) html_content = response.text # YouTube patterns youtube_patterns = [ r'(?:youtube\.com/watch\?v=|youtu\.be/)([a-zA-Z0-9_-]+)', r'youtube\.com/embed/([a-zA-Z0-9_-]+)' ] for pattern in youtube_patterns: match = re.search(pattern, url) if match: video_info["platform"] = "youtube" video_info["id"] = match.group(1) # Extract title from YouTube title_patterns = [ r'([^<]+)', r'"title":"([^"]+)"', r'([^<]+)', r'([^<]+)', r' 200 else video_info['description']) elif video_info['platform'] in ['facebook', 'instagram', 'tiktok', 'twitter']: st.info(f"â„šī¸ {video_info['platform'].title()} content detected. For best results, switch to **Manual Description mode** and describe your video content.") # Check if we should continue with AI analysis or recommend manual mode if video_info['platform'] in ['facebook', 'instagram', 'tiktok', 'twitter'] and not custom_description: st.warning("🔄 **Recommendation:** For social media videos, please either:") st.write("1. Switch to **Manual Description mode** and describe your video content") st.write("2. Or add a detailed description in the 'Additional Description' field above") if st.button("🔄 Switch to Manual Mode", key="switch_mode"): st.rerun() analysis = None else: # Step 2: Analyze video content with AI with st.spinner("🤖 Analyzing video content with AI..."): analysis = analyze_video_content(video_url, custom_description) else: # Manual mode - use custom description directly st.success("✅ Using your custom description!") analysis_prompt = f""" Create a detailed description for generating an engaging video thumbnail based on this video content: {custom_description} Please analyze this content and provide: 1. A clear, detailed description for the thumbnail image (2-3 sentences) 2. Suggested visual style and mood that matches the content 3. Key elements that should be prominently featured 4. Color palette and composition suggestions Focus on creating a thumbnail that would grab attention and accurately represent this content. """ with st.spinner("🤖 Analyzing your description with AI..."): try: response = client.chat.completions.create( model="gpt-4", messages=[{"role": "user", "content": analysis_prompt}], max_tokens=300, temperature=0.7 ) analysis = response.choices[0].message.content.strip() except Exception as e: st.error(f"Error analyzing description: {str(e)}") analysis = None if analysis: st.success("✅ AI analysis complete!") with st.expander("🧠 AI Content Analysis", expanded=True): st.write(analysis) # Step 3: Generate thumbnails st.header("đŸ–ŧī¸ Generated Thumbnails") for i in range(num_variations): with st.spinner(f"🎨 Generating thumbnail {i+1}/{num_variations}..."): # Add variation to prompt for multiple generations varied_analysis = analysis if num_variations > 1: varied_analysis += f" (Create a unique visual variation #{i+1} with different composition, colors, or focus while maintaining the core message)" thumbnail = generate_thumbnail(varied_analysis, thumbnail_style, image_size) if thumbnail: col1, col2 = st.columns([3, 1]) with col1: st.image( thumbnail, caption=f"Thumbnail {i+1} - {thumbnail_style.title()} Style", use_column_width=True ) with col2: # Download button buffer = BytesIO() thumbnail.save(buffer, format="PNG") st.download_button( label="đŸ“Ĩ Download", data=buffer.getvalue(), file_name=f"thumbnail_{i+1}_{thumbnail_style}.png", mime="image/png", key=f"download_{i}", use_container_width=True ) st.divider() elif analysis_mode == "🔗 URL Analysis (Automatic)": # Only show this error for URL mode, not when we're recommending manual mode if not (video_info.get('platform') in ['facebook', 'instagram', 'tiktok', 'twitter'] and not custom_description): st.error("❌ Failed to analyze content. Please try again or provide more details.") # Information sections st.header("â„šī¸ How It Works") col1, col2, col3 = st.columns(3) with col1: st.subheader("1ī¸âƒŖ URL Analysis") st.write("AI analyzes your video URL and description to understand the content") with col2: st.subheader("2ī¸âƒŖ Content Description") st.write("GPT-4 creates a detailed description optimized for thumbnail generation") with col3: st.subheader("3ī¸âƒŖ Image Generation") st.write("DALL-E 3 creates high-quality thumbnails with better prompt following") # Supported platforms st.header("🌐 Platform Support & Recommendations") col1, col2 = st.columns(2) with col1: st.subheader("✅ Automatic Analysis Works Well") st.success(""" **YouTube** - Full title & description extraction **Vimeo** - Complete metadata support **Direct Video URLs** - Basic information extraction **General Websites** - Title and meta description """) with col2: st.subheader("🔄 Use Manual Mode For") st.info(""" **Facebook** - Requires login/blocked by anti-scraping **Instagram** - Login required for video access **TikTok** - Access restrictions and complex structure **Twitter/X** - Limited public API access **Private/Protected Videos** - Authentication required """) st.header("đŸ› ī¸ Quick Fix for Facebook/Social Media Videos") # Quick helper for social media users if st.button("🔄 I have a Facebook/Instagram/TikTok video - Help me!", type="secondary"): st.balloons() st.success("đŸŽ¯ **Quick Solution for Social Media Videos:**") st.write("1. Select **âœī¸ Manual Description (Custom)** mode above") st.write("2. In the description box, tell us about your video:") st.code("""Example template: "[Video topic] - [what happens in video] Target audience: [who watches this] Mood: [fun/serious/educational/promotional] Visual style: [colors you want/aesthetic] Key elements: [people/objects/scenes]" """) st.write("3. Choose your preferred style and generate!") st.info("💡 This method often works **better** than automatic analysis because you know your content best!") st.header("đŸ› ī¸ How to Handle Facebook Videos") with st.expander("📘 Step-by-step guide for Facebook videos", expanded=True): st.write(""" **For your Facebook video:** `https://www.facebook.com/share/v/16HtujeeH2/` 1. **Switch to Manual Description mode** (select the âœī¸ option above) 2. **Describe your Facebook video content, for example:** - What is the video about? - What's the main topic or message? - Who is the target audience? - What's the mood/tone (educational, funny, serious, promotional)? - Any key visual elements or people in the video? 3. **Example description:** > "Educational video about sustainable farming techniques for small-scale farmers. Shows practical tips for organic gardening, water conservation, and crop rotation. Target audience is beginner gardeners and environmentally conscious people. Should have a clean, educational feel with earth tones." 4. **Generate thumbnail** - The AI will create perfect thumbnails based on your description! """) st.header("💡 Pro Tips for Social Media Videos") col1, col2 = st.columns(2) with col1: st.subheader("đŸŽ¯ Better Descriptions") st.info(""" **Include:** - Video topic and main message - Target audience (age, interests) - Mood/tone (fun, serious, educational) - Key visual elements or people - Desired colors or style """) with col2: st.subheader("🚀 Platform-Specific Styles") st.info(""" **Facebook**: Professional or colorful styles work well **Instagram**: Creative and colorful for better engagement **TikTok**: Dramatic and colorful for younger audience **Twitter**: Clean, minimalist for news/discussion content """) # DALL-E 3 Benefits section st.header("🎨 DALL-E 3 Advantages") col1, col2 = st.columns(2) with col1: st.info(""" ✅ **Higher Quality:** Superior image generation ✅ **Better Prompt Following:** More accurate to descriptions ✅ **Enhanced Details:** Sharper, more professional results """) with col2: st.info(""" ✅ **HD Quality:** Crystal clear thumbnails ✅ **Better Composition:** Superior layout and visual balance ✅ **Text Integration:** Can include readable text elements """) # Pricing info st.header("💰 Cost Information") cost_info = f""" **OpenAI API Costs (approximate):** - GPT-4 Analysis: ~$0.001 per video - DALL-E 3 Image Generation: ~$0.08 per {image_size} HD image - **Total per thumbnail:** ~$0.081 USD *Costs may vary based on current OpenAI pricing* """ st.info(cost_info) # Tips st.header("💡 Tips for Best Results") col1, col2 = st.columns(2) with col1: st.subheader("đŸŽ¯ For Better Analysis") st.info(""" **URL Tips:** - Use direct YouTube/Vimeo links for best results - Make sure the video is publicly accessible - For private videos, provide detailed descriptions **Description Tips:** - Include the video topic and target audience - Mention the mood/tone (serious, fun, educational) - Specify any key visual elements or themes """) with col2: st.subheader("🚀 For Better Thumbnails") st.info(""" **Style Selection:** - **Professional**: Business, tutorials, serious content - **Creative**: Art, design, entertainment content - **Colorful**: Kids content, fun videos, gaming - **Dramatic**: Action, movie trailers, intense content - **Minimalist**: Tech, educational, clean aesthetic """) # Troubleshooting section st.header("🔧 Troubleshooting Common Issues") with st.expander("❓ Why doesn't automatic analysis work for my video?"): st.write(""" **Social Media Platforms (Facebook, Instagram, TikTok, Twitter):** - These platforms block automated content extraction - They require login/authentication for video access - **Solution:** Use **Manual Description mode** instead **YouTube/Vimeo Issues:** - Video might be private or region-locked - Some videos have restricted metadata - **Solution:** Add custom description for better context **General Website Videos:** - Some sites block automated requests - Limited metadata available - **Solution:** Describe the video content manually """) with st.expander("🚀 How to get the best thumbnails?"): st.write(""" **For Manual Descriptions:** 1. **Be Specific:** Instead of "cooking video" → "Italian pasta making tutorial showing step-by-step homemade fettuccine preparation" 2. **Include Visual Details:** "Close-up shots of hands kneading dough, flour dust, kitchen setting with warm lighting" 3. **Mention Target Audience:** "For beginner home cooks and food enthusiasts" 4. **Specify Mood/Style:** "Cozy, warm atmosphere with rustic kitchen aesthetic" 5. **Color Preferences:** "Earth tones, warm yellows and browns, natural lighting" """) with st.expander("💰 Cost concerns?"): st.write(""" **Cost Breakdown:** - GPT-4 Analysis: ~$0.001 per video - DALL-E 3 Generation: ~$0.08 per HD thumbnail - **Total:** ~$0.081 per thumbnail **Tips to Save:** - Generate fewer variations (1-2 instead of 3) - Use 512x512 size if budget is tight - Perfect your description before generating to avoid re-dos """) with st.expander("🔒 Privacy and social media videos"): st.write(""" **Why Manual Mode is Better for Social Media:** - **Privacy:** No need to access private content - **Accuracy:** You know your video better than any algorithm - **Control:** Full control over thumbnail style and messaging - **Speed:** No need to wait for extraction attempts **Security:** Your video content stays private - only your description is sent to OpenAI. """) # Footer st.divider() st.markdown("""

Built with â¤ī¸ using Streamlit and OpenAI API (GPT-4 + DALL-E 3)

""", unsafe_allow_html=True)