Beispiel #1
0
def play(slug, **kwargs):
    data, content = api.play(slug)

    headers = {
        'Authorization': 'Bearer {}'.format(userdata.get('access_token')),
    }

    item = plugin.Item(
        path = data['url'],
        inputstream = inputstream.MPD(),
        headers = headers,
    )

    if 'drm' in data:
        item.inputstream = inputstream.Widevine(license_key = data['drm']['licenseUrl'])
        item.proxy_data['manifest_middleware'] = plugin.url_for(mpd_request)
        if settings.getBool('wv_secure'):
            item.inputstream.properties['license_flags'] = 'force_secure_decoder'

    item.play_next = {}
    if ':episode' in slug:
        item.update(
            label = content['titles']['full'],
            art   = {'thumb': _image(content['images'].get('tileburnedin')), 'fanart':  _image(content['images'].get('tile'), size='1920x1080')},
            info  = {
                'plot': content['summaries']['short'],
                'duration': content['duration'],
                'tvshowtitle': content['seriesTitles']['full'],
                'season': content.get('seasonNumber', 1),
                'episode': content.get('numberInSeason', content.get('numberInSeries', 1)),
                'mediatype': 'episode'
            },
        )

        if settings.getBool('play_next_episode', True):
            item.play_next['next_file'] = _get_play_path(content.get('next'))

    elif ':feature' in slug:
        item.update(
            label = content['titles']['full'],
            art   = {'thumb': _image(content['images'].get('tileburnedin')), 'fanart':_image(content['images'].get('tile'), size='1920x1080')},
            info  = {
                'plot': content['summaries']['short'],
                'duration': content['duration'],
                'year': content['releaseYear'],
                'mediatype': 'movie',
            },
        )

        if settings.getBool('play_next_movie', False):
            for slug in content.get('similars', []):
                if ':feature' in slug:
                    item.play_next['next_file'] = 'urn:hbo:feature:' + slug.split(':')[3]
                    break

    if not settings.getBool('ignore_subs', False):
        for row in data.get('textTracks', []):
            item.subtitles.append([row['url'], row['language']])

    return item
Beispiel #2
0
def play_video(index, **kwargs):
    video = VIDEO_TESTS[int(index)]

    item = plugin.Item(path=video['url'], )

    if video['type'] == 'ia_hls':
        item.inputstream = inputstream.HLS(force=True, live=False)
    elif video['type'] == 'ia_mpd':
        item.inputstream = inputstream.MPD()
    elif video['type'] == 'ia_widevine':
        item.inputstream = inputstream.Widevine(video.get('license_key'))

    return item
def play_channel(slug, **kwargs):
    channel = Channel.get_by_id(slug)
    split = channel.url.split('|')

    headers = {
        'user-agent': DEFAULT_USERAGENT,
    }

    if len(split) > 1:
        _headers = dict(
            parse_qsl(u'{}'.format(split[1]), keep_blank_values=True))
        for key in _headers:
            if _headers[key].startswith(' '):
                _headers[key] = u'%20{}'.format(_headers[key][1:])

            headers[key.lower()] = _headers[key]

    item = plugin.Item(
        label=channel.name,
        art={'thumb': channel.logo},
        path=split[0],
        properties=channel.properties,
        headers=headers,
        playable=True,
    )

    if channel.radio:
        item.use_proxy = False

    manifest_type = channel.properties.get(
        'inputstream.adaptive.manifest_type', '')
    license_type = channel.properties.get('inputstream.adaptive.license_type',
                                          '')

    if license_type.lower() == 'com.widevine.alpha':
        inputstream.Widevine().check()

    elif manifest_type.lower() == 'hls':
        inputstream.HLS(force=True, live=True).check()

    elif manifest_type.lower() == 'ism':
        inputstream.Playready().check()

    elif manifest_type.lower() == 'mpd':
        inputstream.MPD().check()

    elif not channel.radio and '.m3u8' in split[0].lower(
    ) and settings.getBool('use_ia_hls_live'):
        item.inputstream = inputstream.HLS(live=True)

    return item
Beispiel #4
0
def play(id, **kwargs):
    data = api.media(id)

    item = plugin.Item(
        path=data['encodings'][0]['master_playlist_url'],
        inputstream=inputstream.MPD(),
        proxy_data={'default_language': 'English'},
    )

    for row in data.get('closed_captions', []):
        item.subtitles.append([row['file'], row['code']])

    if settings.getBool('sync_playback', False):
        item.callback = {
            'type': 'interval',
            'interval': 10,
            'callback': plugin.url_for(callback, media_id=id),
        }

    return item
