def DownloadVideoItem(self, item): """Downloads an existing MediaItem with more data. Arguments: item : MediaItem - the MediaItem that should be downloaded. Returns: The original item with more data added to it's properties. Used to download an <item>. If the item is not complete, the self.UpdateVideoItem method is called to update the item. The method downloads only the MediaStream with the bitrate that was set in the addon settings. After downloading the self.downloaded property is set. """ if not item.IsPlayable(): Logger.Error("Cannot download a folder item.") return item if item.IsPlayable(): if not item.complete: Logger.Info("Fetching MediaUrl for PlayableItem[%s]", item.type) item = self.ProcessVideoItem(item) if not item.complete or not item.HasMediaItemParts(): Logger.Error("Cannot download incomplete item or item without MediaItemParts") return item i = 1 bitrate = AddonSettings.GetMaxStreamBitrate() for mediaItemPart in item.MediaItemParts: Logger.Info("Trying to download %s", mediaItemPart) stream = mediaItemPart.GetMediaStreamForBitrate(bitrate) downloadUrl = stream.Url extension = UriHandler.GetExtensionFromUrl(downloadUrl) if len(item.MediaItemParts) > 1: saveFileName = "%s-Part_%s.%s" % (item.name, i, extension) else: saveFileName = "%s.%s" % (item.name, extension) Logger.Debug(saveFileName) # headers = item.HttpHeaders + mediaItemPart.HttpHeaders headers = item.HttpHeaders.copy() headers.update(mediaItemPart.HttpHeaders) progressDialog = XbmcDialogProgressWrapper("Downloading Item", item.name, stream.Url) folderName = XbmcWrapper.ShowFolderSelection('Select download destination for "%s"' % (saveFileName, )) UriHandler.Download(downloadUrl, saveFileName, folderName, progressDialog, proxy=self.proxy, additionalHeaders=headers) i += 1 item.downloaded = True return item
def GetXBMCPlayListItem(self, parent, bitrate=None, name=None, updateItemUrls=False): """Returns a XBMC List Item than can be played or added to an XBMC PlayList. Arguments: parent : MediaItem - the parent MediaItem Keyword Arguments: quality : [opt] integer - The quality of the requested XBMC PlayListItem streams. name : [opt] string - If set, it overrides the original name of the MediaItem. updateItemUrls : [opt] boolean - If set, the xbmc items will have a path that corresponds with the actual stream. Returns: A tuple with (stream url, XBMC PlayListItem). The XBMC PlayListItem can be used to add to a XBMC Playlist. The stream url can be used to set as the stream for the PlayListItem using xbmc.PlayList.add() If quality is not specified the quality is retrieved from the add-on settings. """ if not name: Logger.Debug("Creating XBMC ListItem '%s'", self.Name) else: Logger.Debug("Creating XBMC ListItem '%s'", name) item = parent.GetXBMCItem(name=name) if not bitrate: bitrate = AddonSettings.GetMaxStreamBitrate() for prop in self.Properties: Logger.Trace("Adding property: %s", prop) item.setProperty(prop[0], prop[1]) # now find the correct quality stream stream = self.GetMediaStreamForBitrate(bitrate) # if self.UserAgent and "|User-Agent" not in stream.Url: # url = "%s|User-Agent=%s" % (stream.Url, htmlentityhelper.HtmlEntityHelper.UrlEncode(self.UserAgent)) # stream.Url = url if updateItemUrls: Logger.Info("Updating xbmc playlist-item path: %s", stream.Url) item.setProperty("path", stream.Url) return stream, item
def PlayVideoItem(self, item, bitrate=None): """Starts the playback of the <item> with the specific <bitrate> in the selected <player>. Arguments: item : MediaItem - The item to start playing Keyword Arguments: bitrate : [opt] integer - The requested bitrate in Kbps or None. plugin : [opt] boolean - Indication whether we are in plugin mode. If True, there will not actually be playback, rather a tuple with info. Returns: The updated <item>. Starts the playback of the selected MediaItem <item>. Before playback is started the item is check for completion (item.complete), if not completed, the self.UpdateVideoItem method is called to update the item. After updating the requested bitrate playlist is selected, if bitrate was set to None the bitrate is retrieved from the addon settings. The playlist is then played using the requested player. """ if bitrate is None: # use the bitrate from the xbmc settings if bitrate was not specified and the item is MultiBitrate bitrate = AddonSettings.GetMaxStreamBitrate() # should we download items? Logger.Debug("Checking for not streamable parts") # We need to substract the download time from processing time downloadStart = datetime.now() for part in item.MediaItemParts: if not part.CanStream: stream = part.GetMediaStreamForBitrate(bitrate) if not stream.Downloaded: Logger.Debug("Downloading not streamable part: %s\nDownloading Stream: %s", part, stream) # we need a unique filename fileName = encodinghelper.EncodingHelper.EncodeMD5(stream.Url) extension = UriHandler.GetExtensionFromUrl(stream.Url) # now we force the busy dialog to close, else we cannot cancel the download # setResolved will not work. xbmc.executebuiltin("Dialog.Close(busydialog)") # headers = item.HttpHeaders + part.HttpHeaders headers = item.HttpHeaders.copy() headers.update(part.HttpHeaders) Logger.Error(headers) streamFilename = "xot.%s.%skbps-%s.%s" % (fileName, stream.Bitrate, item.name, extension) progressDialog = XbmcDialogProgressWrapper("Downloading Item", item.name, stream.Url) cacheFile = UriHandler.Download(stream.Url, streamFilename, self.GetDefaultCachePath(), progressDialog.ProgressUpdate, proxy=self.proxy, additionalHeaders=headers) if cacheFile == "": Logger.Error("Cannot download stream %s \nFrom: %s", stream, part) return if cacheFile.startswith("\\\\"): cacheFile = cacheFile.replace("\\", "/") stream.Url = "file:///%s" % (cacheFile,) else: stream.Url = "file://%s" % (cacheFile,) # stream.Url = cacheFile stream.Downloaded = True # We need to substract the download time from processing time downloadTime = datetime.now() - downloadStart downloadDuration = 1000 * downloadTime.seconds + downloadTime.microseconds / 1000 # Set item as downloaded item.downloaded = True # get the playlist (playList, srt) = item.GetXBMCPlayList(bitrate, updateItemUrls=True, proxy=self.proxy) # call for statistics with timing Statistics.RegisterPlayback(self, item, Initializer.StartTime, -downloadDuration) # if the item urls have been updated, don't start playback, but return return playList, srt