Spaces:
Sleeping
Sleeping
File size: 4,620 Bytes
1aa90a9 422568b 1aa90a9 422568b 1aa90a9 422568b 1aa90a9 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from fastapi.responses import FileResponse
import logging
from pathlib import Path
import sys
# Import config and routers
from config import config
from routers import api
from video_creator.libraries.tts_client import TTSClient
from video_creator.libraries.whisper_client import WhisperClient
from video_creator.libraries.pexels_client import PexelsClient
from video_creator.music_manager import MusicManager
from video_creator.short_creator import ShortCreator
# Setup logging
logging.basicConfig(
level=config.log_level.upper(),
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[logging.StreamHandler(sys.stdout)]
)
logger = logging.getLogger(__name__)
# Create FastAPI app
app = FastAPI(
title="Short Video Maker API",
description="""
# Short Video Maker REST API
Create engaging short-form videos for TikTok, Instagram Reels, and YouTube Shorts.
## Features
- 🎙️ Text-to-speech narration (Kokoro)
- 📝 Automatic caption generation (Whisper)
- 🎥 Background videos from Pexels
- 🎵 Background music with mood selection
- 📱 Portrait & landscape support
## Workflow
1. **Create Video**: POST to `/api/short-video` with scenes and config
2. **Check Status**: GET `/api/short-video/{id}/status` to monitor progress
3. **Download**: GET `/api/short-video/{id}` when status is "ready"
## Environment Setup
Required environment variables:
- `PEXELS_API_KEY` - Get from https://www.pexels.com/api/
- `HF_TTS` - Your TTS service endpoint URL
""",
version="2.0.0",
contact={
"name": "Short Video Maker",
"url": "https://huggingface.co/spaces"
}
)
# Add CORS middleware
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
@app.on_event("startup")
async def startup_event():
"""Initialize services on startup"""
logger.info("Starting Short Video Maker on Hugging Face Spaces...")
# Ensure directories exist
config.ensure_directories()
# Validate environment variables
# Validate environment variables
if not config.pexels_api_key:
logger.warning("PEXELS_API_KEY is missing! Video generation will fail.")
if not config.hf_tts:
logger.warning("HF_TTS is missing! TTS will fail.")
# Initialize components
logger.info("Initializing TTS client...")
tts_client = TTSClient(config.hf_tts)
logger.info("Initializing Whisper client...")
whisper_client = WhisperClient(
model_name=config.whisper_model,
model_dir=config.whisper_model_dir
)
logger.info("Initializing Pexels client...")
pexels_client = PexelsClient(config.pexels_api_key)
logger.info("Initializing music manager...")
music_manager = MusicManager(config.music_dir_path)
try:
music_manager.ensure_music_files_exist()
except FileNotFoundError as e:
logger.error(f"Music setup error: {e}")
logger.warning("Creating empty music directory - you'll need to add music files")
config.music_dir_path.mkdir(parents=True, exist_ok=True)
logger.info("Initializing short creator...")
short_creator = ShortCreator(
config=config,
tts_client=tts_client,
whisper_client=whisper_client,
pexels_client=pexels_client,
music_manager=music_manager
)
# Set the global short creator in the router
api.set_short_creator(short_creator)
logger.info("Short Video Maker started successfully!")
logger.info(f"Server running on port {config.port}")
@app.get("/health")
async def health_check():
"""Health check endpoint"""
return {"status": "ok"}
@app.get("/")
async def read_root():
"""Serve the web UI"""
static_path = Path(__file__).parent / "static" / "index.html"
if static_path.exists():
return FileResponse(static_path)
return {"message": "Short Video Maker API", "docs": "/docs"}
# Include API router
app.include_router(api.router)
# Mount static files if they exist
static_dir = Path(__file__).parent / "static"
if static_dir.exists():
app.mount("/static", StaticFiles(directory=str(static_dir)), name="static")
if __name__ == "__main__":
import uvicorn
uvicorn.run(
"app:app",
host="0.0.0.0",
port=config.port,
log_level=config.log_level.lower()
)
|