def play_asset(self, asset_id): """ Play an asset (can be a program of a live channel). :param string asset_id: The ID of the asset to play. """ # Get asset info asset = self._channel_api.get_asset(asset_id) item = Menu.generate_titleitem(asset) # Get stream info try: stream_info = self._channel_api.get_stream(asset_id) except NotAvailableInOfferException as exc: _LOGGER.error(exc) kodiutils.ok_dialog(message=kodiutils.localize(30712)) return license_key = self._create_license_key( stream_info.drm_license_url, key_headers={'Content-Type': 'application/octet-stream'}) _LOGGER.debug('Starting playing %s with license key %s', stream_info.url, license_key) kodiutils.play(stream_info.url, license_key, item.title, item.art_dict, item.info_dict, item.prop_dict)
def play(item): """ Play the requested item. :type item: string """ # Workaround for Raspberry Pi 3 and older omxplayer = kodiutils.get_global_setting('videoplayer.useomxplayer') if omxplayer is False: kodiutils.set_global_setting('videoplayer.useomxplayer', True) try: # Check if we have credentials if not kodiutils.get_setting( 'username') or not kodiutils.get_setting('password'): confirm = kodiutils.yesno_dialog( message=kodiutils.localize(30701) ) # To watch a video, you need to enter your credentials. Do you want to enter them now? if confirm: kodiutils.open_settings() kodiutils.end_of_directory() return # Fetch an auth token now try: auth = AuthApi(kodiutils.get_setting('username'), kodiutils.get_setting('password'), kodiutils.get_tokens_path()) # Get stream information resolved_stream = ContentApi(auth).get_stream_by_uuid(item) except (InvalidLoginException, AuthenticationException) as ex: _LOGGER.error(ex) kodiutils.ok_dialog( message=kodiutils.localize(30702, error=str(ex))) kodiutils.end_of_directory() return except GeoblockedException: kodiutils.ok_dialog(heading=kodiutils.localize(30709), message=kodiutils.localize( 30710)) # This video is geo-blocked... return except UnavailableException: kodiutils.ok_dialog(heading=kodiutils.localize(30711), message=kodiutils.localize( 30712)) # The video is unavailable... return # Play this item kodiutils.play(resolved_stream)
def play(self, uuid): """ Play the requested item. :type uuid: string """ # Lookup the stream resolved_stream = self._resolve_stream(uuid) if resolved_stream.license_url: # Generate license key license_key = self.create_license_key( resolved_stream.license_url, key_headers=dict(customdata=resolved_stream.auth, )) else: license_key = None kodiutils.play(resolved_stream.url, resolved_stream.stream_type, license_key)
def play_from_page(self, path): """ Play the requested item. :type path: string """ if not path: kodiutils.ok_dialog(message=kodiutils.localize(30712)) # The video is unavailable... return # Get episode information episode = self._api.get_episode(path, cache=CACHE_PREVENT) resolved_stream = None if episode is None: kodiutils.ok_dialog(message=kodiutils.localize(30712)) return if episode.stream: # We already have a resolved stream. Nice! # We don't need credentials for these streams. resolved_stream = ResolvedStream( uuid=episode.uuid, url=episode.stream, ) _LOGGER.debug('Already got a resolved stream: %s', resolved_stream) if episode.uuid: # Lookup the stream resolved_stream = self._resolve_stream(episode.uuid) _LOGGER.debug('Resolved stream: %s', resolved_stream) if resolved_stream: titleitem = Menu.generate_titleitem(episode) if resolved_stream.license_url: # Generate license key license_key = self.create_license_key(resolved_stream.license_url, key_headers=dict( customdata=resolved_stream.auth, )) else: license_key = None kodiutils.play(resolved_stream.url, resolved_stream.stream_type, license_key, info_dict=titleitem.info_dict, art_dict=titleitem.art_dict, prop_dict=titleitem.prop_dict)
def play(self, uuid): """ Play the requested item. :type uuid: string """ if not uuid: kodiutils.ok_dialog(message=kodiutils.localize(30712)) # The video is unavailable... return # Lookup the stream resolved_stream = self._resolve_stream(uuid) if resolved_stream.license_url: # Generate license key license_key = self.create_license_key(resolved_stream.license_url, key_headers=dict( customdata=resolved_stream.auth, )) else: license_key = None kodiutils.play(resolved_stream.url, resolved_stream.stream_type, license_key)
def play_asset(self, asset_id): """ Play an asset (can be a program of a live channel). :param string asset_id: The ID of the asset to play. """ # Get asset info if len(asset_id) == 32: # a locId is 32 chars asset = self._channel_api.get_asset_by_locid(asset_id) else: # an asset_id is 40 chars asset = self._channel_api.get_asset(asset_id) if isinstance(asset, Program): item = Menu.generate_titleitem_program(asset) elif isinstance(asset, Channel): item = Menu.generate_titleitem_channel(asset) else: raise Exception('Unknown asset type: %s' % asset) # Get stream info try: stream_info = self._channel_api.get_stream(asset.uid) except InvalidTokenException: # Retry with fresh tokens self._auth.login(True) stream_info = self._channel_api.get_stream(asset.uid) except (NotAvailableInOfferException, UnavailableException) as exc: _LOGGER.error(exc) kodiutils.ok_dialog( message=kodiutils.localize(30712) ) # The video is unavailable and can't be played right now. kodiutils.end_of_directory() return license_key = self._create_license_key( stream_info.drm_license_url, key_headers={'Content-Type': 'application/octet-stream'}) _LOGGER.debug('Starting playing %s with license key %s', stream_info.url, license_key) kodiutils.play(stream_info.url, license_key, item.title, item.art_dict, item.info_dict, item.prop_dict)
def play(self, channel, item): """ Play the requested item. :type channel: string :type item: string """ try: # Get stream information resolved_stream = self._api.get_stream(channel, item) except GeoblockedException: kodiutils.ok_dialog(heading=kodiutils.localize(30709), message=kodiutils.localize(30710)) # This video is geo-blocked... return except UnavailableException: kodiutils.ok_dialog(heading=kodiutils.localize(30711), message=kodiutils.localize(30712)) # The video is unavailable... return # Play this item kodiutils.play(resolved_stream)
def play(self, category, item): """ Play the requested item. :type category: string :type item: string """ if not self._check_credentials(): kodiutils.end_of_directory() return # Check if inputstreamhelper is correctly installed if not self._check_inputstream(): kodiutils.end_of_directory() return try: # Get stream information resolved_stream = self._vtm_go_stream.get_stream(category, item) except StreamGeoblockedException: kodiutils.ok_dialog(heading=kodiutils.localize(30709), message=kodiutils.localize(30710)) # This video is geo-blocked... kodiutils.end_of_directory() return except StreamUnavailableException: kodiutils.ok_dialog(heading=kodiutils.localize(30711), message=kodiutils.localize(30712)) # The video is unavailable... kodiutils.end_of_directory() return info_dict = { 'tvshowtitle': resolved_stream.program, 'title': resolved_stream.title, 'duration': resolved_stream.duration, } prop_dict = {} stream_dict = { 'duration': resolved_stream.duration, } upnext_data = None # Lookup metadata try: if category in ['movies', 'oneoffs']: info_dict.update({'mediatype': 'movie'}) # Get details movie_details = self._vtm_go.get_movie(item) if movie_details: info_dict.update({ 'plot': movie_details.description, 'year': movie_details.year, 'aired': movie_details.aired, }) elif category == 'episodes': info_dict.update({'mediatype': 'episode'}) # There is no direct API to get episode details, so we go trough the cached program details program = self._vtm_go.get_program(resolved_stream.program_id) if program: episode_details = self._vtm_go.get_episode_from_program(program, item) if episode_details: info_dict.update({ 'plot': episode_details.description, 'season': episode_details.season, 'episode': episode_details.number, }) # Lookup the next episode next_episode_details = self._vtm_go.get_next_episode_from_program(program, episode_details.season, episode_details.number) # Create the data for Up Next if next_episode_details: upnext_data = self.generate_upnext(episode_details, next_episode_details) elif category == 'channels': info_dict.update({'mediatype': 'episode'}) # For live channels, we need to keep on updating the manifest # This might not be needed, and could be done with the Location-tag updates if inputstream.adaptive supports it # See https://github.com/peak3d/inputstream.adaptive/pull/298#issuecomment-524206935 prop_dict.update({ 'inputstream.adaptive.manifest_update_parameter': 'full', }) else: _LOGGER.warning('Unknown category %s', category) except UnavailableException: # We continue without details. # This allows to play some programs that don't have metadata (yet). pass # If we have enabled the Manifest proxy, route the call trough that. if category in ['movies', 'oneoffs', 'episodes'] and kodiutils.get_setting_bool('manifest_proxy'): try: # Python 3 from urllib.parse import urlencode except ImportError: # Python 2 from urllib import urlencode port = kodiutils.get_setting_int('manifest_proxy_port') if not port: kodiutils.notification(message=kodiutils.localize(30718), icon='error') kodiutils.end_of_directory() return url = 'http://127.0.0.1:{port}/manifest?{path}'.format(port=port, path=urlencode({'path': resolved_stream.url})) else: url = resolved_stream.url license_key = self._vtm_go_stream.create_license_key(resolved_stream.license_url) # Play this item kodiutils.play(url, license_key, resolved_stream.title, {}, info_dict, prop_dict, stream_dict) # Wait for playback to start kodi_player = KodiPlayer() if not kodi_player.waitForPlayBack(url=url): # Playback didn't start kodiutils.end_of_directory() return # Send Up Next data if upnext_data and kodiutils.get_setting_bool('useupnext'): _LOGGER.debug("Sending Up Next data: %s", upnext_data) self.send_upnext(upnext_data)
def play(self, category, item): """ Play the requested item. :type category: string :type item: string """ # Check if inputstreamhelper is correctly installed if not self._check_inputstream(): kodiutils.end_of_directory() return try: # Get stream information resolved_stream = self._stream.get_stream(category, item) except UnavailableException: kodiutils.ok_dialog(message=kodiutils.localize( 30712)) # The video is unavailable... kodiutils.end_of_directory() return except LimitReachedException: kodiutils.ok_dialog( message=kodiutils.localize(30713) ) # You have reached the maximum amount of concurrent streams... kodiutils.end_of_directory() return info_dict = { 'tvshowtitle': resolved_stream.program, 'title': resolved_stream.title, 'duration': resolved_stream.duration, } prop_dict = {} stream_dict = { 'duration': resolved_stream.duration, } upnext_data = None # Lookup metadata try: if category in ['movies', 'oneoffs']: info_dict.update({'mediatype': 'movie'}) # Get details movie_details = self._api.get_movie(item) if movie_details: info_dict.update({ 'plot': movie_details.description, 'year': movie_details.year, 'aired': movie_details.aired, }) elif category == 'episodes': info_dict.update({'mediatype': 'episode'}) # There is no direct API to get episode details, so we go trough the cached program details program = self._api.get_program(resolved_stream.program_id) if program: episode_details = self._api.get_episode_from_program( program, item) if episode_details: info_dict.update({ 'plot': episode_details.description, 'season': episode_details.season, 'episode': episode_details.number, }) # Lookup the next episode next_episode_details = self._api.get_next_episode_from_program( program, episode_details.season, episode_details.number) # Create the data for Up Next if next_episode_details: upnext_data = self.generate_upnext( episode_details, next_episode_details) else: _LOGGER.warning('Unknown category %s', category) except UnavailableException: # We continue without details. # This allows to play some programs that don't have metadata (yet). pass # If we have enabled the Manifest proxy, route the call trough that. if kodiutils.get_setting_bool('manifest_proxy'): try: # Python 3 from urllib.parse import urlencode except ImportError: # Python 2 from urllib import urlencode port = kodiutils.get_setting_int('manifest_proxy_port') if not port: kodiutils.notification(message=kodiutils.localize(30718), icon='error') kodiutils.end_of_directory() return url = 'http://127.0.0.1:{port}/manifest?{path}'.format( port=port, path=urlencode({'path': resolved_stream.url})) else: url = resolved_stream.url license_key = self._stream.create_license_key( resolved_stream.license_url) # Play this item kodiutils.play(url, license_key, resolved_stream.title, {}, info_dict, prop_dict, stream_dict, subtitles=resolved_stream.subtitles) # Wait for playback to start kodi_player = KodiPlayer() if not kodi_player.waitForPlayBack(url=url): # Playback didn't start return # Send Up Next data if upnext_data and kodiutils.get_setting_bool('useupnext'): _LOGGER.debug("Sending Up Next data: %s", upnext_data) self.send_upnext(upnext_data)