Beispiel #5
0
    def play(self, slug):
        resp = self._session.get('/videos/{slug}'.format(slug=slug),
                                 allow_redirects=False)

        if resp.status_code == 302 or 'The device limit for your account has been reached' in resp.text:
            raise APIError(_.DEVICE_LIMIT)

        page = resp.text.replace(' ', '').strip()
        play_url = re.search('embed_url:"(.*?)"', page).group(1)

        resp = self._session.get(play_url)
        page = resp.text.replace(' ', '').strip()

        event_id = re.search('eventId:(.*?),', page)

        if event_id:
            config_url = LIVESTREAM_URL.format(event_id=event_id.group(1))
        else:
            config_url = re.search('"config_url":"(.*?)"', page).group(1)
            config_url = config_url.encode().decode('unicode_escape')

        data = self._session.get(config_url,
                                 headers={
                                     'Referer': 'https://embed.vhx.tv/'
                                 }).json()
        if data.get('secure_m3u8_url'):
            return data['secure_m3u8_url'], inputstream.HLS()

        default_cdn = data['request']['files']['dash']['default_cdn']
        mpd_url = data['request']['files']['dash']['cdns'][default_cdn][
            'url']  #.replace('.json?base64_init=1', '.mpd')
        mpd_url = mpd_url.replace('.json', '.mpd')

        if data['request'].get('drm'):
            license_url = self._session.get(
                data['request']['drm']['cdms']['widevine']['license_url']).text
            ia = inputstream.Widevine(license_key=license_url)
        else:
            ia = inputstream.MPD()

        return mpd_url, ia
Beispiel #6
0
def play(slug, skip_intro=None, **kwargs):
    data, content = api.play(slug)

    headers = {
        'Authorization': 'Bearer {}'.format(userdata.get('access_token')),
    }

    item = plugin.Item(
        path=data['url'],
        inputstream=inputstream.MPD(),
        headers=headers,
    )

    if 'drm' in data:
        item.inputstream = inputstream.Widevine(
            license_key=data['drm']['licenseUrl'])
        item.proxy_data['manifest_middleware'] = plugin.url_for(mpd_request)
        if settings.getBool('wv_secure'):
            item.inputstream.properties[
                'license_flags'] = 'force_secure_decoder'

    # resume_from = None
    # if kwargs[ROUTE_RESUME_TAG]:
    #     pass
    #     if settings.getBool('disney_sync', False):
    #         continue_watching = api.continue_watching()
    #         resume_from = continue_watching.get(video['contentId'], 0)
    #         item.properties['ForceResume'] = True

    # elif (int(skip_intro) if skip_intro is not None else settings.getBool('skip_intros', False)):
    #     resume_from = _get_milestone(data.get('annotations'), 'SKIP', default=0)

    # if resume_from is not None:
    #     item.properties['ResumeTime'] = resume_from
    #     item.properties['TotalTime']  = resume_from

    item.play_next = {}

    if ':episode' in slug:
        item.update(
            label=content['titles']['full'],
            art={
                'thumb': _image(content['images'].get('tileburnedin')),
                'fanart': _image(content['images'].get('tile'),
                                 size='1920x1080')
            },
            info={
                'plot':
                content['summaries']['short'],
                'duration':
                content['duration'],
                'tvshowtitle':
                content['seriesTitles']['full'],
                'season':
                content.get('seasonNumber', 1),
                'episode':
                content.get('numberInSeason', content.get('numberInSeries',
                                                          1)),
                'mediatype':
                'episode'
            },
        )

        if settings.getBool('play_next_episode', True):
            item.play_next['next_file'] = _get_play_path(content.get('next'))

    elif ':feature' in slug:
        item.update(
            label=content['titles']['full'],
            art={
                'thumb': _image(content['images'].get('tileburnedin')),
                'fanart': _image(content['images'].get('tile'),
                                 size='1920x1080')
            },
            info={
                'plot': content['summaries']['short'],
                'duration': content['duration'],
                'year': content['releaseYear'],
                'mediatype': 'movie',
            },
        )

        if settings.getBool('play_next_movie', False):
            for slug in content.get('similars', []):
                if ':feature' in slug:
                    item.play_next[
                        'next_file'] = 'urn:hbo:feature:' + slug.split(':')[3]
                    break

    for row in data.get('textTracks', []):
        item.subtitles.append([row['url'], row['language']])

    return item
