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