Spaces:
Running
Running
File size: 3,955 Bytes
46654ce 7bb58ee 6be8085 46654ce 7bb58ee 46654ce 7bb58ee 46654ce 7bb58ee 46654ce 7bb58ee 46654ce 7bb58ee 46654ce 7bb58ee 46654ce 7bb58ee 46654ce 7bb58ee 46654ce 7bb58ee 46654ce 7bb58ee 46654ce 7bb58ee 46654ce 7bb58ee 46654ce 7bb58ee 46654ce 7bb58ee 46654ce 7bb58ee 46654ce 7bb58ee 46654ce 7bb58ee 46654ce d02da21 6be8085 | 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 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | import os
import shutil
import subprocess
import tempfile
from fastapi import FastAPI, File, UploadFile, Form, HTTPException, BackgroundTasks
from fastapi.responses import FileResponse, RedirectResponse
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
# Add CORS middleware (adjust allow_origins for production)
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Ensure the base temporary directory exists.
TEMP_DIR = "temp_files"
os.makedirs(TEMP_DIR, exist_ok=True)
@app.get("/")
def read_root():
return {"message": "Video Subtitle Server is running"}
@app.post("/burn-subtitles")
async def burn_subtitles(
background_tasks: BackgroundTasks,
video: UploadFile = File(...),
subtitle: UploadFile = File(...),
font_size: str = Form("20"),
font_color: str = Form("white"),
output_format: str = Form("mp4")
):
# Create a unique temporary directory for this job.
job_dir = tempfile.mkdtemp(prefix='job_', dir=TEMP_DIR)
try:
# Build file paths.
video_path = os.path.join(job_dir, f"input{os.path.splitext(video.filename)[1]}")
subtitle_path = os.path.join(job_dir, "subtitles.srt")
output_path = os.path.join(job_dir, f"output.{output_format}")
# Save uploaded video file.
with open(video_path, "wb") as video_file:
shutil.copyfileobj(video.file, video_file)
# Save uploaded subtitle file.
with open(subtitle_path, "wb") as subtitle_file:
shutil.copyfileobj(subtitle.file, subtitle_file)
# Format the font color for FFmpeg if provided as hex.
if font_color.startswith('#'):
font_color = font_color.lstrip('#')
if len(font_color) == 6:
r, g, b = font_color[0:2], font_color[2:4], font_color[4:6]
font_color = f"&H{b}{g}{r}&"
# Build the subtitle style string.
subtitle_style = f"FontSize={font_size},PrimaryColour={font_color}"
command = [
"ffmpeg",
"-i", video_path,
"-vf", f"subtitles={subtitle_path}:force_style='{subtitle_style}'",
"-c:a", "copy",
output_path
]
# Run the FFmpeg command.
process = subprocess.run(command, capture_output=True, text=True)
if process.returncode != 0:
raise HTTPException(status_code=500, detail=f"FFmpeg Error: {process.stderr}")
# Schedule cleanup of the job directory after the response is sent.
background_tasks.add_task(shutil.rmtree, job_dir)
return FileResponse(
output_path,
media_type=f"video/{output_format}",
filename=f"processed_video.{output_format}"
)
except Exception as e:
# Clean up immediately on error.
shutil.rmtree(job_dir, ignore_errors=True)
raise HTTPException(status_code=500, detail=str(e))
@app.post("/convert-srt")
async def convert_srt(
background_tasks: BackgroundTasks,
subtitle: UploadFile = File(...),
):
job_dir = tempfile.mkdtemp(prefix='job_', dir=TEMP_DIR)
try:
subtitle_path = os.path.join(job_dir, "subtitles.srt")
with open(subtitle_path, "wb") as subtitle_file:
shutil.copyfileobj(subtitle.file, subtitle_file)
background_tasks.add_task(shutil.rmtree, job_dir)
return FileResponse(
subtitle_path,
media_type="text/plain",
filename="subtitles.srt"
)
except Exception as e:
shutil.rmtree(job_dir, ignore_errors=True)
raise HTTPException(status_code=500, detail=str(e))
@app.get("/health")
def health_check():
return {"status": "healthy"}
@app.get("/doc")
def redirect_to_docs():
return RedirectResponse(url="/docs")
|