Beispiel #7
0
def play(asset_id, **kwargs):
    use_ia_hls = settings.getBool('use_ia_hls')
    stream_data = api.get_stream_data(asset_id)
    token = userdata.get('access_token')

    play_item = plugin.Item(
        art=False,
        headers={'Authorization': 'Bearer {}'.format(token)},
        cookies={
            'access_token': token,
            'client_id': CLIENT_ID
        },
    )

    is_drm = stream_data.get('course_is_drmed', False)

    hls_url = stream_data.get('hls_url')
    if hls_url and not is_drm:
        play_item.path = hls_url
        play_item.inputstream = inputstream.HLS(live=False)
        return play_item

    stream_urls = stream_data.get('stream_urls') or {}
    streams = stream_urls.get('Video') or stream_urls.get('Audio') or []

    CODECS = {
        'libx264': 'H.264',
        'libx265': 'H.265',
    }

    urls = []
    qualities = []
    for item in streams:
        if item['type'] != 'application/x-mpegURL':
            data = stream_data['data']['outputs'][item['label']]

            if data.get('migrated_from_non_labeled_conversions'):
                bandwidth, resolution = BANDWIDTH_MAP.get(int(item['label']))
                codecs, fps = '', ''
            else:
                fps = _(_.QUALITY_FPS, fps=float(data['frame_rate']))
                resolution = '{}x{}'.format(data['width'], data['height'])
                bandwidth = data[
                    'video_bitrate_in_kbps'] * 1000  #(or total_bitrate_in_kbps)
                codecs = CODECS.get(data.get('video_codec'), '')

            urls.append([bandwidth, item['file']])
            qualities.append([
                bandwidth,
                _(_.QUALITY_BITRATE,
                  bandwidth=float(bandwidth) / 1000000,
                  resolution=resolution,
                  fps=fps,
                  codecs=codecs)
            ])

    if not urls:
        for row in stream_data.get('media_sources') or []:
            if row['type'] == 'application/x-mpegURL' and 'encrypted-files' not in row[
                    'src']:
                urls.append([row['src'], inputstream.HLS(live=False)])

            if row['type'] == 'application/dash+xml':
                play_item.path = row['src']

                if is_drm:
                    token = stream_data['media_license_token']
                    ia = inputstream.Widevine(license_key=WV_URL.format(
                        token=token))
                else:
                    ia = inputstream.MPD()

                urls.append([row['src'], ia])

        if urls:
            urls = sorted(urls,
                          key=lambda x: isinstance(x[1], inputstream.Widevine))
            play_item.path = urls[0][0]
            play_item.inputstream = urls[0][1]
            if isinstance(play_item.inputstream, inputstream.Widevine):
                system, arch = get_system_arch()
                if system == 'Windows' or (system == 'Linux'
                                           and arch == 'armv7'):
                    gui.ok(_.VMP_WARNING)

            return play_item

    if not urls:
        raise plugin.Error(_.NO_STREAM_ERROR)

    quality = kwargs.get(QUALITY_TAG)
    if quality is None:
        quality = settings.getEnum('default_quality',
                                   QUALITY_TYPES,
                                   default=QUALITY_ASK)
    else:
        quality = int(quality)

    urls = sorted(urls, key=lambda s: s[0], reverse=True)
    qualities = sorted(qualities, key=lambda s: s[0], reverse=True)

    if quality == QUALITY_CUSTOM:
        quality = int(settings.getFloat('max_bandwidth') * 1000000)
    elif quality == QUALITY_ASK:
        quality = select_quality(qualities)

    if quality == QUALITY_BEST:
        quality = qualities[0][0]
    elif quality == QUALITY_LOWEST:
        quality = qualities[-1][0]

    play_item.path = urls[-1][1]
    for item in urls:
        if item[0] <= quality:
            play_item.path = item[1]
            break

    return play_item
