File size: 1,900 Bytes
b08c203
 
 
 
 
3447b95
 
 
b08c203
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
from fastapi import FastAPI, UploadFile, Form
from fastapi.responses import FileResponse
import uuid
import os
import subprocess

app = FastAPI()

# Overlay 和字体资源路径(固定)
FONT_PATH = "/app/assets/fonts/FonderLTHTCH.ttf"
OVERLAY_PATH = "/app/assets/overlays/dust_particles-1.mp4"

@app.post("/render")
async def render_video(
    image: UploadFile,
    audio: UploadFile,
    fps: int = Form(...),
    filter_complex: str = Form(...),
    preset: str = Form(...),
    filename: str = Form(...),
    video_path: str = Form(...),
    shortest: bool = Form(True),
):
    # 文件处理
    image_ext = image.filename.split(".")[-1]
    audio_ext = audio.filename.split(".")[-1]
    image_path = f"/tmp/{uuid.uuid4()}.{image_ext}"
    audio_path = f"/tmp/{uuid.uuid4()}.{audio_ext}"
    output_path = f"{video_path.rstrip('/')}/{filename}.mp4"

    # 保存上传的 image 和 audio
    with open(image_path, "wb") as f:
        f.write(await image.read())
    with open(audio_path, "wb") as f:
        f.write(await audio.read())

    # 构造 FFmpeg 命令
    cmd = [
        "ffmpeg", "-y", "-nostdin", "-hide_banner", "-loglevel", "error",
        "-loop", "1", "-framerate", str(fps), "-i", image_path,
        "-i", OVERLAY_PATH,
        "-i", audio_path,
        "-filter_complex", filter_complex,
        "-map", "[v]", "-map", "2:a",
        "-c:v", "libx264", "-preset", preset, "-pix_fmt", "yuv420p",
        "-c:a", "aac", "-b:a", "192k",
        "-movflags", "+faststart",
        "-metadata", f"title={filename}"
    ]

    if shortest:
        cmd.append("-shortest")

    cmd.append(output_path)

    # 确保目标路径存在(仅用于 Space /tmp 测试)
    os.makedirs(os.path.dirname(output_path), exist_ok=True)

    # 执行 FFmpeg
    subprocess.run(cmd, check=True)

    return FileResponse(output_path, media_type="video/mp4", filename=f"{filename}.mp4")