Spaces:
Running
Running
File size: 3,751 Bytes
d674fad 97e8589 dbacd04 d674fad dbacd04 d674fad dbacd04 d674fad dbacd04 97e8589 dbacd04 3721375 dbacd04 d674fad 3721375 97e8589 3721375 97e8589 3721375 97e8589 964ccb3 3721375 97e8589 3721375 97e8589 3721375 97e8589 3721375 97e8589 3721375 97e8589 3721375 97e8589 3721375 97e8589 3721375 dbacd04 bec5db9 97e8589 dbacd04 bec5db9 d674fad dbacd04 d674fad 97e8589 dbacd04 3721375 dbacd04 3721375 dbacd04 3721375 dbacd04 d674fad 3721375 dbacd04 d674fad 3721375 726d41b 5782dca 3721375 d674fad 3721375 d674fad |
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 |
import os
import shutil
import uuid
from fastapi import FastAPI, UploadFile, File, HTTPException, Request, BackgroundTasks
from fastapi.responses import FileResponse, HTMLResponse
from fastapi.templating import Jinja2Templates
app = FastAPI(title="Golf Tech Analysis API")
UPLOAD_DIR = "uploads"
TEMPLATES_DIR = "templates"
os.makedirs(UPLOAD_DIR, exist_ok=True)
os.makedirs(TEMPLATES_DIR, exist_ok=True)
# Templates
templates = Jinja2Templates(directory=TEMPLATES_DIR)
# Import optimized pipeline
from main import analyze_video_fast
from reengineer import reengineer_video
@app.get("/")
async def root(request: Request):
"""
Giao diện upload để test (cho developer).
"""
return templates.TemplateResponse("index.html", {"request": request})
@app.post("/")
async def analyze_with_video(
file: UploadFile = File(...), background_tasks: BackgroundTasks = None
):
"""
UI endpoint: Phân tích + Tạo video có overlay.
Trả về video để download.
"""
job_id = str(uuid.uuid4())
video_ext = os.path.splitext(file.filename)[1]
video_path = os.path.join(UPLOAD_DIR, f"{job_id}{video_ext}")
output_dir = os.path.join("output", job_id)
os.makedirs(output_dir, exist_ok=True)
try:
# Lưu video
with open(video_path, "wb") as buffer:
shutil.copyfileobj(file.file, buffer)
# Phân tích (lưu vào output/)
master_json = os.path.join(output_dir, "master_data.json")
result = analyze_video_fast(
video_path, production=True, output_file=master_json, output_base="output"
)
# Tạo video có overlay
output_video = os.path.join(output_dir, "analyzed_video.mp4")
reengineer_video(master_json, video_path, output_video, production=True)
# Cleanup video gốc
if os.path.exists(video_path):
os.remove(video_path)
# Schedule cleanup after response
def cleanup():
try:
if os.path.exists(output_dir):
shutil.rmtree(output_dir, ignore_errors=True)
except:
pass
if background_tasks:
background_tasks.add_task(cleanup)
# Trả về video file
return FileResponse(
output_video, media_type="video/mp4", filename=f"golf_analysis_{job_id}.mp4"
)
except Exception as e:
if os.path.exists(video_path):
os.remove(video_path)
if os.path.exists(output_dir):
shutil.rmtree(output_dir, ignore_errors=True)
raise HTTPException(status_code=500, detail=str(e))
@app.post("/api/analyze")
async def api_analyze(file: UploadFile = File(...)):
"""
Pure API endpoint: Chỉ trả JSON, không tạo video.
Dùng cho app/web production.
"""
job_id = str(uuid.uuid4())
video_ext = os.path.splitext(file.filename)[1]
video_path = os.path.join(UPLOAD_DIR, f"{job_id}{video_ext}")
try:
# Lưu video tạm thời
with open(video_path, "wb") as buffer:
shutil.copyfileobj(file.file, buffer)
# Gọi optimized pipeline (KHÔNG tạo video)
result = analyze_video_fast(video_path, production=True)
# Cleanup
if os.path.exists(video_path):
os.remove(video_path)
return result
except Exception as e:
if os.path.exists(video_path):
os.remove(video_path)
raise HTTPException(status_code=500, detail=str(e))
# Check health (GET, HEAD)
@app.api_route("/api/health", methods=["GET", "HEAD"])
async def health_check():
return {"status": "ok"}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=7860)
|