61 lines
1.9 KiB
Python
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))
|