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
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
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
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
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
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
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
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