# -*- coding: utf-8 -*- import json import threading import uuid import xbmc import database.database import database.emby_db import core.queries_videos import helper.jsonrpc import helper.loghandler class ProgressUpdates(threading.Thread): def __init__(self, Player): self.Player = Player self.Exit = False threading.Thread.__init__(self) def Stop(self): self.Exit = True def run(self): while True: if xbmc.Monitor().waitForAbort(5): return if not self.Exit: self.Player.report_playback(True) else: return class PlayerEvents(xbmc.Player): def __init__(self): self.CurrentlyPlaying = {} self.LOG = helper.loghandler.LOG('EMBY.hooks.player.Player') self.Trailer = False self.PlayerReloadIndex = "-1" self.PlayerLastItem = "" self.PlayerLastItemID = "-1" self.ItemSkipUpdate = [] self.ItemSkipUpdateAfterStop = [] self.ItemSkipUpdateReset = False self.SyncPause = False self.ProgressThread = None self.PlaySessionId = "" self.MediasourceID = "" self.Transcoding = False self.CurrentItem = {} self.SkipUpdate = False self.PlaySessionIdLast = "" self.DynamicItem = {} #Threaded by Monitor def OnStop(self, EmbyServer): if self.ProgressThread: self.ProgressThread.Stop() self.ProgressThread = None if self.Transcoding: EmbyServer.API.close_transcode() self.SyncPause = False #Threaded by Monitor def OnPlay(self, data, EmbyServer, library): self.LOG.info("[ OnPlay ] %s " % data) if data['item']['type'] in ('picture', 'unknown'): return if self.ProgressThread: self.ProgressThread.Stop() self.ProgressThread = None self.SyncPause = True if not self.Trailer: if not "id" in data['item']: DynamicID = EmbyServer.Utils.ReplaceSpecialCharecters(data['item']['title']) if DynamicID in self.DynamicItem: self.CurrentItem['Id'] = self.DynamicItem[DynamicID] else: self.CurrentItem['Tracking'] = False return else: kodi_id = data['item']['id'] media_type = data['item']['type'] item = database.database.get_item_complete(EmbyServer.Utils, kodi_id, media_type) if item: self.CurrentItem['Id'] = item[0] else: self.CurrentItem['Tracking'] = False return #Kodi internal Source if EmbyServer.Utils.direct_path: #native mode PresentationKey = item[10].split("-") self.ItemSkipUpdate.append(PresentationKey[0]) self.ItemSkipUpdate.append(self.CurrentItem['Id']) self.ItemSkipUpdateAfterStop.append(PresentationKey[0]) self.ItemSkipUpdateAfterStop.append(self.CurrentItem['Id']) self.PlaySessionId = str(uuid.uuid4()).replace("-", "") self.CurrentItem['Tracking'] = True self.CurrentItem['Type'] = data['item']['type'] self.CurrentItem['Volume'], self.CurrentItem['Muted'] = self.get_volume() self.CurrentItem['MediaSourceId'] = self.MediasourceID self.CurrentItem['EmbyServer'] = EmbyServer self.CurrentItem['RunTime'] = 0 self.CurrentItem['CurrentPosition'] = 0 self.CurrentItem['Paused'] = False self.CurrentItem['library'] = library self.CurrentItem['MediaSourceId'] = self.MediasourceID self.CurrentItem['Volume'], self.CurrentItem['Muted'] = self.get_volume() def onAVChange(self): self.LOG.info("[ onAVChange ]") def onQueueNextItem(self): self.LOG.info("[ onQueueNextItem ]") def onPlayBackStarted(self): self.LOG.info("[ onPlayBackStarted ]") if self.ReloadStream():#Media reload (3D Movie) return def onPlayBackPaused(self): self.LOG.info("[ onPlayBackPaused ]") if not self.CurrentlyPlaying: return self.CurrentlyPlaying['Paused'] = True self.report_playback() self.LOG.debug("-->[ paused ]") def onPlayBackResumed(self): self.LOG.info("[ onPlayBackResumed ]") if not self.CurrentlyPlaying: return self.CurrentlyPlaying['Paused'] = False self.report_playback(False) self.LOG.debug("--<[ paused ]") def onPlayBackStopped(self): self.LOG.info("[ onPlayBackStopped ]") if self.ReloadStream():#Media reload (3D Movie) return self.PlayerLastItemID = "-1" self.PlayerLastItem = "" self.Trailer = False self.SyncPause = True self.stop_playback(False) self.LOG.info("--<[ playback ]") def onPlayBackSeek(self, time, seekOffset): self.LOG.info("[ onPlayBackSeek ]") if not self.CurrentlyPlaying: return SeekPosition = int(time * 10000) if self.CurrentlyPlaying['RunTime']: if SeekPosition > self.CurrentlyPlaying['RunTime']: SeekPosition = self.CurrentlyPlaying['RunTime'] self.CurrentlyPlaying['CurrentPosition'] = SeekPosition self.report_playback(False) self.SkipUpdate = True #Pause progress updates for one cycle -> new seek position def onPlayBackEnded(self): self.LOG.info("[ onPlayBackEnded ]") if self.Trailer or self.ReloadStream(): return self.PlayerLastItemID = "-1" self.PlayerLastItem = "" self.SyncPause = True self.stop_playback(False) self.LOG.info("--<<[ playback ]") #Threaded to ThreadAVStarted def onAVStarted(self): self.LOG.info("[ onAVStarted ]") new_thread = PlayerWorker(self, "ThreadAVStarted") new_thread.start() def ThreadAVStarted(self): self.LOG.info("[ ThreadAVStarted ]") self.stop_playback(True) while not self.CurrentItem: #wait for OnPlay if xbmc.Monitor().waitForAbort(1): return if not self.CurrentItem['Tracking']: self.CurrentItem = {} return if not self.set_CurrentPosition(): #Stopped directly after started playing self.LOG.info("[ fast stop detected ]") return self.CurrentItem['PlaySessionId'] = self.PlaySessionId self.CurrentlyPlaying = self.CurrentItem self.CurrentItem = {} self.LOG.info("-->[ play/%s ] %s" % (self.CurrentlyPlaying['Id'], self.CurrentlyPlaying)) data = { 'ItemId': self.CurrentlyPlaying['Id'], 'MediaSourceId': self.CurrentlyPlaying['MediaSourceId'], 'PlaySessionId': self.CurrentlyPlaying['PlaySessionId'] } #Init session self.CurrentlyPlaying['EmbyServer'].API.session_playing(data) self.SkipUpdate = False self.report_playback(False) if not self.ProgressThread: self.ProgressThread = ProgressUpdates(self) self.ProgressThread.start() def SETVolume(self, Volume, Mute): if not self.CurrentlyPlaying: return self.CurrentlyPlaying['Volume'] = Volume self.CurrentlyPlaying['Muted'] = Mute self.report_playback(False) def set_CurrentPosition(self): try: CurrentPosition = int(self.getTime() * 10000000) if CurrentPosition < 0: CurrentPosition = 0 self.CurrentlyPlaying['CurrentPosition'] = CurrentPosition return True except: return False def set_Runtime(self): try: self.CurrentlyPlaying['RunTime'] = int(self.getTotalTime() * 10000000) return bool(self.CurrentlyPlaying['RunTime']) except: return False #Report playback progress to emby server. def report_playback(self, UpdatePosition=True): if not self.CurrentlyPlaying or self.Trailer or self.SkipUpdate: self.SkipUpdate = False return if not self.CurrentlyPlaying['RunTime']: if not self.set_Runtime(): self.LOG.info("[ skip progress update, no runtime info ]") return if UpdatePosition: if not self.set_CurrentPosition(): self.LOG.info("[ skip progress update, no position info ]") return data = { 'ItemId': self.CurrentlyPlaying['Id'], 'MediaSourceId': self.CurrentlyPlaying['MediaSourceId'], 'PositionTicks': self.CurrentlyPlaying['CurrentPosition'], 'RunTimeTicks': self.CurrentlyPlaying['RunTime'], 'CanSeek': True, 'QueueableMediaTypes': "Video,Audio", 'VolumeLevel': self.CurrentlyPlaying['Volume'], 'IsPaused': self.CurrentlyPlaying['Paused'], 'IsMuted': self.CurrentlyPlaying['Muted'], 'PlaySessionId': self.CurrentlyPlaying['PlaySessionId'] } self.CurrentlyPlaying['EmbyServer'].API.session_progress(data) def get_volume(self): result = helper.jsonrpc.JSONRPC('Application.GetProperties').execute({'properties': ["volume", "muted"]}) result = result.get('result', {}) volume = result.get('volume') muted = result.get('muted') return volume, muted def onPlayBackError(self): self.LOG.warning("Playback error occured") self.stop_playback(False) def ReloadStream(self): #Media has changed -> reload if self.PlayerReloadIndex != "-1": playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) self.play(item=playlist, startpos=int(self.PlayerReloadIndex)) self.PlayerReloadIndex = "-1" return True return False def stop_playback(self, Init): if self.CurrentlyPlaying: self.LOG.debug("[ played info ] %s" % self.CurrentlyPlaying) data = { 'ItemId': self.CurrentlyPlaying['Id'], 'MediaSourceId': self.CurrentlyPlaying['MediaSourceId'], 'PositionTicks': self.CurrentlyPlaying['CurrentPosition'], 'PlaySessionId': self.CurrentlyPlaying['PlaySessionId'] } self.CurrentlyPlaying['EmbyServer'].API.session_stop(data) if self.Transcoding: self.CurrentlyPlaying['EmbyServer'].API.close_transcode() if not Init: self.ItemSkipUpdate = self.ItemSkipUpdateAfterStop self.ItemSkipUpdateReset = True self.SyncPause = False #Offer delete if self.CurrentlyPlaying: if self.CurrentlyPlaying['EmbyServer'].Utils.Settings.offerDelete: Runtime = int(self.CurrentlyPlaying['RunTime']) if Runtime > 10: if int(self.CurrentlyPlaying['CurrentPosition']) > Runtime * 0.95: #95% Progress DeleteMsg = False if self.CurrentlyPlaying['Type'] == 'episode' and self.CurrentlyPlaying['EmbyServer'].Utils.Settings.deleteTV: DeleteMsg = True elif self.CurrentlyPlaying['Type'] == 'movie' and self.CurrentlyPlaying['EmbyServer'].Utils.Settings.deleteMovies: DeleteMsg = True if DeleteMsg: self.LOG.info("Offer delete option") if self.CurrentlyPlaying['EmbyServer'].Utils.dialog("yesno", heading=self.CurrentlyPlaying['EmbyServer'].Utils.Translate(30091), line1=self.CurrentlyPlaying['EmbyServer'].Utils.Translate(33015)): self.CurrentlyPlaying['EmbyServer'].API.delete_item(self.CurrentlyPlaying['Id']) self.CurrentlyPlaying['library'].removed([self.CurrentlyPlaying['Id']]) self.CurrentlyPlaying['library'].delay_verify([self.CurrentlyPlaying['Id']]) self.CurrentlyPlaying = {} class PlayerWorker(threading.Thread): def __init__(self, Player, method): self.method = method self.Player = Player threading.Thread.__init__(self) def run(self): if self.method == 'ThreadAVStarted': self.Player.ThreadAVStarted() return #Call from WebSocket to manipulate playing URL class WebserviceOnPlay(threading.Thread): def __init__(self, Player, EmbyServer, WebserviceEventIn, WebserviceEventOut): self.LOG = helper.loghandler.LOG('EMBY.hooks.player.WebserviceOnPlay') self.EmbyServer = EmbyServer self.WebserviceEventIn = WebserviceEventIn self.WebserviceEventOut = WebserviceEventOut self.Player = Player self.Intros = None self.IntrosIndex = 0 self.Exit = False self.Trailers = False self.EmbyIDLast = -1 self.EmbyID = -1 self.Type = "" self.KodiID = -1 self.KodiFileID = -1 self.Force = False self.Filename = "" self.MediaSources = [] self.TranscodeReasons = "" self.IncommingData = "" self.TargetVideoBitrate = 0 self.TargetAudioBitrate = 0 self.emby_dbT = None self.BitrateFromURL = None self.MediasourceID = None self.EmbyServer.Utils.load_defaultvideosettings() threading.Thread.__init__(self) def Stop(self): self.Exit = True self.WebserviceEventOut.put("quit") def run(self): while not self.Exit: self.EmbyID = None self.MediasourceID = None self.Type = None self.BitrateFromURL = None self.Filename = None self.IncommingData = self.WebserviceEventOut.get() self.LOG.debug("[ query IncommingData ] %s" % self.IncommingData) if self.IncommingData == "quit": break self.GetParametersFromURLQuery() if 'audio' in self.IncommingData: self.WebserviceEventIn.put(self.EmbyServer.auth.get_serveraddress() + "/emby/audio/" + self.EmbyID + "/stream?static=true&PlaySessionId=" + self.GETPlaySessionId() + "&DeviceId=" + self.EmbyServer.Data['app.device_id'] + "&api_key=" + self.EmbyServer.Data['auth.token'] + "&" + self.Filename) continue if 'livetv' in self.IncommingData: self.WebserviceEventIn.put(self.EmbyServer.auth.get_serveraddress() + "/emby/videos/" + self.EmbyID + "/stream.ts?PlaySessionId=" + self.GETPlaySessionId() + "&DeviceId=" + self.EmbyServer.Data['app.device_id'] + "&api_key=" + self.EmbyServer.Data['auth.token'] + "&" + self.Filename) continue if 'main.m3u8' in self.IncommingData: #Dynamic Transcode query URL = self.IncommingData.replace("/movie/", "/") URL = URL.replace("/musicvideo/", "/") URL = URL.replace("/tvshow/", "/") URL = URL.replace("/video/", "/") URL = URL.replace("/trailer/", "/") self.WebserviceEventIn.put(self.EmbyServer.auth.get_serveraddress() + "/emby/videos/" + self.EmbyIDLast + URL) continue if self.Player.Transcoding: self.EmbyServer.API.close_transcode() self.Player.Transcoding = False if self.Type == "movies": self.Type = "movie" elif self.Type == "tvshows": self.Type = "episode" elif self.Type == "musicvideos": self.Type = "musicvideo" self.Player.SyncPause = True #Reload Playlistitem after playlist injection if self.Player.PlayerReloadIndex != "-1": URL = "RELOAD" self.WebserviceEventIn.put(URL) continue #Trailers if self.EmbyServer.Utils.Settings.enableCinema and self.Player.PlayerLastItemID != self.EmbyID: PlayTrailer = True if self.EmbyServer.Utils.Settings.askCinema: if not self.Player.Trailer: self.Trailers = False if not self.Trailers and not self.Player.Trailer: self.Trailers = True PlayTrailer = self.EmbyServer.Utils.dialog("yesno", heading="{emby}", line1=self.EmbyServer.Utils.Translate(33016)) if PlayTrailer: if self.Player.PlayerLastItem != self.IncommingData or not self.Player.Trailer: xbmc.executeJSONRPC('{ "jsonrpc": "2.0", "method": "Player.SetRepeat", "params": {"playerid": 1, "repeat": "one" }, "id": 1 }') self.Player.PlayerLastItem = self.IncommingData self.IntrosIndex = 0 self.Trailers = False self.Intros = self.EmbyServer.API.get_intros(self.EmbyID) #self.IntrosLocal = self.EmbyServer.API.get_local_trailers(self.EmbyID) self.Player.Trailer = True try: #Play next trailer self.WebserviceEventIn.put(self.Intros['Items'][self.IntrosIndex]['Path']) self.IntrosIndex += 1 continue except: #No more trailers xbmc.executeJSONRPC('{ "jsonrpc": "2.0", "method": "Player.SetRepeat", "params": {"playerid": 1, "repeat": "off" }, "id": 1 }') self.Force = True self.Player.PlayerLastItem = "" self.Intros = None self.IntrosIndex = 0 self.Trailers = False self.Player.Trailer = False else: xbmc.executeJSONRPC('{ "jsonrpc": "2.0", "method": "Player.SetRepeat", "params": {"playerid": 1, "repeat": "off" }, "id": 1 }') #Select mediasources, Audiostreams, Subtitles if self.Player.PlayerLastItemID != self.EmbyID or self.Force: self.Force = False self.Player.PlayerLastItemID = str(self.EmbyID) with database.database.Database(self.EmbyServer.Utils, 'emby', False) as embydb: self.emby_dbT = database.emby_db.EmbyDatabase(embydb.cursor) EmbyDBItem = self.emby_dbT.get_kodiid(self.EmbyID) if EmbyDBItem: #Item synced to Kodi DB if EmbyDBItem[1]: PresentationKey = EmbyDBItem[1].split("-") self.Player.ItemSkipUpdate.append(PresentationKey[0]) self.Player.ItemSkipUpdateAfterStop.append(PresentationKey[0]) self.KodiID = str(EmbyDBItem[0]) self.KodiFileID = str(EmbyDBItem[2]) self.MediaSources = self.emby_dbT.get_mediasource(self.EmbyID) if len(self.MediaSources) == 1: self.Player.PlayerLastItemID = "-1" self.WebserviceEventIn.put(self.LoadData(0)) continue #Multiversion Selection = [] for Data in self.MediaSources: Selection.append(Data[8] + " - " + self.SizeToText(float(Data[7]))) MediaIndex = self.EmbyServer.Utils.dialog("select", heading="Select Media Source:", list=Selection) if MediaIndex <= 0: MediaIndex = 0 self.Player.PlayerLastItemID = "-1" self.MediasourceID = self.MediaSources[MediaIndex][3] self.WebserviceEventIn.put(self.LoadData(MediaIndex)) else: self.Player.PlayerReloadIndex = "-1" self.Player.PlayerLastItem = "" self.Intros = None self.IntrosIndex = 0 self.Trailers = False self.Player.Trailer = False self.SubTitlesAdd() self.Player.Transcoding = self.IsTranscoding(self.BitrateFromURL, None) if self.Player.Transcoding: URL = self.GETTranscodeURL(self.Filename, False, False) else: URL = self.EmbyServer.auth.get_serveraddress() + "/emby/videos/" + self.EmbyID + "/stream?static=true&MediaSourceId=" + self.MediasourceID + "&PlaySessionId=" + self.GETPlaySessionId() + "&DeviceId=" + self.EmbyServer.Data['app.device_id'] + "&api_key=" + self.EmbyServer.Data['auth.token'] + "&" + self.Filename self.WebserviceEventIn.put(URL) #Load SRT subtitles def SubTitlesAdd(self): Subtitles = self.emby_dbT.get_Subtitles(self.EmbyID, 0) if len(Subtitles) >= 1: CounterSubTitle = 0 for Data in Subtitles: CounterSubTitle += 1 if Data[3] == "srt": SubTitleURL = self.EmbyServer.auth.get_serveraddress() + "/emby/videos/" + self.EmbyID + "/" + self.MediasourceID + "/Subtitles/" + str(Data[18]) + "/stream.srt" request = {'type': "GET", 'url': SubTitleURL, 'params': {}} #Get Subtitle Settings with database.database.Database(self.EmbyServer.Utils, 'video', False) as videodb: videodb.cursor.execute(core.queries_videos.get_settings, (self.KodiFileID,)) FileSettings = videodb.cursor.fetchone() if FileSettings: EnableSubtitle = bool(FileSettings[9]) else: if self.EmbyServer.Utils.DefaultVideoSettings: EnableSubtitle = self.EmbyServer.Utils.DefaultVideoSettings['ShowSubtitles'] else: EnableSubtitle = False if Data[4]: SubtileLanguage = Data[4] else: SubtileLanguage = "unknown" Filename = self.EmbyServer.Utils.PathToFilenameReplaceSpecialCharecters(str(CounterSubTitle) + "." + SubtileLanguage + ".srt") Path = self.EmbyServer.Utils.download_file_from_Embyserver(request, Filename, self.EmbyServer) if Path: self.Player.setSubtitles(Path) self.Player.showSubtitles(EnableSubtitle) def LoadData(self, MediaIndex): VideoStreams = self.emby_dbT.get_videostreams(self.EmbyID, MediaIndex) AudioStreams = self.emby_dbT.get_AudioStreams(self.EmbyID, MediaIndex) if not VideoStreams: self.LOG.warning("[ VideoStreams not found ] %s" % self.EmbyID) return self.EmbyServer.auth.get_serveraddress() + "/emby/videos/" + self.EmbyID + "/stream?static=true&MediaSourceId=" + self.MediasourceID + "&PlaySessionId=" + self.GETPlaySessionId() + "&DeviceId=" + self.EmbyServer.Data['app.device_id'] + "&api_key=" + self.EmbyServer.Data['auth.token'] + "&" + self.Filename self.Player.Transcoding = self.IsTranscoding(VideoStreams[0][9], VideoStreams[0][3]) #add codec from videostreams, Bitrate (from file) if self.Player.Transcoding: SubtitleIndex = -1 AudioIndex = -1 Subtitles = [] Subtitles = self.emby_dbT.get_Subtitles(self.EmbyID, MediaIndex) if len(AudioStreams) >= 2: Selection = [] for Data in AudioStreams: Selection.append(Data[7]) AudioIndex = self.EmbyServer.Utils.dialog("select", heading="Select Audio Stream:", list=Selection) if len(Subtitles) >= 1: Selection = [] for Data in Subtitles: Selection.append(Data[7]) SubtitleIndex = self.EmbyServer.Utils.dialog("select", heading="Select Subtitle:", list=Selection) if AudioIndex <= 0 and SubtitleIndex < 0 and MediaIndex <= 0: #No change -> resume return self.GETTranscodeURL(self.Filename, False, False) if AudioIndex <= 0: AudioIndex = 0 if SubtitleIndex < 0: Subtitle = None else: Subtitle = Subtitles[SubtitleIndex] return self.UpdateItem(self.MediaSources[MediaIndex], AudioStreams[AudioIndex], Subtitle) if MediaIndex == 0: self.SubTitlesAdd() return self.EmbyServer.auth.get_serveraddress() + "/emby/videos/" + self.EmbyID + "/stream?static=true&MediaSourceId=" + self.MediasourceID + "&PlaySessionId=" + self.GETPlaySessionId() + "&DeviceId=" + self.EmbyServer.Data['app.device_id'] + "&api_key=" + self.EmbyServer.Data['auth.token'] + "&" + self.Filename return self.UpdateItem(self.MediaSources[MediaIndex], AudioStreams[0], False) def GETTranscodeURL(self, Filename, Audio, Subtitle): TranscodingVideo = "" TranscodingAudio = "" if Subtitle: Subtitle = "&SubtitleStreamIndex=" + Subtitle else: Subtitle = "" if Audio: Audio = "&AudioStreamIndex=" + Audio else: Audio = "" if self.TargetVideoBitrate: TranscodingVideo = "&VideoBitrate=" + str(self.TargetVideoBitrate) if self.TargetAudioBitrate: TranscodingAudio = "&AudioBitrate=" + str(self.TargetAudioBitrate) if Filename: Filename = "&stream-" + Filename return self.EmbyServer.auth.get_serveraddress() + "/emby/videos/" + self.EmbyID + "/master.m3u8?api_key=" + self.EmbyServer.Data['auth.token'] + "&MediaSourceId=" + self.MediasourceID + "&PlaySessionId=" + self.GETPlaySessionId() + "&DeviceId=" + self.EmbyServer.Data['app.device_id'] + "&VideoCodec=" + self.EmbyServer.Utils.Settings.VideoCodecID + "&AudioCodec=" + self.EmbyServer.Utils.Settings.AudioCodecID + TranscodingVideo + TranscodingAudio + Audio + Subtitle + "&TranscodeReasons=" + self.TranscodeReasons + Filename def SizeToText(self, size): suffixes = ['B', 'KB', 'MB', 'GB', 'TB'] suffixIndex = 0 while size > 1024 and suffixIndex < 4: suffixIndex += 1 size = size / 1024.0 return "%.*f%s" % (2, size, suffixes[suffixIndex]) def GETPlaySessionId(self): self.Player.PlaySessionId = str(uuid.uuid4()).replace("-", "") self.Player.MediasourceID = self.MediasourceID return self.Player.PlaySessionId def IsTranscoding(self, Bitrate, Codec): if self.EmbyServer.Utils.Settings.transcodeH265: if Codec in ("h265", "hevc"): self.IsTranscodingByCodec(Bitrate) return True elif self.EmbyServer.Utils.Settings.transcodeDivx: if Codec == "msmpeg4v3": self.IsTranscodingByCodec(Bitrate) return True elif self.EmbyServer.Utils.Settings.transcodeXvid: if Codec == "mpeg4": self.IsTranscodingByCodec(Bitrate) return True elif self.EmbyServer.Utils.Settings.transcodeMpeg2: if Codec == "mpeg2video": self.IsTranscodingByCodec(Bitrate) return True self.TargetVideoBitrate = self.EmbyServer.Utils.Settings.VideoBitrate self.TargetAudioBitrate = self.EmbyServer.Utils.Settings.AudioBitrate self.TranscodeReasons = "ContainerBitrateExceedsLimit" return Bitrate >= self.TargetVideoBitrate def IsTranscodingByCodec(self, Bitrate): if Bitrate >= self.EmbyServer.Utils.Settings.VideoBitrate: self.TranscodeReasons = "ContainerBitrateExceedsLimit" self.TargetVideoBitrate = self.EmbyServer.Utils.Settings.VideoBitrate self.TargetAudioBitrate = self.EmbyServer.Utils.Settings.AudioBitrate else: self.TranscodeReasons = "VideoCodecNotSupported" self.TargetVideoBitrate = 0 self.TargetAudioBitrate = 0 def GetParametersFromURLQuery(self): Type = self.IncommingData[1:] self.Type = Type[:Type.find("/")] Temp = self.IncommingData[self.IncommingData.rfind("/") + 1:] Data = Temp.split("-") if len(Data[0]) < 10: self.Filename = self.IncommingData[self.IncommingData.find("stream-") + 7:] self.EmbyIDLast = Data[0] try: self.BitrateFromURL = int(Data[2]) except: self.BitrateFromURL = 0 self.Player.SyncPause = True self.Player.ItemSkipUpdate.append(Data[0]) self.Player.ItemSkipUpdateAfterStop.append(Data[0]) self.EmbyID = Data[0] self.MediasourceID = Data[1] if self.MediasourceID == "DYNAMIC": Result = self.EmbyServer.API.get_item(self.EmbyID) self.MediasourceID = Result['MediaSources'][0]['Id'] def UpdateItem(self, MediaSource, AudioStream, Subtitle): if self.Type == "movie": result = xbmc.executeJSONRPC('{"jsonrpc":"2.0", "id":1, "method":"VideoLibrary.GetMovieDetails", "params":{"movieid":' + self.KodiID + ', "properties":["title", "playcount", "plot", "genre", "year", "rating", "resume", "streamdetails", "director", "trailer", "tagline", "plotoutline", "originaltitle", "writer", "studio", "mpaa", "country", "imdbnumber", "set", "showlink", "top250", "votes", "sorttitle", "dateadded", "tag", "userrating", "cast", "premiered", "setid", "art", "lastplayed", "uniqueid"]}}') Data = json.loads(result) Details = Data['result']['moviedetails'] elif self.Type == "episode": result = xbmc.executeJSONRPC('{"jsonrpc":"2.0", "id":1, "method":"VideoLibrary.GetEpisodeDetails", "params":{"episodeid":' + self.KodiID + ', "properties":["title", "playcount", "season", "episode", "showtitle", "plot", "rating", "resume", "streamdetails", "firstaired", "writer", "dateadded", "lastplayed", "originaltitle", "seasonid", "specialsortepisode", "specialsortseason", "userrating", "votes", "cast", "art", "uniqueid"]}}') Data = json.loads(result) Details = Data['result']['episodedetails'] elif self.Type == "musicvideo": result = xbmc.executeJSONRPC('{"jsonrpc":"2.0", "id":1, "method":"VideoLibrary.GetMusicVideoDetails", "params":{"musicvideoid":' + self.KodiID + ', "properties":["title", "playcount", "plot", "genre", "year", "rating", "resume", "streamdetails", "director", "studio", "dateadded", "tag", "userrating", "premiered", "album", "artist", "track", "art", "lastplayed"]}}') Data = json.loads(result) Details = Data['result']['musicvideodetails'] Filename = self.EmbyServer.Utils.PathToFilenameReplaceSpecialCharecters(MediaSource[4]) if self.Player.Transcoding: if Subtitle: SubtitleStream = str(int(Subtitle[2]) + 2) else: SubtitleStream = "" URL = self.GETTranscodeURL(Filename, str(int(AudioStream[2]) + 1), SubtitleStream) else: #stream URL = self.EmbyServer.auth.get_serveraddress() + "/emby/videos/" + self.EmbyID +"/stream?static=true&api_key=" + self.EmbyServer.Data['auth.token'] + "&MediaSourceId=" + self.MediasourceID + "&PlaySessionId=" + self.GETPlaySessionId() + "&DeviceId=" + self.EmbyServer.Data['app.device_id'] + "&" + Filename li = self.EmbyServer.Utils.CreateListitem(self.Type, Details) if "3d" in MediaSource[8].lower(): li.setPath(URL) playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) Index = playlist.getposition() playlist.add(URL, li, Index) xbmc.executeJSONRPC('{"jsonrpc":"2.0", "method":"Playlist.Remove", "params":{"playlistid":1, "position":' + str(Index + 1) + '}}') self.Player.PlayerReloadIndex = str(Index) self.Player.PlayerLastItemID = str(self.EmbyID) URL = "RELOAD" else: li.setPath("http://127.0.0.1:57578" + self.IncommingData) self.Player.updateInfoTag(li) self.SubTitlesAdd() self.Player.PlayerReloadIndex = "-1" self.Player.PlayerLastItemID = "-1" return URL