File size: 2,314 Bytes
e5904b8 50debba e5904b8 50debba e5904b8 3668c2d 0786006 3668c2d e5904b8 3668c2d e5904b8 7287532 50debba 7287532 50debba 7287532 e5904b8 | 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 | from fastapi import FastAPI, UploadFile, File, Form
from fastapi.responses import FileResponse, JSONResponse
from gradio_client import Client, handle_file
from gradio_client.exceptions import AppError
import tempfile
import os
import shutil
HF_TOKEN = os.getenv("HF_TOKEN")
app = FastAPI(title="ZHSAPI")
@app.get("/health")
def health():
return {"status": "ok"}
@app.post("/timelapse")
async def generate_timelapse(
start_frame: UploadFile = File(...),
end_frame: UploadFile = File(...),
prompt: str = Form(default="a construction timelapse"),
):
with tempfile.TemporaryDirectory() as tmpdir:
start_path = os.path.join(tmpdir, start_frame.filename)
end_path = os.path.join(tmpdir, end_frame.filename)
with open(start_path, "wb") as f:
shutil.copyfileobj(start_frame.file, f)
with open(end_path, "wb") as f:
shutil.copyfileobj(end_frame.file, f)
# Try diffusion model first, fall back to CPU FILM interpolation on quota error
try:
client = Client("linoyts/LTX-2-3-First-Last-Frame", token=HF_TOKEN)
result = client.predict(
first_image=handle_file(start_path),
last_image=handle_file(end_path),
input_audio=None,
prompt=prompt,
api_name="/generate_video",
)
output_path = result[0] if isinstance(result, (list, tuple)) else result
except AppError as e:
if "GPU quota" not in str(e):
return JSONResponse(status_code=502, content={"error": str(e)})
# Fallback: CPU-based FILM interpolation (no GPU quota)
film = Client("freealise/video_frame_interpolation")
loaded = film.predict(
f=[handle_file(start_path), handle_file(end_path)],
r_bg=False,
api_name="/loadf",
)
frames = loaded[0]
result = film.predict(
f_in=frames,
interpolation=4,
fps_output=0,
api_name="/infer",
)
output_path = result[0]["video"] if isinstance(result[0], dict) else result[0]
return FileResponse(output_path, media_type="video/mp4", filename="timelapse.mp4")
|