Implement batch processing, pause/resume, custom temp directory, and detailed pipeline logs

This commit is contained in:
2026-06-29 08:04:35 -04:00
parent d1ea029afb
commit d35a48bf64
5 changed files with 507 additions and 71 deletions
+135 -2
View File
@@ -235,6 +235,35 @@ class StartUpscaleRequest(BaseModel):
ai_face_restoration: bool = False
ai_rife_interpolation: bool = False
ai_audio_denoise: bool = False
temp_dir: str | None = None
class StartBatchUpscaleRequest(BaseModel):
file_ids: List[str]
model: str = "realesr-animevideov3"
scale: int = 4
tile_size: int = 256
preserve_audio: bool = True
ss: str | None = None
t: str | None = None
gpu_ids: str | None = None
tta: bool = False
unsharp: bool = False
double_fps: bool = False
preserve_subtitles: bool = True
start_sec: float | None = None
end_sec: float | None = None
crf: int = 18
preset: str = "medium"
denoise: bool = False
sharpen: bool = False
interpolation: bool = False
webhook_url: str | None = None
transcode_format: str = "mp4"
is_preview: bool = False
ai_face_restoration: bool = False
ai_rife_interpolation: bool = False
ai_audio_denoise: bool = False
temp_dir: str | None = None
class PreviewRequest(BaseModel):
file_id: str
@@ -422,7 +451,8 @@ def start_upscale(req: StartUpscaleRequest):
is_preview=req.is_preview,
ai_face_restoration=req.ai_face_restoration,
ai_rife_interpolation=req.ai_rife_interpolation,
ai_audio_denoise=req.ai_audio_denoise
ai_audio_denoise=req.ai_audio_denoise,
temp_dir=req.temp_dir
)
jobs_db[job_id] = job
@@ -443,6 +473,80 @@ def start_upscale(req: StartUpscaleRequest):
"status": "queued"
}
@app.post("/api/upscale/start/batch")
def start_upscale_batch(req: StartBatchUpscaleRequest):
"""Queue multiple upscaling tasks with one set of settings"""
queued_jobs = []
# 1. Validation loop
for file_id in req.file_ids:
file_path = None
exts = [".mp4", ".mkv", ".avi", ".mov", ".webm"]
for ext in exts:
test_path = os.path.join(upscaler.UPLOAD_DIR, f"{file_id}{ext}")
if os.path.exists(test_path):
file_path = test_path
break
if not file_path:
raise HTTPException(status_code=404, detail=f"Uploaded file {file_id} not found.")
# 2. Queueing loop
for file_id in req.file_ids:
file_path = None
for ext in [".mp4", ".mkv", ".avi", ".mov", ".webm"]:
test_path = os.path.join(upscaler.UPLOAD_DIR, f"{file_id}{ext}")
if os.path.exists(test_path):
file_path = test_path
break
job_id = str(uuid.uuid4())
job = upscaler.UpscaleJob(
job_id=job_id,
video_path=file_path,
model=req.model,
scale=req.scale,
tile_size=req.tile_size,
preserve_audio=req.preserve_audio,
ss=req.ss,
t=req.t,
gpu_ids=req.gpu_ids,
tta=req.tta,
unsharp=req.unsharp,
double_fps=req.double_fps,
preserve_subtitles=req.preserve_subtitles,
start_sec=req.start_sec,
end_sec=req.end_sec,
crf=req.crf,
preset=req.preset,
denoise=req.denoise,
sharpen=req.sharpen,
interpolation=req.interpolation,
webhook_url=req.webhook_url,
transcode_format=req.transcode_format,
is_preview=req.is_preview,
ai_face_restoration=req.ai_face_restoration,
ai_rife_interpolation=req.ai_rife_interpolation,
ai_audio_denoise=req.ai_audio_denoise,
temp_dir=req.temp_dir
)
jobs_db[job_id] = job
job_queue.put(job_id)
queued_jobs.append({"job_id": job_id, "status": "queued"})
save_jobs_db()
# Broadcast initial queued progress for all queued jobs
for qj in queued_jobs:
broadcast_progress(qj["job_id"], {
"status": "queued",
"progress": 0.0,
"current_frame": 0,
"total_frames": 0,
"eta": "Calculating..."
})
return {"jobs": queued_jobs}
@app.get("/api/upscale/status/{job_id}")
def get_status(job_id: str):
"""Get status of upscale job"""
@@ -699,7 +803,7 @@ def get_queue():
@app.post("/api/upscale/resume/{job_id}")
def resume_job(job_id: str):
"""Resume an interrupted/failed upscale job"""
"""Resume an interrupted/failed/paused upscale job"""
job = jobs_db.get(job_id)
if not job:
raise HTTPException(status_code=404, detail="Job not found.")
@@ -708,6 +812,8 @@ def resume_job(job_id: str):
job.status = "queued"
job.error = None
job.eta = "Queued for resume..."
if hasattr(job, "_is_paused"):
job._is_paused = False
job_queue.put(job_id)
save_jobs_db()
@@ -722,6 +828,33 @@ def resume_job(job_id: str):
return {"job_id": job_id, "status": "queued"}
@app.post("/api/upscale/pause/{job_id}")
def pause_job(job_id: str):
"""Pause a running or queued job"""
job = jobs_db.get(job_id)
if not job:
raise HTTPException(status_code=404, detail="Job not found.")
if job.status not in ["queued", "pending", "analyzing", "extracting", "upscaling", "restoring_faces", "interpolating", "assembling"]:
raise HTTPException(status_code=400, detail=f"Job in status {job.status} cannot be paused.")
# Remove from queue if it is in queue
job_queue.remove(job_id)
# Call pause logic on the job
job.pause()
save_jobs_db()
broadcast_progress(job_id, {
"status": "paused",
"progress": job.progress,
"current_frame": job.current_frame,
"total_frames": job.total_frames,
"eta": "Paused"
})
return {"job_id": job_id, "status": "paused"}
# Websocket endpoint for real-time progress updates
@app.websocket("/ws/progress/{job_id}")
async def websocket_progress(websocket: WebSocket, job_id: str):