mirror of
https://github.com/myronblair/kino-app
synced 2026-06-30 17:50:16 -05:00
auto-commit for cf4f0369-14b7-4d06-b915-b8f7098fd48d
This commit is contained in:
+36
-11
@@ -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)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user