def play(livestream=None, brightcoveId=None, channel=None, **kwargs): if brightcoveId: item = api.get_brightcove_src(brightcoveId) elif livestream: item = plugin.Item(path=livestream, art=False, inputstream=inputstream.HLS(live=True)) if kwargs.get(ROUTE_LIVE_TAG) == ROUTE_LIVE_SUFFIX and not gui.yes_no( _.PLAY_FROM, yeslabel=_.PLAY_FROM_LIVE, nolabel=_.PLAY_FROM_START): item.properties['ResumeTime'] = '1' item.properties['TotalTime'] = '1' item.inputstream = inputstream.HLS(force=True, live=True) if not item.inputstream.check(): plugin.exception(_.LIVE_HLS_REQUIRED) elif channel: data = api.channel(channel) item = plugin.Item(path=data['publisherMetadata']['liveStreamUrl'], art=False, inputstream=inputstream.HLS(live=True)) item.headers = HEADERS 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 = _app_data() data['regions'].pop(ALL, None) channel = None region = None for code in data['regions']: channels = data['regions'][code]['channels'] if id in channels: channel = channels[id] region = data['regions'][code] break if not channel: raise Exception('Unable to find that channel') headers = data.get('headers', {}) headers.update(region.get('headers', {})) headers.update(channel.get('headers', {})) return plugin.Item( label=channel['name'], info={'plot': channel.get('description', '')}, art={'thumb': channel['logo']}, inputstream=inputstream.HLS(live=True), headers=headers, path=_get_url(channel), )
def _play(url, live=False): return plugin.Item( path=url, headers=HEADERS, inputstream=inputstream.HLS(live=live), art=False, )
def play(id, **kwargs): data = api.play(id) headers = {} headers.update(HEADERS) drm_info = data.get('drmInfo') or {} cookies = data.get('cookie') or {} if drm_info: if drm_info['drmScheme'].lower() == 'widevine': ia = inputstream.Widevine(license_key=drm_info['drmLicenseUrl'], ) headers.update(drm_info.get('drmKeyRequestProperties') or {}) else: raise PluginError('Unsupported Stream!') else: ia = inputstream.HLS(live=True) return plugin.Item( path=data['url'], inputstream=ia, headers=headers, cookies=cookies, resume_from=LIVE_HEAD, ## Need to seek to live over multi-periods )
def play_channel(channel, **kwargs): for row in api.live(): if row['title'] == channel: return plugin.Item( inputstream = inputstream.HLS(live=True), path = row['videoRenditions']['videoCloud']['hlsUrl'], art = False, )
def play_channel(id, **kwargs): url = api.play_channel(id) return plugin.Item( path = url, headers = HEADERS, inputstream = inputstream.HLS(live=True), )
def play(id, **kwargs): channel = _channels()[id] return plugin.Item( label=channel['name'], info={'plot': channel['description']}, art={'thumb': channel['logo']}, inputstream=inputstream.HLS(live=True, force=True), path=channel['url'], )
def play(id, **kwargs): data = _app_data() channel = data['regions'][ALL]['channels'][id] return plugin.Item( label=channel['name'], info={'plot': channel.get('description')}, art={'thumb': channel['logo']}, inputstream=inputstream.HLS(live=True), headers=data['headers'], path=channel['url'], )
def play(video_id, **kwargs): url, subtitles = api.play(video_id) item = plugin.Item( path=url, inputstream=inputstream.HLS(live=ROUTE_LIVE_TAG in kwargs), ) for idx, row in enumerate(subtitles): item.subtitles.append([row['file'], row['label']]) 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(id, **kwargs): channel = api.all_channels()[id] item = plugin.Item( label=channel['name'], art={'thumb': channel['logo']}, path=channel['url'], ) if KODI_VERSION > 18: item.inputstream = inputstream.HLS(live=True) return item
def play(type, id, **kwargs): if type == 'channel' and (id == 'TSR' or not api.logged_in): url = 'https://i.mjh.nz/nz/{}'.format(GUEST_SLUGS[id]) else: url = api.access(type, id) item = plugin.Item( path=url, inputstream=inputstream.HLS(live=True, force=True) if id != 'TSR' else None, headers=HEADERS, ) return item
def _get_play_item(game, game_type, play_type=PLAY_FROM_LIVE): play_type = int(play_type) item = parse_game(game) is_live = game.state == Game.LIVE item.inputstream = inputstream.HLS(live=is_live) if play_type == PLAY_FROM_START or (play_type == PLAY_FROM_ASK and not gui.yes_no(_.PLAY_FROM, yeslabel=_.PLAY_FROM_LIVE, nolabel=_.PLAY_FROM_START)): item.properties['ResumeTime'] = '1' item.properties['TotalTime'] = '1' if is_live and not item.inputstream.check(): raise PluginError(_.HLS_REQUIRED) item.path = api.get_play_url(game, game_type) return item
def play(video_id, play_type=None, **kwargs): url = api.play(video_id) play_type = int(play_type) if play_type else settings.getEnum( 'live_play_type', PLAY_FROM_TYPES, default=PLAY_FROM_ASK) is_live = ROUTE_LIVE_TAG in kwargs item = plugin.Item( path=url, inputstream=inputstream.HLS(live=is_live), ) # if is_live and (play_type == PLAY_FROM_START or (play_type == PLAY_FROM_ASK and not gui.yes_no(_.PLAY_FROM, yeslabel=_.PLAY_FROM_LIVE, nolabel=_.PLAY_FROM_START))): # item.properties['ResumeTime'] = '1' # item.properties['TotalTime'] = '1' # item.inputstream.force = True return item
def play(callsign, **kwargs): all_stations = api.all_stations() station = all_stations[callsign] if not station['url']: plugin.exception(_.NO_STREAM_MSG) item = plugin.Item( label=station['name'], path=station['url'], art={'thumb': station['logo']}, headers=HEADERS, inputstream=inputstream.HLS(live=True), geolock='US', ) return item
def play(slug, **kwargs): channel = get_channels()[slug] url = session.head(channel['mjh_master']).headers.get('location', '') item = plugin.Item( path=url or channel['mjh_master'], headers=channel['headers'], info={'plot': channel.get('description')}, video=channel.get('video', {}), audio=channel.get('audio', {}), art={'thumb': channel.get('logo')}, ) if channel.get('hls', False): item.inputstream = inputstream.HLS(live=True) return item
def play(callsign, **kwargs): app_data = _app_data() all_stations = app_data['channels'] station = all_stations[callsign] if not station['url']: plugin.exception(_.NO_STREAM_MSG) item = plugin.Item( label=station['name'], path=station['url'], art={'thumb': station['logo']}, headers=app_data['headers'], inputstream=inputstream.HLS(live=True), ) return item
def play(slug, game_type, play_type=PLAY_FROM_LIVE, **kwargs): play_type = int(play_type) game = get_game(slug) item = parse_game(game) is_live = game.state == Game.LIVE item.inputstream = inputstream.HLS(live=is_live) if play_type == PLAY_FROM_START or ( play_type == PLAY_FROM_ASK and not gui.yes_no(_.PLAY_FROM, yeslabel=_.PLAY_FROM_LIVE, nolabel=_.PLAY_FROM_START)): item.resume_from = 1 if is_live and not item.inputstream.check(): raise PluginError(_.HLS_REQUIRED) item.path = api.get_play_url(game, game_type) 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_channel(slug, **kwargs): channels = api.live_channels() for row in channels: if row['slug'] == slug: if row['dma']: play_path = row['dma']['playback_url'] elif row['currentListing']: play_path = row['currentListing'][0]['contentCANVideo'][ 'liveStreamingUrl'] else: raise Exception('No url found for this channel') return plugin.Item( label=row['channelName'], info={ 'plot': row['description'], }, art={'thumb': config.image(row['filePathLogoSelected'])}, path=play_path, inputstream=inputstream.HLS(live=True), ) raise Exception('Unable to find that channel')
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
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(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