From 39bc3a0dffc7cfda171d8f66d2c443c009c29866 Mon Sep 17 00:00:00 2001 From: JonnyWong16 <9099342+JonnyWong16@users.noreply.github.com> Date: Tue, 7 Jul 2026 16:53:44 -0700 Subject: [PATCH 1/6] Add PlexClient `createPlayQueue` method --- plexapi/client.py | 17 +++++++++++- plexapi/playqueue.py | 64 +++++++++++++++++++++++++++++++------------- 2 files changed, 62 insertions(+), 19 deletions(-) diff --git a/plexapi/client.py b/plexapi/client.py index 4aa7d8755..03a003bbe 100644 --- a/plexapi/client.py +++ b/plexapi/client.py @@ -481,8 +481,23 @@ def setVideoStream(self, videoStreamID, mtype=DEFAULT_MTYPE): """ self.setStreams(videoStreamID=videoStreamID, mtype=mtype) + def createPlayQueue(self, server, items, **kwargs): + """ 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. + **kwargs (dict): Additional options to apply to the playqueue. + See :func:`~plexapi.playqueue.PlayQueue.create` for available parameters. + """ + args = PlayQueue._createArgs(server=server, items=items, **kwargs) + 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 diff --git a/plexapi/playqueue.py b/plexapi/playqueue.py index ede8ccb0f..7b29f174c 100644 --- a/plexapi/playqueue.py +++ b/plexapi/playqueue.py @@ -136,9 +136,8 @@ def get( c._server = server return c - @classmethod - def create( - cls, + @staticmethod + def _createArgs( server, items, startItem=None, @@ -147,28 +146,15 @@ def create( includeChapters=1, includeRelated=1, continuous=0, + **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, + **kwargs } if isinstance(items, list): @@ -187,6 +173,48 @@ def create( if startItem: args["key"] = startItem.key + return args + + @classmethod + def create( + cls, + server, + items, + startItem=None, + shuffle=0, + repeat=0, + includeChapters=1, + includeRelated=1, + continuous=0, + **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. + **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) From e96736bf643a63a7d7283c44f652610b395b69e0 Mon Sep 17 00:00:00 2001 From: JonnyWong16 <9099342+JonnyWong16@users.noreply.github.com> Date: Wed, 8 Jul 2026 16:27:51 -0700 Subject: [PATCH 2/6] Add machineIdentifier to playqueue args --- plexapi/playqueue.py | 1 + 1 file changed, 1 insertion(+) diff --git a/plexapi/playqueue.py b/plexapi/playqueue.py index 7b29f174c..a8b9a9ff1 100644 --- a/plexapi/playqueue.py +++ b/plexapi/playqueue.py @@ -149,6 +149,7 @@ def _createArgs( **kwargs ): args = { + "machineIdentifier": server.machineIdentifier, "includeChapters": includeChapters, "includeRelated": includeRelated, "repeat": repeat, From 39fc9158aa5e4350081c1d7d8c814f10afb0961e Mon Sep 17 00:00:00 2001 From: JonnyWong16 <9099342+JonnyWong16@users.noreply.github.com> Date: Wed, 8 Jul 2026 16:29:04 -0700 Subject: [PATCH 3/6] Add client option to start playqueue paused --- plexapi/client.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plexapi/client.py b/plexapi/client.py index 03a003bbe..29a5052b3 100644 --- a/plexapi/client.py +++ b/plexapi/client.py @@ -481,17 +481,18 @@ def setVideoStream(self, videoStreamID, mtype=DEFAULT_MTYPE): """ self.setStreams(videoStreamID=videoStreamID, mtype=mtype) - def createPlayQueue(self, server, items, **kwargs): + def createPlayQueue(self, server, items, paused=False, **kwargs): """ 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. + paused (bool, optional): Set True to pause playback, False (default) to start playback immediately. **kwargs (dict): Additional options to apply to the playqueue. See :func:`~plexapi.playqueue.PlayQueue.create` for available parameters. """ - args = PlayQueue._createArgs(server=server, items=items, **kwargs) + args = PlayQueue._createArgs(server=server, items=items, paused=int(bool(paused)), **kwargs) self.sendCommand("playback/createPlayQueue", **args) def playMedia(self, media, offset=0, **params): From ce3440943dd783a193b8f3d018168f54cfaf2e7d Mon Sep 17 00:00:00 2001 From: JonnyWong16 <9099342+JonnyWong16@users.noreply.github.com> Date: Wed, 8 Jul 2026 16:47:09 -0700 Subject: [PATCH 4/6] Add test for client.createPlayQueue --- tests/test_client.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/test_client.py b/tests/test_client.py index 21974530e..d9d8bb7c5 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -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"] From b720c9cd3336b172377ffb500295e35d23e1236b Mon Sep 17 00:00:00 2001 From: JonnyWong16 <9099342+JonnyWong16@users.noreply.github.com> Date: Wed, 8 Jul 2026 17:03:46 -0700 Subject: [PATCH 5/6] Change default PlayQueue.create kwargs to bool --- plexapi/playqueue.py | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/plexapi/playqueue.py b/plexapi/playqueue.py index a8b9a9ff1..a29844361 100644 --- a/plexapi/playqueue.py +++ b/plexapi/playqueue.py @@ -141,20 +141,20 @@ 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 ): args = { "machineIdentifier": server.machineIdentifier, - "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 } @@ -182,11 +182,11 @@ def create( 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`. @@ -197,11 +197,11 @@ def create( 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. + 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. """ From a578693d2d83a48446c5364423d608fc14687238 Mon Sep 17 00:00:00 2001 From: JonnyWong16 <9099342+JonnyWong16@users.noreply.github.com> Date: Fri, 10 Jul 2026 09:44:41 -0700 Subject: [PATCH 6/6] Add additional params to client createPlayQueue --- plexapi/client.py | 22 ++++++++++++++++++---- plexapi/playqueue.py | 1 - 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/plexapi/client.py b/plexapi/client.py index 29a5052b3..2329cdec0 100644 --- a/plexapi/client.py +++ b/plexapi/client.py @@ -481,18 +481,32 @@ def setVideoStream(self, videoStreamID, mtype=DEFAULT_MTYPE): """ self.setStreams(videoStreamID=videoStreamID, mtype=mtype) - def createPlayQueue(self, server, items, paused=False, **kwargs): + 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. - paused (bool, optional): Set True to pause playback, False (default) to start playback immediately. - **kwargs (dict): Additional options to apply to the playqueue. + 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. """ - args = PlayQueue._createArgs(server=server, items=items, paused=int(bool(paused)), **kwargs) + 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): diff --git a/plexapi/playqueue.py b/plexapi/playqueue.py index a29844361..2d59bd92d 100644 --- a/plexapi/playqueue.py +++ b/plexapi/playqueue.py @@ -149,7 +149,6 @@ def _createArgs( **kwargs ): args = { - "machineIdentifier": server.machineIdentifier, "includeChapters": int(bool(includeChapters)), "includeRelated": int(bool(includeRelated)), "repeat": int(bool(repeat)),