import streamlit as st import os from pathlib import Path import time import base64 from PIL import Image import io import cv2 import numpy as np from fastapi import FastAPI, File, UploadFile, Form from fastapi.middleware.wsgi import WSGIMiddleware from starlette.responses import JSONResponse # Set page config st.set_page_config(page_title="UltraVideoSpace", layout="wide", initial_sidebar_state="collapsed") # Custom CSS st.markdown(""" """, unsafe_allow_html=True) # FastAPI app app = FastAPI() @app.post("/upload_chunk") async def upload_chunk(file: UploadFile = File(...), chunk_number: int = Form(...), total_chunks: int = Form(...)): chunk_data = await file.read() save_chunk(chunk_data, file.filename, chunk_number) if chunk_number == total_chunks - 1: reassemble_file(file.filename, total_chunks) return JSONResponse(content={"message": "Chunk uploaded successfully"}) # Wrap Streamlit app streamlit_app = WSGIMiddleware(app) def save_chunk(chunk, filename, chunk_number): save_path = Path("uploaded_chunks") save_path.mkdir(exist_ok=True) file_path = save_path / f"{filename}.part{chunk_number}" with file_path.open("wb") as f: f.write(chunk) def reassemble_file(filename, total_chunks): save_path = Path("uploaded_videos") save_path.mkdir(exist_ok=True) file_path = save_path / filename with file_path.open("wb") as outfile: for i in range(total_chunks): chunk_path = Path("uploaded_chunks") / f"{filename}.part{i}" with chunk_path.open("rb") as infile: outfile.write(infile.read()) os.remove(chunk_path) def get_uploaded_videos(): video_dir = Path("uploaded_videos") video_dir.mkdir(exist_ok=True) return [f for f in video_dir.glob("*") if f.suffix.lower() in ['.mp4', '.mkv', '.avi', '.mov', '.mpeg4']] def generate_thumbnail(video_path): try: video = cv2.VideoCapture(str(video_path)) success, image = video.read() if success: image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) image = Image.fromarray(image) image.thumbnail((300, 168)) buffered = io.BytesIO() image.save(buffered, format="PNG") return base64.b64encode(buffered.getvalue()).decode() except Exception as e: st.warning(f"Could not generate thumbnail for {video_path.name}: {str(e)}") return None def main(): st.markdown("

UltraVideoSpace

", unsafe_allow_html=True) st.markdown("""

Drag and drop your video here

or click to select files

Supported formats: MP4, MKV, AVI, MOV, MPEG4

No file size limit (files will be split if larger than 200MB)

""", unsafe_allow_html=True) # File uploader and chunked upload handling st.markdown(""" """, unsafe_allow_html=True) # Display uploaded videos st.markdown("

Your Video Collection

", unsafe_allow_html=True) videos = get_uploaded_videos() if not videos: st.info("Your video collection is empty. Upload some videos to get started!") else: video_grid = "
" for video in videos: thumbnail = generate_thumbnail(video) thumbnail_url = f"data:image/png;base64,{thumbnail}" if thumbnail else "https://via.placeholder.com/300x168.png?text=Video+Thumbnail" video_grid += f"""
{video.name}
{video.name}
""" video_grid += "
" st.markdown(video_grid, unsafe_allow_html=True) selected_video = st.selectbox("Select a video to play", [v.name for v in videos]) if selected_video: video_path = f"uploaded_videos/{selected_video}" st.video(video_path) if __name__ == "__main__": main()