import streamlit as st import base64 from datetime import datetime import plotly.graph_objects as go import cv2 import os import pytz import random import re import requests from moviepy.editor import VideoFileClip from PIL import Image import glob from audio_recorder_streamlit import audio_recorder import json from openai import OpenAI from dotenv import load_dotenv # Page config st.set_page_config( page_title="Bike Cinematic Universe 🎬", page_icon="🚲", layout="wide" ) # Custom CSS with expanded styling st.markdown(""" """, unsafe_allow_html=True) # Load environment variables load_dotenv() client = OpenAI(api_key=os.getenv('OPENAI_API_KEY')) # Bike Collections bike_collections = { "Celestial Collection 🌌": { "Eclipse Vaulter": { "prompt": """Cinematic shot of a sleek black mountain bike silhouetted against a total solar eclipse. The corona creates an ethereal halo effect, with lens flares accentuating key points of the frame. Dynamic composition shows the bike mid-leap, with stardust particles trailing behind. Camera angle: Low angle, wide shot Lighting: Dramatic rim lighting from eclipse Color palette: Deep purples, cosmic blues, corona gold""", "emoji": "🌑" }, "Starlight Leaper": { "prompt": """A black bike performing an epic leap under a vast Milky Way galaxy. Shimmering stars blanket the sky while the bike's wheels leave a trail of stardust. Camera angle: Wide-angle upward shot Lighting: Natural starlight with subtle rim lighting Color palette: Deep blues, silver highlights, cosmic purples""", "emoji": "✨" }, "Moonlit Hopper": { "prompt": """A sleek black bike mid-hop over a moonlit meadow. Full moon illuminating misty surroundings with fireflies dancing around. Camera angle: Side profile with slight low angle Lighting: Soft moonlight with atmospheric fog Color palette: Silver blues, soft whites, deep shadows""", "emoji": "🌙" } }, "Nature-Inspired Collection 🌲": { "Shadow Grasshopper": { "prompt": """A black bike jumping between forest paths. Dappled sunlight streams through the canopy, creating dynamic shadows. Camera angle: Through-the-trees tracking shot Lighting: Natural forest lighting with sun rays Color palette: Forest greens, golden sunlight, deep shadows""", "emoji": "🦗" }, "Onyx Leapfrog": { "prompt": """A bike with obsidian-black finish jumping over a sparkling creek. Water reflection creates mirror effect with ripples from the leap. Camera angle: Low angle from water level Lighting: Golden hour side lighting Color palette: Deep blacks, water blues, forest greens""", "emoji": "🐸" } } } # File handling functions def generate_filename(prompt, file_type): """Generate a safe filename from prompt and timestamp""" central = pytz.timezone('US/Central') safe_date_time = datetime.now(central).strftime("%m%d_%H%M") replaced_prompt = re.sub(r'[<>:"/\\|?*\n]', ' ', prompt) safe_prompt = re.sub(r'\s+', ' ', replaced_prompt).strip()[:240] return f"{safe_date_time}_{safe_prompt}.{file_type}" def save_file(content, filename, is_binary=False): """Save content to file with proper mode""" mode = 'wb' if is_binary else 'w' with open(filename, mode) as f: f.write(content) return filename def process_video(video_path, seconds_per_frame=1): """Extract frames and audio from video""" base64Frames = [] video = cv2.VideoCapture(video_path) total_frames = int(video.get(cv2.CAP_PROP_FRAME_COUNT)) fps = video.get(cv2.CAP_PROP_FPS) frames_to_skip = int(fps * seconds_per_frame) for frame_idx in range(0, total_frames, frames_to_skip): video.set(cv2.CAP_PROP_POS_FRAMES, frame_idx) success, frame = video.read() if not success: break _, buffer = cv2.imencode(".jpg", frame) base64Frames.append(base64.b64encode(buffer).decode("utf-8")) video.release() # Extract audio base_video_path = os.path.splitext(video_path)[0] audio_path = f"{base_video_path}.mp3" try: video_clip = VideoFileClip(video_path) video_clip.audio.write_audiofile(audio_path) video_clip.close() except: st.warning("No audio track found in video") audio_path = None return base64Frames, audio_path def create_media_gallery(): st.header("🎬 Media Gallery") tabs = st.tabs(["🖼️ Images", "🎵 Audio", "🎥 Video", "🎨 Scene Generator"]) with tabs[0]: image_files = glob.glob("*.png") + glob.glob("*.jpg") if image_files: cols = st.columns(3) for idx, image_file in enumerate(image_files): with cols[idx % 3]: st.image(image_file) st.caption(os.path.basename(image_file)) with tabs[1]: audio_files = glob.glob("*.mp3") + glob.glob("*.wav") for audio_file in audio_files: with st.expander(f"🎵 {os.path.basename(audio_file)}"): st.audio(audio_file) with tabs[2]: video_files = glob.glob("*.mp4") for video_file in video_files: with st.expander(f"🎥 {os.path.basename(video_file)}"): st.video(video_file) with tabs[3]: for collection_name, bikes in bike_collections.items(): st.subheader(collection_name) cols = st.columns(len(bikes)) for idx, (bike_name, details) in enumerate(bikes.items()): with cols[idx]: st.markdown(f"""
{details['prompt']}
{bike_details['prompt']}