Support up next

This commit is contained in:
angelblue05 2018-10-15 06:26:11 -05:00
parent 5808c449c4
commit c3fbdf082c
5 changed files with 110 additions and 18 deletions

View File

@ -159,6 +159,13 @@ def get_next(index=None, limit=1):
'StartIndex': None if index is None else int(index)
})
def get_adjacent_episodes(show_id, item_id):
return shows("/%s/Episodes" % show_id, {
'UserId': "{UserId}",
'AdjacentTo': item_id,
'Fields': "Overview"
})
def get_genres(parent_id=None):
return _get("Genres", {
'ParentId': parent_id,

View File

@ -46,7 +46,8 @@ def set_properties(item, method, server_id=None):
'SubsMapping': info.get('Subtitles'),
'AudioStreamIndex': info.get('AudioStreamIndex'),
'SubtitleStreamIndex': info.get('SubtitleStreamIndex'),
'CurrentPosition': info.get('CurrentPosition')
'CurrentPosition': info.get('CurrentPosition'),
'CurrentEpisode': info.get('CurrentEpisode')
})
window('emby_play.json', current)
@ -400,6 +401,14 @@ class PlayUtils(object):
}
if settings('transcode_h265.bool'):
profile['DirectPlayProfiles'][0]['VideoCodec'] = "h264,mpeg4,mpeg2video"
else:
profile['TranscodingProfiles'].insert(0, {
"Container": "m3u8",
"Type": "Video",
"AudioCodec": "aac,mp3,ac3,opus,flac,vorbis",
"VideoCodec": "h264,h265,hevc,mpeg4,mpeg2video",
"MaxAudioChannels": "6"
})
if settings('transcodeHi10P.bool'):
profile['CodecProfiles'].append(

View File

@ -2,6 +2,7 @@
#################################################################################################
import binascii
import json
import logging
import os
@ -127,13 +128,20 @@ def find(dict, item):
if re.match(key, item, re.I):
return dict[key]
def event(method, data=None):
def event(method, data=None, sender=None, hexlify=False):
''' Data is a dictionary.
'''
data = data or {}
xbmc.executebuiltin('NotifyAll(plugin.video.emby, %s, "[%s]")' % (method, json.dumps(data).replace('"', '\\"')))
LOG.debug("---[ event: %s ] %s", method, data)
sender = sender or "plugin.video.emby"
if hexlify:
data = '\\"[\\"{0}\\"]\\"'.format(binascii.hexlify(json.dumps(data)))
else:
data = '"[%s]"' % json.dumps(data).replace('"', '\\"')
xbmc.executebuiltin('NotifyAll(%s, %s, %s)' % (sender, method, data))
LOG.debug("---[ event: %s/%s ] %s", sender, method, data)
def dialog(dialog_type, *args, **kwargs):

View File

@ -2,6 +2,7 @@
#################################################################################################
import binascii
import json
import logging
import threading
@ -45,8 +46,8 @@ class Monitor(xbmc.Monitor):
LOG.info("--<[ kodi scan/%s ]", library)
def onNotification(self, sender, method, data):
if sender.lower() not in ('plugin.video.emby', 'xbmc'):
if sender.lower() not in ('plugin.video.emby', 'xbmc', 'upnextprovider'):
return
if sender == 'plugin.video.emby':
@ -61,6 +62,18 @@ class Monitor(xbmc.Monitor):
return
data = json.loads(data)[0]
elif sender == 'upnextprovider':
method = method.split('.')[1]
if method not in ('plugin.video.emby_play_action'):
return
data = json.loads(data)
method = "Play"
if data:
data = json.loads(binascii.unhexlify(data[0]))
else:
if method not in ('Player.OnPlay', 'VideoLibrary.OnUpdate', 'Player.OnAVChange'):
return

View File

@ -9,7 +9,8 @@ import os
import xbmc
import xbmcvfs
from helper import _, window, settings, dialog, JSONRPC
from objects.obj import Objects
from helper import _, api, window, settings, dialog, event, JSONRPC
from emby import Emby
#################################################################################################
@ -24,6 +25,7 @@ class Player(xbmc.Player):
# Borg - multiple instances, shared state
_shared_state = {}
played = {}
up_next = False
def __init__(self):
@ -35,6 +37,7 @@ class Player(xbmc.Player):
''' We may need to wait for info to be set in kodi monitor.
Accounts for scenario where Kodi starts playback and exits immediately.
'''
self.up_next = False
count = 0
monitor = xbmc.Monitor()
@ -219,6 +222,49 @@ class Player(xbmc.Player):
else:
item['SubtitleStreamIndex'] = subs + tracks + 1
def next_up(self):
current_file = self.getPlayingFile()
item = self.played[current_file]
objects = Objects()
if item['Type'] != 'Episode':
return
next_items = item['Server']['api'].get_adjacent_episodes(item['CurrentEpisode']['tvshowid'], item['Id'])
for index, next_item in enumerate(next_items['Items']):
if next_item['Id'] == item['Id']:
try:
next_item = next_items['Items'][index + 1]
except IndexError:
LOG.warn("No next up episode.")
return
break
API = api.API(next_item, item['Server']['auth/server-address'])
data = objects.map(next_item, "UpNext")
artwork = API.get_all_artwork(objects.map(next_item, 'ArtworkParent'), True)
data['art'] = {
'tvshow.poster': artwork.get('Series.Primary'),
'tvshow.fanart': None,
'thumb': artwork.get('Primary')
}
if artwork['Backdrop']:
data['art']['tvshow.fanart'] = artwork['Backdrop'][0]
next_info = {
'play_info': {'ItemIds': [data['episodeid']], 'ServerId': item['ServerId'], 'PlayCommand': 'PlayNow'},
'current_episode': item['CurrentEpisode'],
'next_episode': data
}
LOG.debug("--[ next up ] %s", json.dumps(next_info, indent=4))
event("upnext_data", next_info, hexlify=True)
def onPlayBackPaused(self):
current_file = self.getPlayingFile()
@ -268,15 +314,32 @@ class Player(xbmc.Player):
item = self.played[current_file]
if window('emby.external.bool'):
return
if not report:
previous = item['CurrentPosition']
item['CurrentPosition'] = int(self.getTime())
if int(item['CurrentPosition']) == 1:
return
try:
played = float(item['CurrentPosition'] * 10000000) / int(item['Runtime']) * 100
except ZeroDivisionError: # Runtime is 0.
played = 0
if played > 2.0 and not self.up_next:
self.up_next = True
self.next_up()
if (item['CurrentPosition'] - previous) < 30:
return
result = JSONRPC('Application.GetProperties').execute({'properties': ["volume", "muted"]})
result = result.get('result', {})
item['Volume'] = result.get('volume')
@ -330,18 +393,10 @@ class Player(xbmc.Player):
if item:
window('emby.skip.%s.bool' % item['Id'], True)
if item['CurrentPosition'] and item['Runtime']:
if window('emby.external.bool'):
window('emby.external', clear=True)
try:
if window('emby.external.bool'):
window('emby.external', clear=True)
raise ValueError
played = float(item['CurrentPosition'] * 10000000) / int(item['Runtime'])
except ZeroDivisionError: # Runtime is 0.
played = 0
except ValueError:
played = 100
if int(item['CurrentPosition']) == 1:
item['CurrentPosition'] = int(item['Runtime'])
data = {