Files
web-utils/backend/app/tools/video_ops.py
2026-01-28 15:33:47 +09:00

61 lines
1.9 KiB
Python

import os
import shutil
import uuid
from pathlib import Path
from fastapi import APIRouter, UploadFile, HTTPException, BackgroundTasks
from fastapi.responses import FileResponse
import ffmpeg
router = APIRouter()
TEMP_DIR = Path("temp_uploads")
TEMP_DIR.mkdir(exist_ok=True)
def cleanup_file(path: Path):
try:
if path.exists():
path.unlink()
except Exception as e:
print(f"Error cleaning up file {path}: {e}")
@router.post("/gif")
async def convert_video_to_gif(file: UploadFile, background_tasks: BackgroundTasks):
if not (file.content_type or "").startswith("video/"):
raise HTTPException(status_code=400, detail="File must be a video")
file_id = str(uuid.uuid4())
input_path = TEMP_DIR / f"{file_id}_{file.filename}"
output_filename = f"{file_id}.gif"
output_path = TEMP_DIR / output_filename
try:
with input_path.open("wb") as buffer:
shutil.copyfileobj(file.file, buffer)
stream = ffmpeg.input(str(input_path))
stream = ffmpeg.filter(stream, 'fps', fps=10)
stream = ffmpeg.filter(stream, 'scale', 320, -1)
stream = ffmpeg.output(stream, str(output_path))
ffmpeg.run(stream, capture_stdout=True, capture_stderr=True)
background_tasks.add_task(cleanup_file, input_path)
background_tasks.add_task(cleanup_file, output_path)
return FileResponse(
output_path,
media_type="image/gif",
filename="converted.gif"
)
except ffmpeg.Error as e:
cleanup_file(input_path)
if output_path.exists():
cleanup_file(output_path)
print(e.stderr.decode('utf8'))
raise HTTPException(status_code=500, detail="FFmpeg conversion failed")
except Exception as e:
cleanup_file(input_path)
if output_path.exists():
cleanup_file(output_path)
raise HTTPException(status_code=500, detail=str(e))