def _get_item_id(cls, kodi_id, item_type): item_id = xbmc.getInfoLabel('ListItem.Property(plexid)') if not item_id and kodi_id and item_type: with embydb.GetEmbyDB() as emby_db: item = emby_db.getItem_byKodiId(kodi_id, item_type) try: item_id = item[0] except TypeError: log.error('Could not get the Plex id for context menu') return item_id
def skipTo(self, plexId, typus): # playlistId = self.getPlaylistId(tryDecode(xbmc_type(typus))) # playerId = self. with embydb.GetEmbyDB() as emby_db: embydb_item = emby_db.getItem_byId(plexId) try: dbid = embydb_item[0] mediatype = embydb_item[4] except TypeError: log.info('Couldnt find item %s in Kodi db' % plexId) return log.debug('plexid: %s, kodi id: %s, type: %s' % (plexId, dbid, mediatype))
def playAll(self, itemids, startat): log = self.logMsg window = utils.window embyconn = utils.kodiSQL('emby') embycursor = embyconn.cursor() emby_db = embydb.Embydb_Functions(embycursor) player = xbmc.Player() playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) playlist.clear() log("---*** PLAY ALL ***---", 1) log("Items: %s and start at: %s" % (itemids, startat), 1) started = False window('emby_customplaylist', value="true") if startat != 0: # Seek to the starting position window('emby_customplaylist.seektime', str(startat)) with embydb.GetEmbyDB() as emby_db: for itemid in itemids: embydb_item = emby_db.getItem_byId(itemid) try: dbid = embydb_item[0] mediatype = embydb_item[4] except TypeError: # Item is not found in our database, add item manually log( "Item was not found in the database, manually adding item.", 1) item = PlexFunctions.GetPlexMetadata(itemid) if item is None or item == 401: log('Could not download itemid %s' % itemid, -1) else: self.addtoPlaylist_xbmc(playlist, item) else: # Add to playlist self.addtoPlaylist(dbid, mediatype) log("Adding %s to playlist." % itemid, 1) if not started: started = True player.play(playlist) self.verifyPlaylist()
def _initiatePlaylist(self): log.info('Initiating playlist') playlist = None with embydb.GetEmbyDB() as emby_db: for item in self.items: itemid = item['plexId'] embydb_item = emby_db.getItem_byId(itemid) try: mediatype = embydb_item[4] except TypeError: log.info('Couldnt find item %s in Kodi db' % itemid) item = PlexFunctions.GetPlexMetadata(itemid) if item in (None, 401): log.info('Couldnt find item %s on PMS, trying next' % itemid) continue if PlexAPI.API(item[0]).getType() == 'track': playlist = xbmc.PlayList(xbmc.PLAYLIST_MUSIC) log.info('Music playlist initiated') self.typus = 'music' else: playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) log.info('Video playlist initiated') self.typus = 'video' else: if mediatype == 'song': playlist = xbmc.PlayList(xbmc.PLAYLIST_MUSIC) log.info('Music playlist initiated') self.typus = 'music' else: playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) log.info('Video playlist initiated') self.typus = 'video' break self.playlist = playlist if self.playlist is not None: self.playlistId = self.playlist.getPlayListId()
def _processItems(self, startitem, startPlayer=False): startpos = None with embydb.GetEmbyDB() as emby_db: for pos, item in enumerate(self.items): kodiId = None plexId = item['plexId'] embydb_item = emby_db.getItem_byId(plexId) try: kodiId = embydb_item[0] mediatype = embydb_item[4] except TypeError: log.info('Couldnt find item %s in Kodi db' % plexId) xml = PlexFunctions.GetPlexMetadata(plexId) if xml in (None, 401): log.error('Could not download plexId %s' % plexId) else: log.debug('Downloaded xml metadata, adding now') self._addtoPlaylist_xbmc(xml[0]) else: # Add to playlist log.debug("Adding %s PlexId %s, KodiId %s to playlist." % (mediatype, plexId, kodiId)) self._addtoPlaylist(kodiId, mediatype) # Add the kodiId if kodiId is not None: item['kodiId'] = str(kodiId) if (startpos is None and startitem[1] == item[startitem[0]]): startpos = pos if startPlayer is True and len(self.playlist) > 0: if startpos is not None: self.player.play(self.playlist, startpos=startpos) else: log.info('Never received a starting item for playlist, ' 'starting with the first entry') self.player.play(self.playlist)
plexid = "" if not itemtype and xbmc.getCondVisibility("Container.Content(albums)"): itemtype = "album" if not itemtype and xbmc.getCondVisibility("Container.Content(artists)"): itemtype = "artist" if not itemtype and xbmc.getCondVisibility("Container.Content(songs)"): itemtype = "song" if not itemtype and xbmc.getCondVisibility("Container.Content(pictures)"): itemtype = "picture" if (not itemid or itemid == "-1") and xbmc.getInfoLabel("ListItem.Property(plexid)"): plexid = xbmc.getInfoLabel("ListItem.Property(plexid)") else: with embydb.GetEmbyDB() as emby_db: item = emby_db.getItem_byKodiId(itemid, itemtype) if item: plexid = item[0] logMsg("Contextmenu opened for plexid: %s - itemtype: %s" % (plexid, itemtype)) if plexid: item = PF.GetPlexMetadata(plexid) if item is None or item == 401: logMsg('Could not get item metadata for item %s' % plexid, -1) return API = PlexAPI.API(item[0]) userdata = API.getUserData() likes = userdata['Likes']
def onPlayBackStarted(self): """ Will be called when xbmc starts playing a file. Window values need to have been set in Kodimonitor.py """ self.stopAll() # Get current file (in utf-8!) try: currentFile = self.getPlayingFile() xbmc.sleep(300) except: currentFile = "" count = 0 while not currentFile: xbmc.sleep(100) try: currentFile = self.getPlayingFile() except: pass if count == 20: break else: count += 1 if not currentFile: log.warn('Error getting currently playing file; abort reporting') return # Save currentFile for cleanup later and for references self.currentFile = currentFile window('plex_lastPlayedFiled', value=currentFile) # We may need to wait for info to be set in kodi monitor itemId = window("emby_%s.itemid" % currentFile) count = 0 while not itemId: xbmc.sleep(200) itemId = window("emby_%s.itemid" % currentFile) if count == 5: log.warn("Could not find itemId, cancelling playback report!") return count += 1 log.info("ONPLAYBACK_STARTED: %s itemid: %s" % (currentFile, itemId)) embyitem = "emby_%s" % currentFile runtime = window("%s.runtime" % embyitem) refresh_id = window("%s.refreshid" % embyitem) playMethod = window("%s.playmethod" % embyitem) itemType = window("%s.type" % embyitem) try: playcount = int(window("%s.playcount" % embyitem)) except ValueError: playcount = 0 window('emby_skipWatched%s' % itemId, value="true") log.debug("Playing itemtype is: %s" % itemType) customseek = window('plex_customplaylist.seektime') if customseek: # Start at, when using custom playlist (play to Kodi from # webclient) log.info("Seeking to: %s" % customseek) try: self.seekTime(int(customseek)) except: log.error('Could not seek!') window('plex_customplaylist.seektime', clear=True) try: seekTime = self.getTime() except RuntimeError: log.error('Could not get current seektime from xbmc player') seekTime = 0 # Get playback volume volume_query = { "jsonrpc": "2.0", "id": 1, "method": "Application.GetProperties", "params": { "properties": ["volume", "muted"] } } result = xbmc.executeJSONRPC(json.dumps(volume_query)) result = json.loads(result) result = result.get('result') volume = result.get('volume') muted = result.get('muted') # Postdata structure to send to Emby server url = "{server}/:/timeline?" postdata = { 'QueueableMediaTypes': "Video", 'CanSeek': True, 'ItemId': itemId, 'MediaSourceId': itemId, 'PlayMethod': playMethod, 'VolumeLevel': volume, 'PositionTicks': int(seekTime * 10000000), 'IsMuted': muted } # Get the current audio track and subtitles if playMethod == "Transcode": # property set in PlayUtils.py postdata['AudioStreamIndex'] = window("%sAudioStreamIndex" % currentFile) postdata['SubtitleStreamIndex'] = window("%sSubtitleStreamIndex" % currentFile) else: # Get the current kodi audio and subtitles and convert to Emby equivalent tracks_query = { "jsonrpc": "2.0", "id": 1, "method": "Player.GetProperties", "params": { "playerid": 1, "properties": [ "currentsubtitle", "currentaudiostream", "subtitleenabled" ] } } result = xbmc.executeJSONRPC(json.dumps(tracks_query)) result = json.loads(result) result = result.get('result') try: # Audio tracks indexAudio = result['currentaudiostream']['index'] except (KeyError, TypeError): indexAudio = 0 try: # Subtitles tracks indexSubs = result['currentsubtitle']['index'] except (KeyError, TypeError): indexSubs = 0 try: # If subtitles are enabled subsEnabled = result['subtitleenabled'] except (KeyError, TypeError): subsEnabled = "" # Postdata for the audio postdata['AudioStreamIndex'] = indexAudio + 1 # Postdata for the subtitles if subsEnabled and len( xbmc.Player().getAvailableSubtitleStreams()) > 0: # Number of audiotracks to help get Emby Index audioTracks = len(xbmc.Player().getAvailableAudioStreams()) mapping = window("%s.indexMapping" % embyitem) if mapping: # Set in playbackutils.py log.debug("Mapping for external subtitles index: %s" % mapping) externalIndex = json.loads(mapping) if externalIndex.get(str(indexSubs)): # If the current subtitle is in the mapping postdata['SubtitleStreamIndex'] = externalIndex[str( indexSubs)] else: # Internal subtitle currently selected subindex = indexSubs - len( externalIndex) + audioTracks + 1 postdata['SubtitleStreamIndex'] = subindex else: # Direct paths enabled scenario or no external subtitles set postdata[ 'SubtitleStreamIndex'] = indexSubs + audioTracks + 1 else: postdata['SubtitleStreamIndex'] = "" # Post playback to server # log("Sending POST play started: %s." % postdata, 2) # self.doUtils(url, postBody=postdata, type="POST") # Ensure we do have a runtime try: runtime = int(runtime) except ValueError: try: runtime = self.getTotalTime() log.error("Runtime is missing, Kodi runtime: %s" % runtime) except: log.error('Could not get kodi runtime, setting to zero') runtime = 0 with embydb.GetEmbyDB() as emby_db: emby_dbitem = emby_db.getItem_byId(itemId) try: fileid = emby_dbitem[1] except TypeError: log.info("Could not find fileid in plex db.") fileid = None # Save data map for updates and position calls data = { 'runtime': runtime, 'item_id': itemId, 'refresh_id': refresh_id, 'currentfile': currentFile, 'AudioStreamIndex': postdata['AudioStreamIndex'], 'SubtitleStreamIndex': postdata['SubtitleStreamIndex'], 'playmethod': playMethod, 'Type': itemType, 'currentPosition': int(seekTime), 'fileid': fileid, 'itemType': itemType, 'playcount': playcount } self.played_info[currentFile] = data log.info("ADDING_FILE: %s" % data) # log some playback stats '''if(itemType != None):
def onNotification(self, sender, method, data): if method not in ("Playlist.OnAdd"): self.logMsg("Method: %s Data: %s" % (method, data), 1) if data: data = json.loads(data, 'utf-8') if method == "Player.OnPlay": self.PlayBackStart(data) elif method == "Player.OnStop": # Should refresh our video nodes, e.g. on deck # xbmc.executebuiltin('ReloadSkin()') pass elif method == "VideoLibrary.OnUpdate": # Manually marking as watched/unwatched playcount = data.get('playcount') item = data.get('item') try: kodiid = item['id'] item_type = item['type'] except (KeyError, TypeError): self.logMsg("Item is invalid for playstate update.", 1) else: # Send notification to the server. with embydb.GetEmbyDB() as emby_db: emby_dbitem = emby_db.getItem_byKodiId(kodiid, item_type) try: itemid = emby_dbitem[0] except TypeError: self.logMsg("Could not find itemid in emby database.", 1) else: # Stop from manually marking as watched unwatched, with actual playback. if utils.window('emby_skipWatched%s' % itemid) == "true": # property is set in player.py utils.window('emby_skipWatched%s' % itemid, clear=True) else: # notify the server if playcount != 0: scrobble(itemid, 'watched') else: scrobble(itemid, 'unwatched') elif method == "VideoLibrary.OnRemove": # Removed function, because with plugin paths + clean library, it will wipe # entire library if user has permissions. Instead, use the emby context menu available # in Isengard and higher version pass '''try: kodiid = data['id'] type = data['type'] except (KeyError, TypeError): self.logMsg("Item is invalid for emby deletion.", 1) else: # Send the delete action to the server. embyconn = utils.kodiSQL('emby') embycursor = embyconn.cursor() emby_db = embydb.Embydb_Functions(embycursor) emby_dbitem = emby_db.getItem_byKodiId(kodiid, type) try: itemid = emby_dbitem[0] except TypeError: self.logMsg("Could not find itemid in emby database.", 1) else: if utils.settings('skipContextMenu') != "true": resp = xbmcgui.Dialog().yesno( heading="Confirm delete", line1="Delete file on Emby Server?") if not resp: self.logMsg("User skipped deletion.", 1) embycursor.close() return url = "{server}/emby/Items/%s?format=json" % itemid self.logMsg("Deleting request: %s" % itemid) doUtils.downloadUrl(url, action_type="DELETE") finally: embycursor.close()''' elif method == "System.OnWake": # Allow network to wake up xbmc.sleep(10000) utils.window('plex_onWake', value="true") elif method == "GUI.OnScreensaverDeactivated": if utils.settings('dbSyncScreensaver') == "true": xbmc.sleep(5000) utils.window('plex_runLibScan', value="full") elif method == "Playlist.OnClear": pass
def PlayBackStart(self, data): """ Called whenever a playback is started """ log = self.logMsg window = utils.window # Get currently playing file - can take a while. Will be utf-8! try: currentFile = self.xbmcplayer.getPlayingFile() except: currentFile = None count = 0 while currentFile is None: xbmc.sleep(100) try: currentFile = self.xbmcplayer.getPlayingFile() except: pass if count == 50: log("No current File - Cancelling OnPlayBackStart...", -1) return else: count += 1 log("Currently playing file is: %s" % utils.tryDecode(currentFile), 1) # Try to get a Kodi ID item = data.get('item') try: type = item['type'] except: log("Item is invalid for PMS playstate update.", 0) return try: kodiid = item['id'] except (KeyError, TypeError): itemType = window("emby_%s.type" % currentFile) log("No kodi id passed. Playing itemtype is: %s" % itemType, 1) if itemType in ('movie', 'episode'): # Window was setup by PKC and is NOT a trailer ('clip') with kodidb.GetKodiDB('video') as kodi_db: kodiid = kodi_db.getIdFromTitle(data.get('item')) if kodiid is None: log( "Skip playstate update. No unique Kodi title found" " for %s" % data.get('item'), 0) return else: log("Item is invalid for PMS playstate update.", 0) return # Get Plex' item id with embydb.GetEmbyDB() as emby_db: emby_dbitem = emby_db.getItem_byKodiId(kodiid, type) try: plexid = emby_dbitem[0] except TypeError: log("No Plex id returned for kodiid %s" % kodiid, 0) return log("Found Plex id %s for Kodi id %s" % (plexid, kodiid), 1) # Set some stuff if Kodi initiated playback if ((utils.settings('useDirectPaths') == "1" and not type == "song") or (type == "song" and utils.settings('enableMusic') == "true")): if self.StartDirectPath(plexid, type, currentFile) is False: log('Could not initiate monitoring; aborting', -1) return # Save currentFile for cleanup later and to be able to access refs window('plex_lastPlayedFiled', value=utils.tryDecode(currentFile)) window('Plex_currently_playing_itemid', value=plexid) window("emby_%s.itemid" % currentFile, value=plexid) log('Finish playback startup', 1)
def PlayBackStart(self, data): """ Called whenever a playback is started """ # Get currently playing file - can take a while. Will be utf-8! try: currentFile = self.xbmcplayer.getPlayingFile() except: currentFile = None count = 0 while currentFile is None: xbmc.sleep(100) try: currentFile = self.xbmcplayer.getPlayingFile() except: pass if count == 50: log.info("No current File, cancel OnPlayBackStart...") return else: count += 1 # Just to be on the safe side currentFile = tryDecode(currentFile) log.debug("Currently playing file is: %s" % currentFile) # Get the type of media we're playing try: typus = data['item']['type'] except (TypeError, KeyError): log.info("Item is invalid for PMS playstate update.") return log.debug("Playing itemtype is (or appears to be): %s" % typus) # Try to get a Kodi ID # If PKC was used - native paths, not direct paths plexid = window('emby_%s.itemid' % tryEncode(currentFile)) # Get rid of the '' if the window property was not set plexid = None if not plexid else plexid kodiid = None if plexid is None: log.debug('Did not get Plex id from window properties') try: kodiid = data['item']['id'] except (TypeError, KeyError): log.debug('Did not get a Kodi id from Kodi, darn') # For direct paths, if we're not streaming something # When using Widgets, Kodi doesn't tell us shit so we need this hack if (kodiid is None and plexid is None and typus != 'song' and not currentFile.startswith('http')): try: filename = currentFile.rsplit('/', 1)[1] path = currentFile.rsplit('/', 1)[0] + '/' except IndexError: filename = currentFile.rsplit('\\', 1)[1] path = currentFile.rsplit('\\', 1)[0] + '\\' log.debug('Trying to figure out playing item from filename: %s ' 'and path: %s' % (filename, path)) with kodidb.GetKodiDB('video') as kodi_db: try: kodiid, typus = kodi_db.getIdFromFilename(filename, path) except TypeError: log.info('Abort playback report, could not id kodi item') return if plexid is None: # Get Plex' item id with embydb.GetEmbyDB() as emby_db: emby_dbitem = emby_db.getItem_byKodiId(kodiid, typus) try: plexid = emby_dbitem[0] except TypeError: log.info("No Plex id returned for kodiid %s. Aborting playback" " report" % kodiid) return log.debug("Found Plex id %s for Kodi id %s for type %s" % (plexid, kodiid, typus)) # Set some stuff if Kodi initiated playback if ((settings('useDirectPaths') == "1" and not typus == "song") or (typus == "song" and settings('enableMusic') == "true")): if self.StartDirectPath(plexid, typus, tryEncode(currentFile)) is False: log.error('Could not initiate monitoring; aborting') return # Save currentFile for cleanup later and to be able to access refs window('plex_lastPlayedFiled', value=currentFile) window('plex_currently_playing_itemid', value=plexid) window("emby_%s.itemid" % tryEncode(currentFile), value=plexid) log.info('Finish playback startup')