auto-commit for cf4f0369-14b7-4d06-b915-b8f7098fd48d

This commit is contained in:
emergent-agent-e1
2026-04-29 16:21:32 +00:00
parent 00b0d5426c
commit 20aba50fa1
5 changed files with 180 additions and 46 deletions
+36 -11
View File
@@ -28,7 +28,7 @@ from auth import hash_password, verify_password, create_token, decode_token
from seed import SAMPLE_MOVIES
import tmdb as tmdb_client
import radarr as radarr_client
from transcode import transcode_to_hls, srt_to_vtt
from transcode import transcode_quick, transcode_abr, srt_to_vtt
ROOT_DIR = Path(__file__).parent
@@ -469,28 +469,40 @@ async def _set_hls_status(movie_id: str, status: str, path: Optional[str] = None
logger.warning(f"HLS {movie_id}: {error}")
async def _run_transcode(movie_id: str, source: Path):
async def _run_transcode(movie_id: str, source: Path, quality: str):
out_dir = HLS_DIR / movie_id
async def cb(status, error=None):
if status == "done":
await _set_hls_status(movie_id, "done", path=f"{movie_id}/playlist.m3u8")
# Clear any prior output before re-encoding
import shutil as _sh
_sh.rmtree(out_dir, ignore_errors=True)
async def cb(status, entry: Optional[str] = None, error: Optional[str] = None):
if status == "done" and entry:
await _set_hls_status(movie_id, "done", path=entry)
else:
await _set_hls_status(movie_id, status, error=error)
await transcode_to_hls(source, out_dir, cb)
if quality == "abr":
await transcode_abr(source, out_dir, cb)
else:
await transcode_quick(source, out_dir, cb)
@api.post("/movies/{movie_id}/transcode")
async def trigger_transcode(movie_id: str, user: dict = Depends(require_admin)):
async def trigger_transcode(movie_id: str, payload: Optional[dict] = None, user: dict = Depends(require_admin)):
"""Body: {"quality": "quick"|"abr"} — default "quick"."""
quality = (payload or {}).get("quality", "quick")
if quality not in ("quick", "abr"):
raise HTTPException(status_code=400, detail="quality must be 'quick' or 'abr'")
movie = await db.movies.find_one({"id": movie_id}, {"_id": 0})
if not movie: raise HTTPException(status_code=404, detail="Movie not found")
if movie.get("storage_type") not in ("local", "radarr") or not movie.get("storage_path"):
raise HTTPException(status_code=400, detail="Only local/radarr movies can be transcoded")
if movie.get("hls_status") == "running":
if movie.get("hls_status") in ("running", "pending"):
raise HTTPException(status_code=409, detail="Already transcoding")
source = Path(movie["storage_path"]) if movie["storage_type"] == "radarr" else VIDEOS_DIR / movie["storage_path"]
await _set_hls_status(movie_id, "pending")
asyncio.create_task(_run_transcode(movie_id, source))
return {"ok": True, "status": "pending"}
asyncio.create_task(_run_transcode(movie_id, source, quality))
return {"ok": True, "status": "pending", "quality": quality}
@api.get("/movies/{movie_id}/hls/{filename:path}")
@@ -513,7 +525,20 @@ async def serve_hls(
raise HTTPException(status_code=400, detail="Invalid path")
if not target.is_file():
raise HTTPException(status_code=404, detail="HLS file not found")
media_type = "application/vnd.apple.mpegurl" if filename.endswith(".m3u8") else "video/mp2t"
# Rewrite playlists to propagate ?auth= to relative URLs (variants + segments)
if filename.endswith(".m3u8"):
text = target.read_text(encoding="utf-8", errors="ignore")
out_lines = []
for line in text.splitlines():
stripped = line.strip()
if stripped and not stripped.startswith("#") and "://" not in stripped:
sep = "&" if "?" in stripped else "?"
line = f"{stripped}{sep}auth={token}"
out_lines.append(line)
return Response("\n".join(out_lines) + "\n", media_type="application/vnd.apple.mpegurl")
media_type = "video/mp2t" if filename.endswith(".ts") else "application/octet-stream"
return FileResponse(str(target), media_type=media_type)