Skip to content

Commit 0c1d904

Browse files
authored
Add support for lists, playQueues, and playlists to Plex controller. (#418)
* Add support for playQueues, playlists, lists of media w/ startItem arg Thanks to recent changes by @jjlawren to PlexAPI's playQueues, this adds support for playing additional types of media to Chromecasts when using Python-PlexAPI (4.1.1+). Adds list, playQueue, and playlist support (possibly just fixes playlists, they weren't working for me before). Also adds the ability to start at any point in the list/queue/playlist by providing a media item as startItem. * Refactor _reset_playback offset * Ex. Playing lists, playlists, playQueues, media, w/ or w/o startItem. * Formatting, SP, and grammar of docstring, logs, and comments. * Pass existing playQueues as is unless startItem is used This makes it so you can pass a playQueue without stripping it's args. You can still use startItem by using the playQueue's args and not the play media method: `Plex.server.createPlayQueue(media, shuffle=1, continuous=1, startItem=media[3])` * Typo
1 parent 91eb57e commit 0c1d904

File tree

2 files changed

+259
-95
lines changed

2 files changed

+259
-95
lines changed

examples/plex_multi_example.py

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
"""
2+
Examples of the Plex controller playing on a Chromecast.
3+
4+
DEMO TYPES:
5+
* simple: Picks the first item it finds in your libray and plays it.
6+
* list: Creates a list of items from your library and plays them.
7+
* playqueue: Creates a playqueue and plays it.
8+
* playlist: Creates a playlist, plays it, then deletes it.
9+
10+
All demos with the exception of 'simple' can use startItem.
11+
startItem lets you start playback anywhere in the list of items.
12+
turning this option on will pick an item in the middle of the list to start from.
13+
14+
This demo uses features that require the latest Python-PlexAPI
15+
pip install plexapi
16+
17+
"""
18+
19+
import pychromecast
20+
import argparse
21+
import logging
22+
import zeroconf
23+
import sys
24+
25+
from pychromecast.controllers.plex import PlexController
26+
from plexapi.server import PlexServer
27+
28+
29+
# Change to the friendly name of your Chromecast.
30+
CAST_NAME = "Office TV"
31+
32+
# Replace with your own Plex URL, including port.
33+
PLEX_URL = "http://192.168.1.3:32400"
34+
35+
# Replace with your Plex token. See link below on how to find it:
36+
# https://support.plex.tv/articles/204059436-finding-an-authentication-token-x-plex-token/
37+
PLEX_TOKEN = "Y0urT0k3nH3rE"
38+
39+
# Library of items to pick from for tests. Use "episode", "movie", or "track".
40+
PLEX_LIBRARY = "episode"
41+
42+
# The demo type you'd like to run.
43+
# Options are "single", "list", "playqueue", or "playlist"
44+
DEMO_TYPE = "playqueue"
45+
46+
# If demo type is anything other than "single",
47+
# make this True to see a demo of startItem.
48+
START_ITEM = True
49+
50+
parser = argparse.ArgumentParser(
51+
description="How to play media items, lists, playQueues, "
52+
"and playlists to a Chromecast device."
53+
)
54+
parser.add_argument("--show-debug", help="Enable debug log", action="store_true")
55+
parser.add_argument(
56+
"--show-zeroconf-debug", help="Enable zeroconf debug log", action="store_true"
57+
)
58+
parser.add_argument(
59+
"--cast", help='Name of cast device (default: "%(default)s").', default=CAST_NAME
60+
)
61+
parser.add_argument(
62+
"--url", help='URL of your Plex Server (default: "%(default)s").', default=PLEX_URL
63+
)
64+
parser.add_argument(
65+
"--library",
66+
help="The library you'd like to test: episode, movie, or track (default: '%(default)s').",
67+
default=PLEX_LIBRARY,
68+
)
69+
parser.add_argument("--token", help="Your Plex token.", default=PLEX_TOKEN)
70+
parser.add_argument(
71+
"--demo",
72+
help="The demo you'd like to run: single, list, playqueue, or playlist (default: '%(default)s').",
73+
default=DEMO_TYPE,
74+
)
75+
parser.add_argument(
76+
"--startitem",
77+
help="If demo type is anything other than 'single', set to True to see a demo of startItem (default: '%(default)s').",
78+
default=START_ITEM,
79+
)
80+
81+
args = parser.parse_args()
82+
if args.show_debug:
83+
logging.basicConfig(level=logging.DEBUG)
84+
if args.show_zeroconf_debug:
85+
print("Zeroconf version: " + zeroconf.__version__)
86+
logging.getLogger("zeroconf").setLevel(logging.DEBUG)
87+
startItem = None
88+
89+
90+
def media_info(media, items):
91+
print(f"Cast Device: {cast.name}")
92+
print(f"Media Type: {type(media)}")
93+
print(f"Media Items: {items}")
94+
95+
96+
def start_item_info(media):
97+
if args.startitem:
98+
print(f"Starting From: {media}")
99+
100+
101+
chromecasts, browser = pychromecast.get_listed_chromecasts(friendly_names=[args.cast])
102+
cast = next((cc for cc in chromecasts if cc.name == args.cast), None)
103+
104+
if not cast:
105+
print(f"No chromecast with name '{args.cast}' found.")
106+
foundCasts = ", ".join([cc.name for cc in pychromecast.get_chromecasts()[0]])
107+
print(f"Chromecasts found: {foundCasts}")
108+
sys.exit(1)
109+
110+
plex_server = PlexServer(args.url, args.token)
111+
112+
# Create a list of 5 items from the selected library.
113+
libraryItems = plex_server.library.search(
114+
libtype=args.library, sort="addedAt:desc", limit=5
115+
)
116+
117+
if args.demo == "single":
118+
# Use a single item as media.
119+
media = libraryItems[0]
120+
media_info(media, libraryItems[0])
121+
elif args.demo == "list":
122+
# Use the unaltered list as media.
123+
media = libraryItems
124+
# Set starting position to the 2nd item if startItem demo.
125+
startItem = libraryItems[1] if args.startitem else None
126+
# Print info
127+
media_info(libraryItems, libraryItems)
128+
start_item_info(libraryItems[1])
129+
elif args.demo == "playqueue":
130+
# Convert list into a playqueue for media.
131+
media = plex_server.createPlayQueue(libraryItems)
132+
# Set starting position to the 3rd item if startItem demo.
133+
startItem = libraryItems[2] if args.startitem else None
134+
# Print info
135+
media_info(media, media.items)
136+
start_item_info(libraryItems[2])
137+
elif args.demo == "playlist":
138+
# Convert list into a playlist for media.
139+
media = plex_server.createPlaylist("pychromecast test playlist", libraryItems)
140+
# Set starting position to the 4th item if startItem demo.
141+
startItem = libraryItems[3] if args.startitem else None
142+
# Print info
143+
media_info(media, media.items())
144+
start_item_info(libraryItems[2])
145+
146+
plex_c = PlexController()
147+
cast.register_handler(plex_c)
148+
cast.wait()
149+
150+
# Plays the media item, list, playlist, or playqueue.
151+
# If startItem = None it is ignored and playback starts at first item,
152+
# otherwise playback starts at the position of the media item given.
153+
plex_c.block_until_playing(media, startItem=startItem)
154+
155+
if getattr(media, "TYPE", None) == "playlist":
156+
media.delete()

0 commit comments

Comments
 (0)