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)
Beispiel #3
0
    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)
Beispiel #4
0
    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)
Beispiel #5
0
    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)
Beispiel #6
0
    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)
Beispiel #8
0
    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)
Beispiel #9
0
    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)