PlexKodiConnect/resources/lib/playqueue.py

147 lines
5.2 KiB
Python
Raw Normal View History

2017-12-09 05:43:06 +11:00
"""
Monitors the Kodi playqueue and adjusts the Plex playqueue accordingly
"""
2017-12-10 00:35:08 +11:00
from logging import getLogger
2017-01-03 00:07:24 +11:00
from threading import RLock, Thread
2016-12-28 03:33:52 +11:00
from xbmc import Player, PlayList, PLAYLIST_MUSIC, PLAYLIST_VIDEO
2016-12-28 03:33:52 +11:00
from utils import window
2016-12-28 03:33:52 +11:00
import playlist_func as PL
2017-03-06 03:51:58 +11:00
from PlexFunctions import ConvertPlexToKodiTime, GetAllPlexChildren
from PlexAPI import API
2017-01-10 05:56:57 +11:00
from playbackutils import PlaybackUtils
2017-12-09 05:43:06 +11:00
import json_rpc as js
2017-03-06 03:51:58 +11:00
import variables as v
2016-12-28 03:33:52 +11:00
###############################################################################
2017-12-10 00:35:08 +11:00
LOG = getLogger("PLEX." + __name__)
2016-12-28 03:33:52 +11:00
2017-12-09 05:43:06 +11:00
# lock used for playqueue manipulations
LOCK = RLock()
PLUGIN = 'plugin://%s' % v.ADDON_ID
# Our PKC playqueues (3 instances of Playqueue_Object())
PLAYQUEUES = []
2016-12-28 03:33:52 +11:00
###############################################################################
def init_playqueues():
2016-12-28 03:33:52 +11:00
"""
Call this once on startup to initialize the PKC playqueue objects in
the list PLAYQUEUES
2016-12-28 03:33:52 +11:00
"""
if PLAYQUEUES:
LOG.debug('Playqueues have already been initialized')
return
# Initialize Kodi playqueues
with LOCK:
for i in (0, 1, 2):
# Just in case the Kodi response is not sorted correctly
2017-12-09 05:43:06 +11:00
for queue in js.get_playlists():
if queue['playlistid'] != i:
continue
2017-01-03 00:07:24 +11:00
playqueue = PL.Playqueue_Object()
playqueue.playlistid = i
2017-01-03 00:07:24 +11:00
playqueue.type = queue['type']
# Initialize each Kodi playlist
if playqueue.type == v.KODI_TYPE_AUDIO:
2017-01-03 00:07:24 +11:00
playqueue.kodi_pl = PlayList(PLAYLIST_MUSIC)
elif playqueue.type == v.KODI_TYPE_VIDEO:
2017-01-03 00:07:24 +11:00
playqueue.kodi_pl = PlayList(PLAYLIST_VIDEO)
else:
# Currently, only video or audio playqueues available
playqueue.kodi_pl = PlayList(PLAYLIST_VIDEO)
# Overwrite 'picture' with 'photo'
playqueue.type = v.KODI_TYPE_PHOTO
PLAYQUEUES.append(playqueue)
LOG.debug('Initialized the Kodi playqueues: %s', PLAYQUEUES)
2016-12-28 03:33:52 +11:00
2016-12-30 01:41:14 +11:00
2018-01-11 06:14:05 +11:00
def get_playqueue_from_type(kodi_playlist_type):
"""
2018-01-11 06:14:05 +11:00
Returns the playqueue according to the kodi_playlist_type ('video',
'audio', 'picture') passed in
"""
with LOCK:
for playqueue in PLAYQUEUES:
2018-01-11 06:14:05 +11:00
if playqueue.type == kodi_playlist_type:
break
else:
2018-01-11 06:14:05 +11:00
raise ValueError('Wrong playlist type passed in: %s',
kodi_playlist_type)
return playqueue
2017-03-06 03:51:58 +11:00
2016-12-28 23:14:21 +11:00
def init_playqueue_from_plex_children(plex_id, transient_token=None):
"""
Init a new playqueue e.g. from an album. Alexa does this
2016-12-29 00:48:23 +11:00
Returns the Playlist_Object
"""
xml = GetAllPlexChildren(plex_id)
try:
xml[0].attrib
except (TypeError, IndexError, AttributeError):
LOG.error('Could not download the PMS xml for %s', plex_id)
return
playqueue = get_playqueue_from_type(
v.KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[xml[0].attrib['type']])
playqueue.clear()
for i, child in enumerate(xml):
api = API(child)
PL.add_item_to_playlist(playqueue, i, plex_id=api.getRatingKey())
playqueue.plex_transient_token = transient_token
LOG.debug('Firing up Kodi player')
Player().play(playqueue.kodi_pl, None, False, 0)
return playqueue
2016-12-29 05:38:43 +11:00
def update_playqueue_from_PMS(playqueue,
playqueue_id=None,
repeat=None,
offset=None,
transient_token=None):
"""
Completely updates the Kodi playqueue with the new Plex playqueue. Pass
in playqueue_id if we need to fetch a new playqueue
repeat = 0, 1, 2
offset = time offset in Plextime (milliseconds)
"""
LOG.info('New playqueue %s received from Plex companion with offset '
'%s, repeat %s', playqueue_id, offset, repeat)
# Safe transient token from being deleted
if transient_token is None:
transient_token = playqueue.plex_transient_token
with LOCK:
xml = PL.get_PMS_playlist(playqueue, playqueue_id)
playqueue.clear()
try:
PL.get_playlist_details_from_xml(playqueue, xml)
except KeyError:
LOG.error('Could not get playqueue ID %s', playqueue_id)
return
playqueue.repeat = 0 if not repeat else int(repeat)
playqueue.plex_transient_token = transient_token
PlaybackUtils(xml, playqueue).play_all()
window('plex_customplaylist', value="true")
if offset not in (None, "0"):
window('plex_customplaylist.seektime',
str(ConvertPlexToKodiTime(offset)))
for startpos, item in enumerate(playqueue.items):
if item.id == playqueue.selectedItemID:
break
else:
startpos = 0
# Start playback. Player does not return in time
LOG.debug('Playqueues after Plex Companion update are now: %s',
PLAYQUEUES)
thread = Thread(target=Player().play,
args=(playqueue.kodi_pl,
None,
False,
startpos))
thread.setDaemon(True)
thread.start()