Spaces:
Sleeping
Sleeping
| """ | |
| Streamlit app for generating videos using Azure Sora API. | |
| - Users provide an API key, endpoint, and a text prompt. | |
| - Advanced settings allow selection of video resolution, length, and number of variants. | |
| - Generated videos are stored and displayed for all users. | |
| """ | |
| import streamlit as st | |
| import os | |
| from sora_video_downloader import SoraClient, VideoJob, VideoStorage | |
| # --- Hardcoded for testing, but can be made user-editable --- | |
| DEFAULT_API_KEY = os.getenv('AZURE_OPENAI_API_KEY', 'YOUR_AZURE_API_KEY') | |
| DEFAULT_ENDPOINT = os.getenv('AZURE_OPENAI_ENDPOINT', 'https://levm3-me7f7pgq-eastus2.cognitiveservices.azure.com') | |
| # --- UI: Title and Sidebar --- | |
| st.title("Sora Video Generator (Azure)") | |
| st.sidebar.header("Azure Sora Settings") | |
| api_key = st.sidebar.text_input("API Key", value=DEFAULT_API_KEY, type="password") | |
| endpoint = st.sidebar.text_input("Azure AI Foundry Endpoint", value=DEFAULT_ENDPOINT) | |
| # --- UI: Main Input --- | |
| st.header("Generate a Video with Sora") | |
| prompt = st.text_area("Video Prompt", "A video of a cat playing with a ball of yarn in a sunny room") | |
| # --- UI: Advanced Settings --- | |
| st.subheader("Advanced Settings") | |
| col1, col2 = st.columns(2) | |
| DURATION_RES_MAP = { | |
| 5: [ | |
| (480, 480), (854, 480), (720, 720), (1280, 720), (1080, 1080), (1920, 1080) | |
| ], | |
| 10: [ | |
| (480, 480), (854, 480), (720, 720), (1280, 720), (1080, 1080) | |
| ], | |
| 20: [ | |
| (480, 480), (854, 480), (720, 720), (1280, 720) | |
| ] | |
| } | |
| with col1: | |
| n_seconds = st.selectbox("Video Length (seconds)", options=[5, 10, 20], index=0) | |
| valid_resolutions = DURATION_RES_MAP[n_seconds] | |
| res_labels = [f"{w}x{h}" for (w, h) in valid_resolutions] | |
| res_idx = st.selectbox("Resolution", options=list(range(len(res_labels))), format_func=lambda i: res_labels[i], index=0) | |
| width, height = valid_resolutions[res_idx] | |
| with col2: | |
| n_variants = st.slider("Number of Variants", min_value=1, max_value=4, value=1) | |
| # --- Video Generation Logic --- | |
| generate = st.button("Generate Video") | |
| status_placeholder = st.empty() | |
| video_storage = VideoStorage() | |
| if generate: | |
| # Validate required fields | |
| if not api_key or not endpoint or not prompt.strip(): | |
| st.error("Please provide all required fields.") | |
| else: | |
| status_placeholder.info("Starting video generation...") | |
| sora = SoraClient(api_key, endpoint) | |
| job = VideoJob(sora, prompt, height=height, width=width, n_seconds=n_seconds, n_variants=n_variants) | |
| if job.run(): | |
| saved_files = job.download_videos(video_storage.storage_dir) | |
| if saved_files: | |
| status_placeholder.success(f"Video(s) generated and saved: {', '.join([os.path.basename(f) for f in saved_files])}") | |
| else: | |
| status_placeholder.error("Video generation succeeded but download failed.") | |
| else: | |
| status_placeholder.error("Video generation failed.") | |
| # --- Display All Generated Videos --- | |
| st.header("All Generated Videos") | |
| video_files = video_storage.list_videos() | |
| if not video_files: | |
| st.info("No videos generated yet.") | |
| else: | |
| for video_path in sorted(video_files, reverse=True): | |
| st.video(video_path) | |
| st.caption(os.path.basename(video_path)) | |
| st.download_button("Download", data=open(video_path, "rb").read(), file_name=os.path.basename(video_path), mime="video/mp4") |