Spaces:
Runtime error
Runtime error
| import streamlit as st | |
| import os | |
| import tempfile | |
| import time | |
| from datetime import timedelta | |
| import pandas as pd | |
| import numpy as np | |
| from typing import Optional, Tuple, List | |
| import plotly.graph_objects as go | |
| from utils import ( | |
| process_video_upload, | |
| extract_video_info, | |
| create_timeline_figure, | |
| apply_editing_effects, | |
| export_video | |
| ) | |
| # Set page config | |
| st.set_page_config( | |
| page_title="VideoCoF - Unified Video Editing", | |
| page_icon="π₯", | |
| layout="wide", | |
| initial_sidebar_state="expanded" | |
| ) | |
| # Custom CSS for modern styling | |
| st.markdown(""" | |
| <style> | |
| .main-header { | |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
| padding: 2rem; | |
| border-radius: 10px; | |
| margin-bottom: 2rem; | |
| color: white; | |
| } | |
| .stButton>button { | |
| background-color: #667eea; | |
| color: white; | |
| border-radius: 5px; | |
| border: none; | |
| padding: 0.5rem 1rem; | |
| transition: all 0.3s; | |
| } | |
| .stButton>button:hover { | |
| background-color: #5a67d8; | |
| transform: translateY(-1px); | |
| } | |
| .sidebar .sidebar-content { | |
| background-color: #f8f9fa; | |
| } | |
| .video-container { | |
| border-radius: 10px; | |
| overflow: hidden; | |
| box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); | |
| } | |
| .timeline-container { | |
| background-color: #ffffff; | |
| border-radius: 10px; | |
| padding: 1rem; | |
| box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); | |
| } | |
| </style> | |
| """) | |
| # Header with anycoder link | |
| st.markdown(""" | |
| <div class="main-header"> | |
| <h1>π₯ VideoCoF</h1> | |
| <p style="font-size: 1.2rem; margin: 0;">Unified Video Editing with Temporal Reasoner</p> | |
| <div style="margin-top: 1rem;"> | |
| <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" style="color: white; text-decoration: underline;"> | |
| Built with anycoder | |
| </a> | |
| </div> | |
| </div> | |
| """, unsafe_allow_html=True) | |
| # Initialize session state | |
| if 'video_file' not in st.session_state: | |
| st.session_state.video_file = None | |
| if 'video_info' not in st.session_state: | |
| st.session_state.video_info = None | |
| if 'edited_video' not in st.session_state: | |
| st.session_state.edited_video = None | |
| if 'timeline_data' not in st.session_state: | |
| st.session_state.timeline_data = None | |
| if 'is_processing' not in st.session_state: | |
| st.session_state.is_processing = False | |
| # Sidebar for controls | |
| with st.sidebar: | |
| st.header("ποΈ Controls") | |
| # Video upload section | |
| st.subheader("Upload Video") | |
| uploaded_file = st.file_uploader( | |
| "Choose a video file", | |
| type=["mp4", "avi", "mov", "mkv"], | |
| help="Supported formats: MP4, AVI, MOV, MKV" | |
| ) | |
| if uploaded_file and not st.session_state.is_processing: | |
| if st.button("Load Video", type="primary"): | |
| st.session_state.is_processing = True | |
| with st.spinner("Processing video..."): | |
| # Process the uploaded video | |
| temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.mp4') | |
| temp_file.write(uploaded_file.read()) | |
| temp_file.close() | |
| # Extract video info | |
| video_info = extract_video_info(temp_file.name) | |
| st.session_state.video_info = video_info | |
| # Create timeline data | |
| st.session_state.timeline_data = create_timeline_figure(video_info) | |
| # Store video file | |
| st.session_state.video_file = temp_file.name | |
| # Clean up | |
| os.unlink(temp_file.name) | |
| st.session_state.is_processing = False | |
| st.rerun() | |
| # Main content area | |
| if st.session_state.video_file: | |
| # Video player section | |
| st.subheader("π¬ Video Player") | |
| col1, col2 = st.columns([3, 1]) | |
| with col1: | |
| st.video(st.session_state.video_file) | |
| with col2: | |
| if st.session_state.video_info: | |
| st.metric("Duration", f"{st.session_state.video_info['duration']:.2f}s") | |
| st.metric("Resolution", f"{st.session_state.video_info['width']}Γ{st.session_state.video_info['height']}") | |
| st.metric("FPS", f"{st.session_state.video_info['fps']}") | |
| # Timeline section | |
| st.subheader("β±οΈ Timeline Editor") | |
| if st.session_state.timeline_data: | |
| st.plotly_chart(st.session_state.timeline_data, use_container_width=True) | |
| # Editing controls | |
| st.subheader("βοΈ Editing Tools") | |
| editing_tabs = st.tabs(["Trim", "Effects", "Filters", "Speed"]) | |
| with editing_tabs[0]: # Trim tab | |
| col1, col2 = st.columns(2) | |
| with col1: | |
| start_time = st.slider( | |
| "Start Time", | |
| 0.0, | |
| st.session_state.video_info['duration'], | |
| 0.0, | |
| step=0.1, | |
| help="Set the start time of the video segment" | |
| ) | |
| with col2: | |
| end_time = st.slider( | |
| "End Time", | |
| 0.0, | |
| st.session_state.video_info['duration'], | |
| st.session_state.video_info['duration'], | |
| step=0.1, | |
| help="Set the end time of the video segment" | |
| ) | |
| with editing_tabs[1]: # Effects tab | |
| effects = st.multiselect( | |
| "Apply Effects", | |
| ["Fade In", "Fade Out", "Crossfade", "Blur", "Sharpen"], | |
| help="Select effects to apply to the video" | |
| ) | |
| with editing_tabs[2]: # Filters tab | |
| filters = st.selectbox( | |
| "Video Filter", | |
| ["None", "Grayscale", "Sepia", "Vintage", "Cool", "Warm"], | |
| help="Apply a visual filter to the video" | |
| ) | |
| with editing_tabs[3]: # Speed tab | |
| speed = st.slider( | |
| "Playback Speed", | |
| 0.25, | |
| 2.0, | |
| 1.0, | |
| step=0.25, | |
| help="Adjust the playback speed of the video" | |
| ) | |
| # Apply edits button | |
| if st.button("Apply Edits", type="primary"): | |
| with st.spinner("Applying edits..."): | |
| st.session_state.edited_video = apply_editing_effects( | |
| st.session_state.video_file, | |
| start_time, | |
| end_time, | |
| effects, | |
| filters, | |
| speed | |
| ) | |
| st.success("Edits applied successfully!") | |
| # Export section | |
| st.subheader("πΎ Export Options") | |
| export_format = st.selectbox( | |
| "Export Format", | |
| ["MP4", "AVI", "MOV"], | |
| help="Choose the output format for your edited video" | |
| ) | |
| if st.session_state.edited_video: | |
| col1, col2 = st.columns([1, 1]) | |
| with col1: | |
| if st.button("Download Edited Video"): | |
| with open(st.session_state.edited_video, "rb") as file: | |
| st.download_button( | |
| label="Download", | |
| data=file, | |
| file_name=f"edited_video.{export_format.lower()}", | |
| mime=f"video/{export_format.lower()}" | |
| ) | |
| with col2: | |
| if st.button("Export to Cloud"): | |
| st.info("Cloud export functionality coming soon!") | |
| else: | |
| st.info("π Please upload a video file to get started with VideoCoF!") |