File size: 4,487 Bytes
8f7c473 | 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 155 156 | """
Video Showcase API
FastAPI โ ุจุชุจุนุชูู ุจูุงูุงุช ุงูู
ูุชุฌุ ุจูุฑุฌุนูู ููุฏูู
"""
import os
import uuid
from fastapi import FastAPI, HTTPException, BackgroundTasks
from fastapi.responses import FileResponse, JSONResponse
from pydantic import BaseModel
from typing import Optional
from templates import get_template, list_templates
from templates.base import RenderRequest
from renderer import render_video
app = FastAPI(
title="Video Showcase API",
description="ุจูุนู
ู ููุฏูู Product Showcase ุชููุงุฆู",
version="1.0.0"
)
OUTPUT_DIR = "/tmp/videos"
os.makedirs(OUTPUT_DIR, exist_ok=True)
# ============================================================
# Models
# ============================================================
class VideoRequest(BaseModel):
# --- ู
ุทููุจ ---
template: str = "showcase_arabic"
title: str
# --- ุงุฎุชูุงุฑู ---
discount: Optional[str] = ""
badge: Optional[str] = ""
phone: Optional[str] = ""
website: Optional[str] = ""
image_path: Optional[str] = ""
music_path: Optional[str] = ""
bg_left: Optional[str] = ""
bg_right: Optional[str] = ""
duration: Optional[int] = 6
fps: Optional[int] = 30
width: Optional[int] = 1280
height: Optional[int] = 720
music_volume: Optional[float] = 0.20
# ============================================================
# Routes
# ============================================================
@app.get("/")
def root():
return {
"status": "running",
"message": "Video Showcase API ุดุบุงู โ
",
"endpoints": {
"GET /templates": "ุดูู ุงูุชู
ุจูุชุณ ุงูู
ุชุงุญุฉ",
"POST /render": "ุงุนู
ู ููุฏูู",
"GET /video/{video_id}": "ุญู
ูู ุงูููุฏูู",
"GET /health": "Health check"
}
}
@app.get("/health")
def health():
return {"status": "ok"}
@app.get("/templates")
def get_templates():
"""ุดูู ูู ุงูุชู
ุจูุชุณ ุงูู
ุชุงุญุฉ"""
return {
"templates": list_templates(),
"count": len(list_templates())
}
@app.post("/render")
def render(req: VideoRequest):
"""
ุงุนู
ู ููุฏูู
ู
ุซุงู ู
ู n8n:
POST /render
{
"template": "showcase_arabic",
"title": "ุงุญุฏุซ ุงุฌูุฒุฉ\\nููุฑุจุงุฆูุฉ",
"discount": "ุฎุตู
20ูช",
"image_path": "/tmp/product.png",
"music_path": "/tmp/music.mp3"
}
"""
# ุชุญูู ู
ู ุงูุชู
ุจูุช
try:
template = get_template(req.template)
except ValueError as e:
raise HTTPException(status_code=404, detail=str(e))
# ID ูุฑูุฏ ููููุฏูู
video_id = str(uuid.uuid4())[:8]
output = os.path.join(OUTPUT_DIR, f"{video_id}.mp4")
# ุนู
ู ุงูู RenderRequest
render_req = RenderRequest(
title = req.title,
discount = req.discount or "",
badge = req.badge or "",
phone = req.phone or "",
website = req.website or "",
image_path = req.image_path or "",
music_path = req.music_path or "",
output_path = output,
bg_left = req.bg_left or "",
bg_right = req.bg_right or "",
duration = req.duration or 6,
fps = req.fps or 30,
width = req.width or 1280,
height = req.height or 720,
music_volume = req.music_volume or 0.20,
)
# Render
try:
final_path = render_video(template, render_req)
except Exception as e:
raise HTTPException(status_code=500, detail=f"ุฎุทุฃ ูู ุงูู render: {str(e)}")
size_mb = os.path.getsize(final_path) / 1024 / 1024
return {
"status": "success",
"video_id": video_id,
"download": f"/video/{video_id}",
"size_mb": round(size_mb, 2),
"template": req.template,
}
@app.get("/video/{video_id}")
def download_video(video_id: str):
"""ุญู
ูู ุงูููุฏูู"""
path = os.path.join(OUTPUT_DIR, f"{video_id}.mp4")
if not os.path.exists(path):
raise HTTPException(status_code=404, detail="ุงูููุฏูู ู
ุด ู
ูุฌูุฏ ุฃู ุงุชู
ุณุญ")
return FileResponse(
path,
media_type="video/mp4",
filename=f"showcase_{video_id}.mp4"
)
|