Spaces:
No application file
No application file
| === requirements.txt === | |
| streamlit | |
| Pillow | |
| === config.py === | |
| import os | |
| # --- General Configuration --- | |
| APP_TITLE = "Sora 2 Simulator: Text & Image to Video Generation" | |
| ANYCODER_LINK = "https://huggingface.co/spaces/akhaliq/anycoder" | |
| ANYCODER_TEXT = "Built with anycoder" | |
| # --- Generation Parameters --- | |
| MIN_DURATION_S = 4 | |
| MAX_DURATION_S = 120 | |
| DEFAULT_DURATION_S = 30 | |
| GENERATION_COST_PER_SECOND = 0.05 # Mock cost | |
| # --- Mock Output Configuration --- | |
| # NOTE: Since actual binary files cannot be generated or shipped, | |
| # we use mock placehoolder URLs/data. | |
| MOCK_VIDEO_URL = "https://storage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4" # Public domain sample video | |
| MOCK_AUDIO_DATA = "placeholder_audio.mp3" | |
| # Mock audio data (Base64 encoded silence or small placeholder) | |
| # In a real app, this would be a loaded audio file. | |
| # Using a descriptive placeholder here for pure Python execution. | |
| MOCK_AUDIO_DESCRIPTION = "Simulated high-fidelity audio track generated based on prompt." | |
| # --- UI Texts --- | |
| DISCLAIMER = ( | |
| "🚨 **IMPORTANT SIMULATION NOTICE:** The actual OpenAI Sora 2 model is not publicly available. " | |
| "This application is a sophisticated simulation demonstrating the expected capabilities and workflow " | |
| "of a next-generation video generation interface. Video output is a public domain placeholder." | |
| ) | |
| === utils.py === | |
| import time | |
| import random | |
| from config import MOCK_VIDEO_URL, MOCK_AUDIO_DESCRIPTION | |
| def simulate_video_generation(prompt: str, duration_s: int, generate_audio: bool) -> dict: | |
| """ | |
| Simulates the intensive process of generating a video using a large AI model. | |
| The mock duration is proportional to the requested video length. | |
| """ | |
| # Calculate simulated generation time (e.g., 0.5s per 10 seconds of video) | |
| base_time = 3.0 | |
| time_per_second = 0.5 | |
| simulated_delay = base_time + (duration_s / 10 * time_per_second) | |
| # Cap the delay for user experience | |
| if simulated_delay > 15: | |
| simulated_delay = 15 + random.uniform(0, 5) # Max 20s simulation | |
| time.sleep(simulated_delay) | |
| # Mock generation metadata | |
| output = { | |
| "status": "success", | |
| "video_url": MOCK_VIDEO_URL, | |
| "duration_s": duration_s, | |
| "prompt_used": prompt, | |
| "model_version": "Sora 2.1 (Simulated)", | |
| "cost": round(duration_s * 0.05 + random.uniform(0.5, 1.5), 2), # Mock Cost calculation | |
| "audio_description": MOCK_AUDIO_DESCRIPTION if generate_audio else None | |
| } | |
| return output | |
| === streamlit_app.py === | |
| import streamlit as st | |
| from PIL import Image | |
| import io | |
| from config import ( | |
| APP_TITLE, ANYCODER_LINK, ANYCODER_TEXT, | |
| MIN_DURATION_S, MAX_DURATION_S, DEFAULT_DURATION_S, | |
| GENERATION_COST_PER_SECOND, DISCLAIMER | |
| ) | |
| from utils import simulate_video_generation | |
| # --- Configuration and Setup --- | |
| st.set_page_config( | |
| page_title=APP_TITLE, | |
| layout="wide", | |
| initial_sidebar_state="expanded" | |
| ) | |
| # Initialize Session State | |
| if 'generation_output' not in st.session_state: | |
| st.session_state.generation_output = None | |
| if 'is_running' not in st.session_state: | |
| st.session_state.is_running = False | |
| def clear_output(): | |
| """Clears the previous generation results.""" | |
| st.session_state.generation_output = None | |
| def handle_generation(prompt, image_file, duration_s, generate_audio): | |
| """Handles the submission and simulation process.""" | |
| if st.session_state.is_running: | |
| st.warning("A generation task is already running. Please wait.") | |
| return | |
| st.session_state.is_running = True | |
| clear_output() | |
| input_prompt = prompt | |
| if image_file: | |
| # Simulate processing the image input | |
| input_prompt = f"Image-to-Video: {image_file.name}. Prompt: {prompt}" | |
| try: | |
| # Display feedback and run simulation | |
| with st.spinner(f"Generating high-fidelity video sequence ({duration_s}s)... This may take up to 20 seconds."): | |
| output = simulate_video_generation(input_prompt, duration_s, generate_audio) | |
| st.session_state.generation_output = output | |
| st.balloons() | |
| st.success("Video generation complete!") | |
| except Exception as e: | |
| st.error(f"An error occurred during simulation: {e}") | |
| finally: | |
| st.session_state.is_running = False | |
| st.rerun() | |
| # --- Sidebar UI --- | |
| with st.sidebar: | |
| st.title("Sora 2 Controls") | |
| st.markdown( | |
| f""" | |
| **Maximum Duration:** {MAX_DURATION_S // 60}m {MAX_DURATION_S % 60}s | |
| **Input Modes:** Text-to-Video, Image-to-Video | |
| """ | |
| ) | |
| # Custom CSS for the sidebar link | |
| st.markdown( | |
| f""" | |
| <style> | |
| .footer-link {{ | |
| font-size: 0.8rem; | |
| color: #888888; | |
| margin-top: 15px; | |
| }} | |
| </style> | |
| <div class="footer-link"> | |
| <a href="{ANYCODER_LINK}" target="_blank">{ANYCODER_TEXT}</a> | |
| </div> | |
| """, | |
| unsafe_allow_html=True | |
| ) | |
| # --- Main Application UI --- | |
| st.markdown(f"## {APP_TITLE}") | |
| st.caption(DISCLAIMER) | |
| st.divider() | |
| # Input Form | |
| with st.form("sora_generation_form", clear_on_submit=False): | |
| col1, col2 = st.columns([3, 1]) | |
| with col1: | |
| prompt = st.text_area( | |
| "🎬 Describe your desired scene (Text-to-Video)", | |
| placeholder="A golden retriever wearing a tiny chef's hat, baking bread on a cloud, cinematic 8K, highly detailed.", | |
| height=100 | |
| ) | |
| with col2: | |
| image_file = st.file_uploader( | |
| "🖼️ Upload starting image (Image-to-Video)", | |
| type=["png", "jpg", "jpeg"], | |
| help="Optional: Start the video generation from a specific image." | |
| ) | |
| if image_file: | |
| st.image(image_file, caption="Input Image Preview", use_column_width=True) | |
| st.subheader("Generation Settings") | |
| settings_col1, settings_col2, settings_col3 = st.columns(3) | |
| with settings_col1: | |
| video_duration = st.slider( | |
| "⏱️ Video Duration (seconds)", | |
| min_value=MIN_DURATION_S, | |
| max_value=MAX_DURATION_S, | |
| value=DEFAULT_DURATION_S, | |
| step=1, | |
| help=f"Generates videos from {MIN_DURATION_S}s up to 2 minutes." | |
| ) | |
| with settings_col2: | |
| generate_audio = st.checkbox( | |
| "🔊 Generate Realistic Audio Track", | |
| value=True, | |
| help="Sora 2 includes synchronized, high-fidelity audio generation." | |
| ) | |
| with settings_col3: | |
| # Mock Cost Display | |
| mock_cost = round(video_duration * GENERATION_COST_PER_SECOND, 2) | |
| st.metric( | |
| label="Estimated Token Cost (Mock)", | |
| value=f"${mock_cost:.2f}", | |
| delta=f"${GENERATION_COST_PER_SECOND} / second" | |
| ) | |
| st.markdown("---") | |
| # Disable button if inputs are missing | |
| is_disabled = not (prompt or image_file) or st.session_state.is_running | |
| submit_button = st.form_submit_button( | |
| label="⚡ Generate Video (Simulated)", | |
| type="primary", | |
| disabled=is_disabled | |
| ) | |
| if submit_button: | |
| if not prompt and image_file: | |
| st.warning("Please provide a text prompt to guide the video generation, even if uploading an image.") | |
| elif not prompt and not image_file: | |
| st.error("Please provide either a text description or an image file to start.") | |
| else: | |
| handle_generation(prompt, image_file, video_duration, generate_audio) | |
| # --- Output Display --- | |
| if st.session_state.generation_output: | |
| output = st.session_state.generation_output | |
| st.subheader("🎥 Sora 2 Simulated Output") | |
| st.info(f"Generated successfully in {output['duration_s']} seconds using **{output['model_version']}**.") | |
| # Layout for metadata and video | |
| output_col1, output_col2 = st.columns([1, 2]) | |
| with output_col1: | |
| st.markdown("**Generation Metadata**") | |
| st.json({ | |
| "Prompt Input": output['prompt_used'][:100] + "...", | |
| "Output Duration": f"{output['duration_s']} seconds", | |
| "Simulated Cost": f"${output['cost']:.2f}", | |
| }) | |
| st.download_button( | |
| label="⬇️ Download Video (Mock File)", | |
| data="This is a simulated download link.", | |
| file_name="sora_output_simulated.mp4", | |
| mime="text/plain", | |
| type="secondary" | |
| ) | |
| with output_col2: | |
| st.markdown("### Video Output (Public Placeholder)") | |
| st.video(output['video_url'], format="video/mp4", start_time=0) | |
| if output['audio_description']: | |
| st.markdown("### Audio Track") | |
| st.markdown(f"**Description:** {output['audio_description']}") | |
| # Streamlit audio component using a simple placeholder representation | |
| st.audio(data=b'', format="audio/mp3", loop=False) | |
| st.caption("Audio component is displayed, simulating a synchronized audio track.") |