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)