Files
musicseerr/backend/services/plex_playback_service.py
T
Harvey 0f25ebc26d Plex Integration + Music Source Integration Improvements (#37)
* plex integration

* The big one - Full Music Source page rework + Playlist importing + Full Plex Integration + Discovery Options + More Like This/Surprise Me/Instant Mix + More...

* Music source track page - Play all / shuffle fixes

* lint

* format

* fix type checks

* format
2026-04-13 23:39:01 +01:00

72 lines
2.5 KiB
Python

from __future__ import annotations
import logging
from fastapi.responses import Response, StreamingResponse
from infrastructure.cache.memory_cache import CacheInterface
from repositories.plex_models import StreamProxyResult
from repositories.protocols.plex import PlexRepositoryProtocol
logger = logging.getLogger(__name__)
class PlexPlaybackService:
def __init__(
self,
plex_repo: PlexRepositoryProtocol,
cache: CacheInterface | None = None,
) -> None:
self._plex = plex_repo
self._cache = cache
async def proxy_head(self, part_key: str) -> Response:
result: StreamProxyResult = await self._plex.proxy_head_stream(part_key)
return Response(status_code=result.status_code, headers=result.headers)
async def proxy_stream(
self, part_key: str, range_header: str | None = None
) -> StreamingResponse:
result: StreamProxyResult = await self._plex.proxy_get_stream(
part_key, range_header=range_header
)
return StreamingResponse(
content=result.body_chunks,
status_code=result.status_code,
headers=result.headers,
media_type=result.media_type,
)
async def scrobble(self, rating_key: str) -> bool:
try:
ok = await self._plex.scrobble(rating_key)
if self._cache:
await self._cache.delete("plex:sessions")
return ok
except Exception: # noqa: BLE001
logger.warning("Plex scrobble failed for %s", rating_key, exc_info=True)
return False
async def report_now_playing(self, rating_key: str) -> bool:
try:
ok = await self._plex.now_playing(rating_key)
if self._cache:
await self._cache.delete("plex:sessions")
return ok
except Exception: # noqa: BLE001
logger.warning("Plex now-playing failed for %s", rating_key, exc_info=True)
return False
async def report_stopped(self, rating_key: str) -> bool:
try:
ok = await self._plex.now_playing(rating_key, state="stopped")
if self._cache:
await self._cache.delete("plex:sessions")
return ok
except Exception: # noqa: BLE001
logger.warning("Plex stopped report failed for %s", rating_key, exc_info=True)
return False
async def proxy_thumb(self, rating_key: str, size: int = 500) -> tuple[bytes, str]:
return await self._plex.proxy_thumb(rating_key, size=size)