mirror of
https://github.com/jellyfin/jellyfin-kodi.git
synced 2024-11-10 12:16:12 +00:00
Fix source selection for direct stream
And missing imports. Fix set_artwork.
This commit is contained in:
parent
304aa503e1
commit
1798e6e01d
4 changed files with 69 additions and 63 deletions
|
@ -12,7 +12,7 @@ import xbmcgui
|
||||||
import downloadutils
|
import downloadutils
|
||||||
import embydb_functions as embydb
|
import embydb_functions as embydb
|
||||||
import playbackutils as pbutils
|
import playbackutils as pbutils
|
||||||
from utils import window, settings
|
from utils import window, settings, create_id
|
||||||
from ga_client import log_error
|
from ga_client import log_error
|
||||||
from database import DatabaseConn
|
from database import DatabaseConn
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ class KodiMonitor(xbmc.Monitor):
|
||||||
return self._on_play_(data)
|
return self._on_play_(data)
|
||||||
else:
|
else:
|
||||||
if ((settings('useDirectPaths') == "1" and not item_type == "song") or
|
if ((settings('useDirectPaths') == "1" and not item_type == "song") or
|
||||||
(item_type == "song" and settings('enableMusic') == "true")):
|
(item_type == "song" and settings('enableMusic') == "true")):
|
||||||
# Set up properties for player
|
# Set up properties for player
|
||||||
item_id = self._get_item_id(kodi_id, item_type)
|
item_id = self._get_item_id(kodi_id, item_type)
|
||||||
if item_id:
|
if item_id:
|
||||||
|
@ -142,15 +142,13 @@ class KodiMonitor(xbmc.Monitor):
|
||||||
count += 1
|
count += 1
|
||||||
xbmc.sleep(200)
|
xbmc.sleep(200)
|
||||||
else:
|
else:
|
||||||
listitem = xbmcgui.ListItem()
|
window('emby_%s.play.json' % playurl, {
|
||||||
playback = pbutils.PlaybackUtils(result)
|
|
||||||
|
|
||||||
if item_type == "song" and settings('streamMusic') == "true":
|
'playmethod': "DirectStream" if item_type == "song" and settings('streamMusic') == "true" else "DirectPlay",
|
||||||
window('emby_%s.playmethod' % playurl, value="DirectStream")
|
'playsession_id': str(create_id()).replace("-", "")
|
||||||
else:
|
})
|
||||||
window('emby_%s.playmethod' % playurl, value="DirectPlay")
|
listitem = xbmcgui.ListItem()
|
||||||
# Set properties for player.py
|
pbutils.PlaybackUtils(result).set_properties(playurl, listitem)
|
||||||
playback.set_properties(playurl, listitem)
|
|
||||||
|
|
||||||
def _video_update(self, data):
|
def _video_update(self, data):
|
||||||
# Manually marking as watched/unwatched
|
# Manually marking as watched/unwatched
|
||||||
|
@ -242,7 +240,7 @@ class SpecialMonitor(threading.Thread):
|
||||||
elif isPlaying and not window('emby.external_check'):
|
elif isPlaying and not window('emby.external_check'):
|
||||||
time = player.getTime()
|
time = player.getTime()
|
||||||
|
|
||||||
if time > 1:
|
if time > 1: # Not external player.
|
||||||
window('emby.external_check', value="true")
|
window('emby.external_check', value="true")
|
||||||
self.external_count = 0
|
self.external_count = 0
|
||||||
elif self.external_count == 15:
|
elif self.external_count == 15:
|
||||||
|
|
|
@ -163,7 +163,7 @@ class PlaybackUtils(object):
|
||||||
# Set listitem and properties for each additional parts
|
# Set listitem and properties for each additional parts
|
||||||
pb = PlaybackUtils(part)
|
pb = PlaybackUtils(part)
|
||||||
pb.set_properties(url, listitem)
|
pb.set_properties(url, listitem)
|
||||||
pb.setArtwork(listitem)
|
pb.set_artwork(listitem, part['Type'])
|
||||||
|
|
||||||
self.stack.append([url, listitem])
|
self.stack.append([url, listitem])
|
||||||
|
|
||||||
|
@ -217,16 +217,19 @@ class PlaybackUtils(object):
|
||||||
item_id = self.item['Id']
|
item_id = self.item['Id']
|
||||||
item_type = self.item['Type']
|
item_type = self.item['Type']
|
||||||
|
|
||||||
play_method = window('emby_%s.playmethod' % url)
|
info = window('emby_%s.play.json' % url)
|
||||||
window('emby_%s.playmethod' % url, clear=True)
|
window('emby_%s.play.json' % url, clear=True)
|
||||||
|
|
||||||
window('emby_%s.json' % url, {
|
window('emby_%s.json' % url, {
|
||||||
|
|
||||||
'url': url,
|
'url': url,
|
||||||
'runtime': str(self.item.get('RunTimeTicks')),
|
'runtime': str(self.item.get('RunTimeTicks')),
|
||||||
'type': item_type,
|
'type': item_type,
|
||||||
'id': item_id,
|
'id': item_id,
|
||||||
|
'mediasource_id': info.get('mediasource_id', item_id),
|
||||||
'refreshid': self.item.get('SeriesId') if item_type == "Episode" else item_id,
|
'refreshid': self.item.get('SeriesId') if item_type == "Episode" else item_id,
|
||||||
'playmethod': play_method
|
'playmethod': info['playmethod'],
|
||||||
|
'playsession_id': info['playsession_id']
|
||||||
})
|
})
|
||||||
|
|
||||||
self.set_artwork(listitem, item_type)
|
self.set_artwork(listitem, item_type)
|
||||||
|
@ -279,6 +282,7 @@ class PlaybackUtils(object):
|
||||||
else:
|
else:
|
||||||
listitem.setArt({art: path})
|
listitem.setArt({art: path})
|
||||||
|
|
||||||
|
|
||||||
def play_all(self, item_ids, seektime=None, **kwargs):
|
def play_all(self, item_ids, seektime=None, **kwargs):
|
||||||
|
|
||||||
self.playlist.clear()
|
self.playlist.clear()
|
||||||
|
|
|
@ -11,6 +11,7 @@ import xbmcgui
|
||||||
|
|
||||||
import clientinfo
|
import clientinfo
|
||||||
import downloadutils
|
import downloadutils
|
||||||
|
import read_embyserver as embyserver
|
||||||
import websocket_client as wsc
|
import websocket_client as wsc
|
||||||
from utils import window, settings, language as lang, JSONRPC
|
from utils import window, settings, language as lang, JSONRPC
|
||||||
from ga_client import GoogleAnalytics, log_error
|
from ga_client import GoogleAnalytics, log_error
|
||||||
|
@ -37,6 +38,7 @@ class Player(xbmc.Player):
|
||||||
|
|
||||||
self.clientInfo = clientinfo.ClientInfo()
|
self.clientInfo = clientinfo.ClientInfo()
|
||||||
self.doUtils = downloadutils.DownloadUtils().downloadUrl
|
self.doUtils = downloadutils.DownloadUtils().downloadUrl
|
||||||
|
self.emby = embyserver.Read_EmbyServer()
|
||||||
self.ws = wsc.WebSocketClient()
|
self.ws = wsc.WebSocketClient()
|
||||||
self.xbmcplayer = xbmc.Player()
|
self.xbmcplayer = xbmc.Player()
|
||||||
|
|
||||||
|
@ -128,6 +130,9 @@ class Player(xbmc.Player):
|
||||||
refresh_id = item.get('refreshid')
|
refresh_id = item.get('refreshid')
|
||||||
play_method = item.get('playmethod')
|
play_method = item.get('playmethod')
|
||||||
item_type = item.get('type')
|
item_type = item.get('type')
|
||||||
|
playsession_id = item.get('playsession_id')
|
||||||
|
mediasource_id = item.get('mediasource_id')
|
||||||
|
|
||||||
|
|
||||||
#self.set_audio_subs(item.get('forcedaudio'), item.get('forcedsubs'))
|
#self.set_audio_subs(item.get('forcedaudio'), item.get('forcedsubs'))
|
||||||
|
|
||||||
|
@ -156,14 +161,15 @@ class Player(xbmc.Player):
|
||||||
url = "{server}/emby/Sessions/Playing"
|
url = "{server}/emby/Sessions/Playing"
|
||||||
postdata = {
|
postdata = {
|
||||||
|
|
||||||
'QueueableMediaTypes': "Video",
|
'QueueableMediaTypes': "Video,Audio",
|
||||||
'CanSeek': True,
|
'CanSeek': True,
|
||||||
'ItemId': item_id,
|
'ItemId': item_id,
|
||||||
'MediaSourceId': item_id,
|
'MediaSourceId': mediasource_id or item_id,
|
||||||
'PlayMethod': play_method,
|
'PlayMethod': play_method,
|
||||||
'VolumeLevel': volume,
|
'VolumeLevel': volume,
|
||||||
'PositionTicks': int(seekTime * 10000000),
|
'PositionTicks': int(seekTime * 10000000),
|
||||||
'IsMuted': muted
|
'IsMuted': muted,
|
||||||
|
'PlaySessionId': playsession_id
|
||||||
}
|
}
|
||||||
|
|
||||||
# Get the current audio track and subtitles
|
# Get the current audio track and subtitles
|
||||||
|
@ -249,13 +255,15 @@ class Player(xbmc.Player):
|
||||||
|
|
||||||
'runtime': runtime,
|
'runtime': runtime,
|
||||||
'item_id': item_id,
|
'item_id': item_id,
|
||||||
|
'mediasource_id': mediasource_id,
|
||||||
'refresh_id': refresh_id,
|
'refresh_id': refresh_id,
|
||||||
'currentfile': currentFile,
|
'currentfile': currentFile,
|
||||||
'AudioStreamIndex': postdata['AudioStreamIndex'],
|
'AudioStreamIndex': postdata['AudioStreamIndex'],
|
||||||
'SubtitleStreamIndex': postdata['SubtitleStreamIndex'],
|
'SubtitleStreamIndex': postdata['SubtitleStreamIndex'],
|
||||||
'playmethod': play_method,
|
'playmethod': play_method,
|
||||||
'Type': item_type,
|
'Type': item_type,
|
||||||
'currentPosition': int(seekTime)
|
'currentPosition': int(seekTime),
|
||||||
|
'playsession_id': playsession_id
|
||||||
}
|
}
|
||||||
|
|
||||||
self.played_info[currentFile] = data
|
self.played_info[currentFile] = data
|
||||||
|
@ -282,6 +290,8 @@ class Player(xbmc.Player):
|
||||||
playTime = data['currentPosition']
|
playTime = data['currentPosition']
|
||||||
playMethod = data['playmethod']
|
playMethod = data['playmethod']
|
||||||
paused = data.get('paused', False)
|
paused = data.get('paused', False)
|
||||||
|
playsession_id = data.get('playsession_id')
|
||||||
|
mediasource_id = data.get('mediasource_id')
|
||||||
|
|
||||||
|
|
||||||
# Get playback volume
|
# Get playback volume
|
||||||
|
@ -297,12 +307,13 @@ class Player(xbmc.Player):
|
||||||
'QueueableMediaTypes': "Video",
|
'QueueableMediaTypes': "Video",
|
||||||
'CanSeek': True,
|
'CanSeek': True,
|
||||||
'ItemId': itemId,
|
'ItemId': itemId,
|
||||||
'MediaSourceId': itemId,
|
'MediaSourceId': mediasource_id or itemId,
|
||||||
'PlayMethod': playMethod,
|
'PlayMethod': playMethod,
|
||||||
'PositionTicks': int(playTime * 10000000),
|
'PositionTicks': int(playTime * 10000000),
|
||||||
'IsPaused': paused,
|
'IsPaused': paused,
|
||||||
'VolumeLevel': volume,
|
'VolumeLevel': volume,
|
||||||
'IsMuted': muted
|
'IsMuted': muted,
|
||||||
|
'PlaySessionId': playsession_id
|
||||||
}
|
}
|
||||||
|
|
||||||
if playMethod == "Transcode":
|
if playMethod == "Transcode":
|
||||||
|
@ -525,24 +536,9 @@ class Player(xbmc.Player):
|
||||||
|
|
||||||
def stopPlayback(self, data):
|
def stopPlayback(self, data):
|
||||||
|
|
||||||
log.debug("stopPlayback called")
|
log.debug("stopPlayback called.")
|
||||||
|
|
||||||
itemId = data['item_id']
|
position_ticks = int(data['currentPosition'] * 10000000)
|
||||||
currentPosition = data['currentPosition']
|
position = data['runtime'] if position_ticks and window('emby.external') else position_ticks
|
||||||
positionTicks = int(currentPosition * 10000000)
|
|
||||||
|
|
||||||
url = "{server}/emby/Sessions/Playing/Stopped"
|
self.emby.stop_playback(data['item_id'], position, data['playsession_id'], data.get('mediasource_id'))
|
||||||
postdata = {
|
|
||||||
|
|
||||||
'ItemId': itemId,
|
|
||||||
'MediaSourceId': itemId,
|
|
||||||
'PositionTicks': positionTicks
|
|
||||||
}
|
|
||||||
self.doUtils(url, postBody=postdata, action_type="POST")
|
|
||||||
|
|
||||||
#If needed, close any livestreams
|
|
||||||
livestreamid = window("emby_%s.livestreamid" % self.currentFile)
|
|
||||||
if livestreamid:
|
|
||||||
url = "{server}/emby/LiveStreams/Close"
|
|
||||||
postdata = { 'LiveStreamId': livestreamid }
|
|
||||||
self.doUtils(url, postBody=postdata, action_type="POST")
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
import collections
|
import collections
|
||||||
import logging
|
import logging
|
||||||
|
import requests
|
||||||
import os
|
import os
|
||||||
import urllib
|
import urllib
|
||||||
|
|
||||||
|
@ -14,7 +15,7 @@ import xbmcvfs
|
||||||
import clientinfo
|
import clientinfo
|
||||||
import downloadutils
|
import downloadutils
|
||||||
import read_embyserver as embyserver
|
import read_embyserver as embyserver
|
||||||
from utils import window, settings, language as lang, urllib_path
|
from utils import window, settings, language as lang, urllib_path, create_id
|
||||||
|
|
||||||
#################################################################################################
|
#################################################################################################
|
||||||
|
|
||||||
|
@ -25,6 +26,7 @@ log = logging.getLogger("EMBY."+__name__)
|
||||||
|
|
||||||
class PlayUtils():
|
class PlayUtils():
|
||||||
|
|
||||||
|
play_session_id = None
|
||||||
method = "DirectPlay"
|
method = "DirectPlay"
|
||||||
force_transcode = False
|
force_transcode = False
|
||||||
|
|
||||||
|
@ -40,6 +42,7 @@ class PlayUtils():
|
||||||
self.emby = embyserver.Read_EmbyServer()
|
self.emby = embyserver.Read_EmbyServer()
|
||||||
|
|
||||||
self.server = window('emby_server%s' % window('emby_currUser'))
|
self.server = window('emby_server%s' % window('emby_currUser'))
|
||||||
|
self.play_session_id = str(create_id()).replace("-", "")
|
||||||
|
|
||||||
def get_play_url(self, force_transcode=False):
|
def get_play_url(self, force_transcode=False):
|
||||||
|
|
||||||
|
@ -50,20 +53,25 @@ class PlayUtils():
|
||||||
|
|
||||||
self.force_transcode = force_transcode
|
self.force_transcode = force_transcode
|
||||||
info = self.get_playback_info()
|
info = self.get_playback_info()
|
||||||
play_url = False if info == False else None
|
url = False if info == False else None
|
||||||
|
|
||||||
if info:
|
if info:
|
||||||
play_url = info['Path'].encode('utf-8')
|
url = info['Path'].encode('utf-8')
|
||||||
window('emby_%s.playmethod' % play_url, value=self.method)
|
window('emby_%s.play.json' % url, {
|
||||||
|
|
||||||
|
'playmethod': self.method,
|
||||||
|
'playsession_id': self.play_session_id,
|
||||||
|
'mediasource_id': info.get('Id') or self.item['Id']
|
||||||
|
})
|
||||||
|
|
||||||
if self.method == "DirectPlay":
|
if self.method == "DirectPlay":
|
||||||
# Log filename, used by other addons eg subtitles which require the file name
|
# Log filename, used by other addons eg subtitles which require the file name
|
||||||
window('embyfilename', value=play_url)
|
window('embyfilename', value=url)
|
||||||
|
|
||||||
log.info("playback info: %s", info)
|
log.info("playback info: %s", info)
|
||||||
log.info("play method: %s play url: %s", self.method, play_url)
|
log.info("play method: %s play url: %s", self.method, url)
|
||||||
|
|
||||||
return play_url
|
return url
|
||||||
|
|
||||||
def get_playback_info(self):
|
def get_playback_info(self):
|
||||||
|
|
||||||
|
@ -208,35 +216,35 @@ class PlayUtils():
|
||||||
transcode = False
|
transcode = False
|
||||||
break
|
break
|
||||||
|
|
||||||
play_url = self.get_transcode_url(source) if transcode else self.get_direct_url(source)
|
url = self.get_transcode_url(source) if transcode else self.get_direct_url(source)
|
||||||
|
url += "&MediaSourceId=%s" % source['Id']
|
||||||
|
url += "&PlaySessionId=%s" % self.play_session_id
|
||||||
|
url += "&api_key=%s" % downloadutils.DownloadUtils().get_token()
|
||||||
|
|
||||||
user_token = downloadutils.DownloadUtils().get_token()
|
return url
|
||||||
play_url += "&api_key=" + user_token
|
|
||||||
|
|
||||||
return play_url
|
|
||||||
|
|
||||||
def get_direct_url(self, source):
|
def get_direct_url(self, source):
|
||||||
|
|
||||||
self.method = "DirectStream"
|
self.method = "DirectStream"
|
||||||
|
|
||||||
if self.item['Type'] == "Audio":
|
if self.item['Type'] == "Audio":
|
||||||
play_url = "%s/emby/Audio/%s/stream.%s?static=true" % (self.server, self.item['Id'], self.item['MediaSources'][0]['Container'])
|
url = "%s/emby/Audio/%s/stream.%s?static=true" % (self.server, self.item['Id'], self.item['MediaSources'][0]['Container'])
|
||||||
else:
|
else:
|
||||||
play_url = "%s/emby/Videos/%s/stream?static=true" % (self.server, self.item['Id'])
|
url = "%s/emby/Videos/%s/stream?static=true" % (self.server, self.item['Id'])
|
||||||
|
|
||||||
# Append external subtitles
|
# Append external subtitles
|
||||||
if settings('enableExternalSubs') == "true":
|
if settings('enableExternalSubs') == "true":
|
||||||
self.set_external_subs(source, play_url)
|
self.set_external_subs(source, url)
|
||||||
|
|
||||||
return play_url
|
return url
|
||||||
|
|
||||||
def get_transcode_url(self, source):
|
def get_transcode_url(self, source):
|
||||||
|
|
||||||
self.method = "Transcode"
|
self.method = "Transcode"
|
||||||
|
|
||||||
item_id = self.item['Id']
|
item_id = self.item['Id']
|
||||||
play_url = urllib_path("%s/emby/Videos/%s/master.m3u8" % (self.server, item_id), {
|
url = urllib_path("%s/emby/Videos/%s/master.m3u8" % (self.server, item_id), {
|
||||||
'MediaSourceId': source['Id'],
|
|
||||||
'VideoCodec': "h264",
|
'VideoCodec': "h264",
|
||||||
'AudioCodec': "ac3",
|
'AudioCodec': "ac3",
|
||||||
'MaxAudioChannels': 6,
|
'MaxAudioChannels': 6,
|
||||||
|
@ -246,14 +254,14 @@ class PlayUtils():
|
||||||
|
|
||||||
# Limit to 8 bit if user selected transcode Hi10P
|
# Limit to 8 bit if user selected transcode Hi10P
|
||||||
if settings('transcodeHi10P') == "true":
|
if settings('transcodeHi10P') == "true":
|
||||||
play_url += "&MaxVideoBitDepth=8"
|
url += "&MaxVideoBitDepth=8"
|
||||||
|
|
||||||
# Adjust the video resolution
|
# Adjust the video resolution
|
||||||
play_url += "&maxWidth=%s&maxHeight=%s" % (self.get_resolution())
|
url += "&maxWidth=%s&maxHeight=%s" % (self.get_resolution())
|
||||||
# Select audio and subtitles
|
# Select audio and subtitles
|
||||||
play_url += self.get_audio_subs(source)
|
url += self.get_audio_subs(source)
|
||||||
|
|
||||||
return play_url
|
return url
|
||||||
|
|
||||||
def set_external_subs(self, source, play_url):
|
def set_external_subs(self, source, play_url):
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue