CoolFace
Apppublic

datasea/ffmpeg-video-render

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes
app.py62 linesDownload Raw Back to root
1from fastapi import FastAPI, UploadFile, Form2from fastapi.responses import FileResponse3import uuid4import os5import subprocess6 7app = FastAPI()8 9# Overlay 和字体资源路径(固定)10FONT_PATH = "/app/assets/fonts/FonderLTHTCH.ttf"11OVERLAY_PATH = "/app/assets/overlays/dust_particles-1.mp4"12 13@app.post("/render")14async def render_video(15    image: UploadFile,16    audio: UploadFile,17    fps: int = Form(...),18    filter_complex: str = Form(...),19    preset: str = Form(...),20    filename: str = Form(...),21    video_path: str = Form(...),22    shortest: bool = Form(True),23):24    # 文件处理25    image_ext = image.filename.split(".")[-1]26    audio_ext = audio.filename.split(".")[-1]27    image_path = f"/tmp/{uuid.uuid4()}.{image_ext}"28    audio_path = f"/tmp/{uuid.uuid4()}.{audio_ext}"29    output_path = f"{video_path.rstrip('/')}/{filename}.mp4"30 31    # 保存上传的 image 和 audio32    with open(image_path, "wb") as f:33        f.write(await image.read())34    with open(audio_path, "wb") as f:35        f.write(await audio.read())36 37    # 构造 FFmpeg 命令38    cmd = [39        "ffmpeg", "-y", "-nostdin", "-hide_banner", "-loglevel", "error",40        "-loop", "1", "-framerate", str(fps), "-i", image_path,41        "-i", OVERLAY_PATH,42        "-i", audio_path,43        "-filter_complex", filter_complex,44        "-map", "[v]", "-map", "2:a",45        "-c:v", "libx264", "-preset", preset, "-pix_fmt", "yuv420p",46        "-c:a", "aac", "-b:a", "192k",47        "-movflags", "+faststart",48        "-metadata", f"title={filename}"49    ]50 51    if shortest:52        cmd.append("-shortest")53 54    cmd.append(output_path)55 56    # 确保目标路径存在(仅用于 Space /tmp 测试)57    os.makedirs(os.path.dirname(output_path), exist_ok=True)58 59    # 执行 FFmpeg60    subprocess.run(cmd, check=True)61 62    return FileResponse(output_path, media_type="video/mp4", filename=f"{filename}.mp4")