Adds continuous play support to Plex integration (#158281)

This commit is contained in:
Siemon Geeroms
2025-12-16 14:20:03 +01:00
committed by GitHub
parent d6b675138d
commit 412ee0da05
3 changed files with 45 additions and 3 deletions

View File

@@ -2,6 +2,8 @@
import logging
import plexapi.playqueue
from homeassistant.components.media_player import MediaType
from homeassistant.helpers.template import result_as_boolean
from homeassistant.util import dt as dt_util
@@ -167,7 +169,10 @@ class PlexMediaSearchResult:
if isinstance(resume, str):
resume = result_as_boolean(resume)
if resume:
return self.media.viewOffset
media = self.media
if isinstance(media, plexapi.playqueue.PlayQueue) and len(media.items) > 0:
media = media.items[0]
return media.viewOffset
return 0
@property
@@ -177,3 +182,11 @@ class PlexMediaSearchResult:
if isinstance(shuffle, str):
shuffle = result_as_boolean(shuffle)
return shuffle
@property
def continuous(self) -> bool:
"""Return value of continuous parameter."""
continuous = self._params.get("continuous", False)
if isinstance(continuous, str):
continuous = result_as_boolean(continuous)
return continuous

View File

@@ -174,6 +174,7 @@ def process_plex_payload(
search_query = content.copy()
shuffle = search_query.pop("shuffle", 0)
continuous = search_query.pop("continuous", 0)
# Remove internal kwargs before passing copy to plexapi
for internal_key in ("resume", "offset"):
@@ -181,9 +182,12 @@ def process_plex_payload(
media = plex_server.lookup_media(content_type, **search_query)
if supports_playqueues and (isinstance(media, list) or shuffle):
if supports_playqueues and (isinstance(media, list) or shuffle or continuous):
playqueue = plex_server.create_playqueue(
media, includeRelated=0, shuffle=shuffle
media,
includeRelated=0,
shuffle=1 if shuffle else 0,
continuous=1 if continuous else 0,
)
return PlexMediaSearchResult(playqueue, content)

View File

@@ -130,6 +130,10 @@ async def test_lookup_media_for_other_integrations(
PLEX_URI_SCHEME
+ '{"library_name": "Music", "artist_name": "Artist", "shuffle": 1}'
)
CONTENT_ID_CONTINUOUS = (
PLEX_URI_SCHEME
+ '{"library_name": "Music", "artist_name": "Artist", "continuous": 1}'
)
# Test with no Plex integration available
with pytest.raises(HomeAssistantError) as excinfo:
@@ -158,6 +162,7 @@ async def test_lookup_media_for_other_integrations(
)
assert isinstance(result.media, plexapi.audio.Artist)
assert not result.shuffle
assert not result.continuous
# Test media key payload without playqueue
result = process_plex_payload(
@@ -180,6 +185,13 @@ async def test_lookup_media_for_other_integrations(
assert isinstance(result.media, plexapi.audio.Artist)
assert result.shuffle
# Test continuous without playqueue
result = process_plex_payload(
hass, MediaType.MUSIC, CONTENT_ID_CONTINUOUS, supports_playqueues=False
)
assert isinstance(result.media, plexapi.audio.Artist)
assert result.continuous
# Test with media not found
with patch(
"plexapi.library.LibrarySection.search",
@@ -208,6 +220,10 @@ async def test_lookup_media_for_other_integrations(
result = process_plex_payload(hass, MediaType.MUSIC, CONTENT_ID_SHUFFLE)
assert isinstance(result.media, plexapi.playqueue.PlayQueue)
# Test playqueue is created with continuous
result = process_plex_payload(hass, MediaType.MUSIC, CONTENT_ID_CONTINUOUS)
assert isinstance(result.media, plexapi.playqueue.PlayQueue)
async def test_lookup_media_with_urls(hass: HomeAssistant, mock_plex_server) -> None:
"""Test media lookup for media_player.play_media calls from cast/sonos."""
@@ -228,3 +244,12 @@ async def test_lookup_media_with_urls(hass: HomeAssistant, mock_plex_server) ->
assert isinstance(result.media, plexapi.audio.Track)
assert result.shuffle is True
assert result.offset == 0
# Test URL format with continuous
CONTENT_ID_URL_WITH_CONTINUOUS = CONTENT_ID_URL + "?continuous=1"
result = process_plex_payload(
hass, MediaType.MUSIC, CONTENT_ID_URL_WITH_CONTINUOUS, supports_playqueues=False
)
assert isinstance(result.media, plexapi.audio.Track)
assert result.continuous is True
assert result.offset == 0