refactor(transcode): thread fs ops + atomic cache publish
- run blocking Path.exists/read_text off the event loop via anyio.to_thread - publish HLS renditions by building into a temp dir then atomic rename, so a reader never sees a playlist referencing half-written segments - per-writer temp name for opus so two concurrent jobs can't interleave - drop a track's cached renditions on delete so they don't dangle Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,7 @@ quality renditions; HLS segments are AAC-in-MPEG-TS (broad player support).
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import uuid
|
||||
from pathlib import Path
|
||||
|
||||
import anyio
|
||||
@@ -30,7 +31,10 @@ class FfmpegTranscoder:
|
||||
|
||||
async def to_opus(self, src: Path, dest: Path, *, bitrate_kbps: int) -> None:
|
||||
await anyio.to_thread.run_sync(_mkdir, dest.parent)
|
||||
tmp = dest.with_suffix(dest.suffix + ".part")
|
||||
# Per-writer temp name (not a shared ``.part``) so two concurrent jobs for
|
||||
# the same rendition can't interleave into one file — each writes its own
|
||||
# temp and the last atomic replace wins, both leaving a valid output.
|
||||
tmp = dest.with_name(f"{dest.name}.{uuid.uuid4().hex}.part")
|
||||
await self._run(
|
||||
"-i", str(src),
|
||||
"-vn", "-c:a", "libopus", "-b:a", f"{bitrate_kbps}k",
|
||||
|
||||
Reference in New Issue
Block a user