Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion plexapi/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -481,8 +481,38 @@ def setVideoStream(self, videoStreamID, mtype=DEFAULT_MTYPE):
"""
self.setStreams(videoStreamID=videoStreamID, mtype=mtype)

def createPlayQueue(self, server, items, offset=0, paused=False, **params):
""" Create a playqueue and start playback of the specified media item.

Parameters:
server (:class:`~plexapi.server.PlexServer`): Server you are connected to.
items (:class:`~plexapi.base.PlexPartialObject`):
A media item or a list of media items.
offset (int, optional): Number of milliseconds at which to start playing with zero
representing the beginning (default 0).
paused (bool, optional): Set True to pause playback,
default False to start playback immediately.
**params (dict): Additional options to apply to the playqueue.
See :func:`~plexapi.playqueue.PlayQueue.create` for available parameters.
"""
protocol, address, port = server._baseurl.split(':')
args = PlayQueue._createArgs(
server=server,
items=items,
offset=offset,
paused=int(bool(paused)),
protocol=protocol,
address=address.strip('/'),
port=port,
machineIdentifier=server.machineIdentifier,
source=server.machineIdentifier,
**params)
self.sendCommand("playback/createPlayQueue", **args)

def playMedia(self, media, offset=0, **params):
""" Start playback of the specified media item. See also:
""" Start playback of the specified media item.
Note: This is a legacy command for older clients.
Use :func:`~plexapi.client.PlexClient.createPlayQueue` instead for modern clients.

Parameters:
media (:class:`~plexapi.media.Media`): Media item to be played back
Expand Down
84 changes: 56 additions & 28 deletions plexapi/playqueue.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,39 +136,25 @@ def get(
c._server = server
return c

@classmethod
def create(
cls,
@staticmethod
def _createArgs(
server,
items,
startItem=None,
shuffle=0,
repeat=0,
includeChapters=1,
includeRelated=1,
continuous=0,
shuffle=False,
repeat=False,
includeChapters=True,
includeRelated=True,
continuous=False,
**kwargs
):
"""Create and return a new :class:`~plexapi.playqueue.PlayQueue`.

Parameters:
server (:class:`~plexapi.server.PlexServer`): Server you are connected to.
items (:class:`~plexapi.base.PlexPartialObject`):
A media item or a list of media items.
startItem (:class:`~plexapi.base.Playable`, optional):
Media item in the PlayQueue where playback should begin.
shuffle (int, optional): Start the playqueue shuffled.
repeat (int, optional): Start the playqueue shuffled.
includeChapters (int, optional): include Chapters.
includeRelated (int, optional): include Related.
continuous (int, optional): include additional items after the initial item.
For a show this would be the next episodes, for a movie it does nothing.
"""
args = {
"includeChapters": includeChapters,
"includeRelated": includeRelated,
"repeat": repeat,
"shuffle": shuffle,
"continuous": continuous,
"includeChapters": int(bool(includeChapters)),
"includeRelated": int(bool(includeRelated)),
"repeat": int(bool(repeat)),
"shuffle": int(bool(shuffle)),
"continuous": int(bool(continuous)),
**kwargs
}

if isinstance(items, list):
Expand All @@ -187,6 +173,48 @@ def create(
if startItem:
args["key"] = startItem.key

return args

@classmethod
def create(
cls,
server,
items,
startItem=None,
shuffle=False,
repeat=False,
includeChapters=True,
includeRelated=True,
continuous=False,
**kwargs
):
"""Create and return a new :class:`~plexapi.playqueue.PlayQueue`.

Parameters:
server (:class:`~plexapi.server.PlexServer`): Server you are connected to.
items (:class:`~plexapi.base.PlexPartialObject`):
A media item or a list of media items.
startItem (:class:`~plexapi.base.Playable`, optional):
Media item in the PlayQueue where playback should begin.
shuffle (bool, optional): Start the playqueue shuffled.
repeat (bool, optional): Start the playqueue shuffled.
includeChapters (bool, optional): include Chapters.
includeRelated (bool, optional): include Related.
continuous (bool, optional): include additional items after the initial item.
For a show this would be the next episodes, for a movie it does nothing.
**kwargs (dict): Additional options to apply to the playqueue.
"""
args = cls._createArgs(
server=server,
items=items,
startItem=startItem,
shuffle=shuffle,
repeat=repeat,
includeChapters=includeChapters,
includeRelated=includeRelated,
continuous=continuous,
**kwargs
)
path = f"/playQueues{utils.joinArgs(args)}"
data = server.query(path, method=server._session.post)
c = cls(server, data, initpath=path)
Expand Down
17 changes: 17 additions & 0 deletions tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,3 +139,20 @@ def test_client_timeline(plex, client, movies, proxy):
print("movie.markPlayed()")
movie.markPlayed()
time.sleep(2)


@pytest.mark.client
def test_client_createPlayQueue(client, plex, movie, mocker):
client.sendCommand = mocker.MagicMock(return_value=None)

client.createPlayQueue(plex, movie, paused=True)

client.sendCommand.assert_called_once()
args = client.sendCommand.call_args[0]
kwargs = client.sendCommand.call_args[1]

assert args[0] == "playback/createPlayQueue"
assert kwargs["paused"] == 1
assert kwargs["type"] == movie.listType
assert kwargs["uri"].startswith(f"server://{plex.machineIdentifier}/")
assert movie.key in kwargs["uri"]