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()
    )