DR-LYRIA-001: Waveform performance overhaul
- Convert generate_waveform_svg() from sync to async (subprocess.run -> asyncio.create_subprocess_exec) - Add early downsampling to ~2000 samples before numpy processing (~95% memory reduction for 120s tracks) - Pre-generate waveform on clip completion in _generate_and_save() - Add Cache-Control headers (public, max-age=86400) to waveform endpoint - Preserve on-demand generation as lazy fallback
This commit is contained in:
1 parent
f8969d8585
commit
3500c73167
2 files changed
+99
-68
No files matched your search
+28
-6
@@ -49,7 +49,11 @@ async def list_models():
|
||||
return {"models": LYRIA_MODELS, "default": DEFAULT_MODEL}
|
||||
|
||||
async def _generate_and_save(clip_id: str, prompt: str, model: str, duration: int):
|
||||
"""Background task: call Lyria API and save the result."""
|
||||
"""Background task: call Lyria API and save the result.
|
||||
|
||||
DR-LYRIA-001: Pre-generates waveform SVG after clip is ready,
|
||||
so users never wait for on-demand generation.
|
||||
"""
|
||||
try:
|
||||
result = await generate_clip(prompt, model, duration)
|
||||
|
||||
@@ -60,6 +64,16 @@ async def _generate_and_save(clip_id: str, prompt: str, model: str, duration: in
|
||||
status="ready",
|
||||
file_size=file_info["file_size"]
|
||||
)
|
||||
# DR-LYRIA-001: Pre-generate waveform SVG immediately
|
||||
# so it's ready before the user views the clip
|
||||
try:
|
||||
clip = await get_clip(clip_id)
|
||||
if clip and clip.get("filename"):
|
||||
await generate_waveform_svg(clip_id, clip["filename"])
|
||||
except Exception as wf_err:
|
||||
# Waveform pre-generation failure is non-fatal —
|
||||
# on-demand fallback will catch it on view
|
||||
print(f"Waveform pre-gen warning for {clip_id}: {wf_err}")
|
||||
else:
|
||||
await update_clip_status(
|
||||
clip_id,
|
||||
@@ -228,14 +242,22 @@ async def get_waveform(clip_id: str):
|
||||
clip = await get_clip(clip_id)
|
||||
if not clip:
|
||||
raise HTTPException(status_code=404, detail="Clip not found")
|
||||
# Check if waveform already exists
|
||||
# Check if pre-generated waveform exists on disk
|
||||
svg_path = get_waveform_path(clip_id)
|
||||
if svg_path and svg_path.exists():
|
||||
return FileResponse(svg_path, media_type="image/svg+xml")
|
||||
# Generate on demand
|
||||
return FileResponse(
|
||||
svg_path,
|
||||
media_type="image/svg+xml",
|
||||
headers={"Cache-Control": "public, max-age=86400"}
|
||||
)
|
||||
# Lazy fallback: generate on demand (should rarely trigger)
|
||||
try:
|
||||
svg_path_str = generate_waveform_svg(clip_id, clip["filename"])
|
||||
return FileResponse(svg_path_str, media_type="image/svg+xml")
|
||||
svg_path_str = await generate_waveform_svg(clip_id, clip["filename"])
|
||||
return FileResponse(
|
||||
svg_path_str,
|
||||
media_type="image/svg+xml",
|
||||
headers={"Cache-Control": "public, max-age=86400"}
|
||||
)
|
||||
except FileNotFoundError:
|
||||
raise HTTPException(status_code=404, detail="Audio file not found")
|
||||
except Exception as e:
|
||||
|
||||
Reference in new issue
Block a user