Beispiel #8
0
def play(id, start_from=0, play_type=PLAY_FROM_LIVE, **kwargs):
    asset = api.stream(id)

    start_from = int(start_from)
    play_type = int(play_type)
    is_live = kwargs.get(ROUTE_LIVE_TAG) == ROUTE_LIVE_SUFFIX

    streams = [asset['recommendedStream']]
    streams.extend(asset['alternativeStreams'])
    streams = [s for s in streams if s['mediaFormat'] in SUPPORTED_FORMATS]

    if not streams:
        raise PluginError(_.NO_STREAM)

    providers = SUPPORTED_PROVIDERS[:]
    providers.extend([s['provider'] for s in streams])

    streams = sorted(streams,
                     key=lambda k: (providers.index(k['provider']),
                                    SUPPORTED_FORMATS.index(k['mediaFormat'])))
    stream = streams[0]

    log.debug('Stream CDN: {provider} | Stream Format: {mediaFormat}'.format(
        **stream))

    item = plugin.Item(
        path=stream['manifest']['uri'],
        art=False,
        headers=HEADERS,
        use_proxy=True,  #required to support dolby 5.1 and license requests
    )

    if is_live and (play_type == PLAY_FROM_LIVE or
                    (play_type == PLAY_FROM_ASK
                     and gui.yes_no(_.PLAY_FROM,
                                    yeslabel=_.PLAY_FROM_LIVE,
                                    nolabel=_.PLAY_FROM_START))):
        play_type = PLAY_FROM_LIVE
        start_from = 0

    if stream['mediaFormat'] == FORMAT_DASH:
        item.inputstream = inputstream.MPD()

    elif stream['mediaFormat'] == FORMAT_HLS_TS:
        force = (is_live and play_type == PLAY_FROM_LIVE)
        item.inputstream = inputstream.HLS(force=force, live=is_live)

        if force and not item.inputstream.check():
            raise PluginError(_.HLS_REQUIRED)

    elif stream['mediaFormat'] == FORMAT_HLS_FMP4:
        item.inputstream = inputstream.HLS(force=True, live=is_live)
        if not item.inputstream.check():
            raise PluginError(_.HLS_REQUIRED)

    elif stream['mediaFormat'] in (FORMAT_DRM_DASH, FORMAT_DRM_DASH_HEVC):
        item.inputstream = inputstream.Widevine(
            license_key=plugin.url_for(license_request))

    if start_from:
        item.properties['ResumeTime'] = start_from
        item.properties['TotalTime'] = start_from

    return item
Beispiel #9
0
def play(id, start_from=0, play_type=PLAY_FROM_LIVE, **kwargs):
    asset = api.stream(id)

    start_from = int(start_from)
    play_type = int(play_type)
    is_live = kwargs.get(ROUTE_LIVE_TAG) == ROUTE_LIVE_SUFFIX

    streams = [asset['recommendedStream']]
    streams.extend(asset['alternativeStreams'])
    streams = [s for s in streams if s['mediaFormat'] in SUPPORTED_FORMATS]

    if not streams:
        raise PluginError(_.NO_STREAM)

    prefer_cdn = settings.getEnum('prefer_cdn', AVAILABLE_CDNS)
    if prefer_cdn == CDN_AUTO:
        try:
            prefer_cdn = api.use_cdn(is_live)['useCDN']
        except Exception as e:
            log.debug('Failed to get preferred cdn')
            prefer_cdn = None

    providers = [prefer_cdn]
    providers.extend([s['provider'] for s in streams])

    streams = sorted(streams,
                     key=lambda k: (providers.index(k['provider']),
                                    SUPPORTED_FORMATS.index(k['mediaFormat'])))
    stream = streams[0]

    log.debug('Stream CDN: {provider} | Stream Format: {mediaFormat}'.format(
        **stream))

    item = plugin.Item(
        path=stream['manifest']['uri'],
        art=False,
        headers=HEADERS,
    )

    item.headers.update(
        {'authorization': 'Bearer {}'.format(userdata.get('access_token'))})

    if is_live and (play_type == PLAY_FROM_LIVE or
                    (play_type == PLAY_FROM_ASK
                     and gui.yes_no(_.PLAY_FROM,
                                    yeslabel=_.PLAY_FROM_LIVE,
                                    nolabel=_.PLAY_FROM_START))):
        play_type = PLAY_FROM_LIVE
        start_from = 0

    ## Cloudfront streams start from correct position
    if stream['provider'] == CDN_CLOUDFRONT and start_from:
        start_from = 1

    if stream['mediaFormat'] == FORMAT_DASH:
        item.inputstream = inputstream.MPD()

    elif stream['mediaFormat'] == FORMAT_HLS_TS:
        force = (is_live and play_type == PLAY_FROM_LIVE
                 and asset['assetType'] != 'live-linear')
        item.inputstream = inputstream.HLS(force=force, live=is_live)
        if force and not item.inputstream.check():
            raise PluginError(_.HLS_REQUIRED)

    elif stream['mediaFormat'] == FORMAT_HLS_FMP4:
        item.inputstream = inputstream.HLS(force=True, live=is_live)
        if not item.inputstream.check():
            raise PluginError(_.HLS_REQUIRED)

    elif stream['mediaFormat'] in (FORMAT_DRM_DASH, FORMAT_DRM_DASH_HEVC):
        item.inputstream = inputstream.Widevine(license_key=LICENSE_URL, )

    if start_from and not kwargs[ROUTE_RESUME_TAG]:
        item.properties['ResumeTime'] = start_from
        item.properties['TotalTime'] = start_from

    return item