Esempio n. 1
0
    def _get_vod_streams(self):
        url = 'http://ida.omroep.nl/odi/?prid={}&puboptions=adaptive,h264_bb,h264_sb,h264_std&adaptive=no&part=1&token={}'\
            .format(quote(self.npo_id), quote(self.get_token()))
        res = http.get(url, headers=HTTP_HEADERS);

        data = res.json()

        streams = {}
        stream = http.get(data['streams'][0].replace('jsonp', 'json'), headers=HTTP_HEADERS).json()
        streams['best'] = streams['high'] = HTTPStream(self.session, stream['url'])
        return streams
Esempio n. 2
0
    def _get_vod_streams(self):
        url = 'http://ida.omroep.nl/odi/?prid={0}&puboptions=adaptive,h264_bb,h264_sb,h264_std&adaptive=no&part=1&token={1}'\
            .format(quote(self.npo_id), quote(self.get_token()))
        res = http.get(url, headers=HTTP_HEADERS)

        data = res.json()

        streams = {}
        stream = http.get(data['streams'][0].replace('jsonp', 'json'),
                          headers=HTTP_HEADERS).json()
        streams['best'] = streams['high'] = HTTPStream(self.session,
                                                       stream['url'])
        return streams
Esempio n. 3
0
    def get_token(self):
        url = 'http://ida.omroep.nl/npoplayer/i.js?s={0}'.format(
            quote(self.url))
        token = http.get(url, headers=HTTP_HEADERS).text
        token = re.compile(r'token.*?"(.*?)"',
                           re.DOTALL + re.IGNORECASE).search(token).group(1)

        # Great the have a ['en','ok','t'].reverse() decurity option in npoplayer.js
        secured = list(token)
        token = list(token)

        first = -1
        second = -1
        for i, c in enumerate(token):
            if c.isdigit() and 4 < i < len(token):
                if first == -1:
                    first = i
                else:
                    second = i
                    break

        if first == -1:
            first = 12
        if second == -1:
            second = 13

        secured[first] = token[second]
        secured[second] = token[first]
        return ''.join(secured)
Esempio n. 4
0
    def get_token(self):
        url = 'http://ida.omroep.nl/npoplayer/i.js?s={}'.format(quote(self.url))
        token = http.get(url, headers=HTTP_HEADERS).text
        token = re.compile('token.*?"(.*?)"', re.DOTALL + re.IGNORECASE).search(token).group(1)

        # Great the have a ['en','ok','t'].reverse() decurity option in npoplayer.js
        secured = list(token)
        token = list(token)

        first = -1
        second = -1
        for i, c in enumerate(token):
            if c.isdigit() and 4 < i < len(token):
                if first == -1:
                    first = i
                else:
                    second = i
                    break

        if first == -1:
            first = 12
        if second == -1:
            second = 13

        secured[first] = token[second]
        secured[second] = token[first]
        return ''.join(secured)
Esempio n. 5
0
    def _get_streams(self):
        m = self._live_url_re.search(self.page.text)
        playlist_url = m and update_scheme(self.url, m.group(1))
        player_url = self.url
        token = self._get_token()

        if playlist_url:
            log.debug("Found playlist URL in the page")
        else:
            live_channel = None
            for div in itertags(self.page.text, "div"):
                if div.attributes.get("id") == "botonLive":
                    live_channel = div.attributes.get("data-canal")

            if live_channel:
                log.debug("Live channel: {0}".format(live_channel))
                player_url = self._channel_urls[live_channel] + quote(token)
                page = self.session.http.get(player_url,
                                             raise_for_status=False)
                if "block access from your country." in page.text:
                    raise PluginError("Content is geo-locked")
                m = self._playlist_re.search(page.text)
                playlist_url = m and update_scheme(self.url, m.group(1))
            else:
                log.error("Could not find the live channel")

        if playlist_url:
            stream_url = "{0}?{1}".format(playlist_url,
                                          urlencode({"iut": token}))
            return HLSStream.parse_variant_playlist(
                self.session, stream_url, headers={"referer": player_url})
Esempio n. 6
0
    def _location(self, url):

        url = quote(url, safe="%/:=&?~#+!$,;'@()*[]")
        req = self.session.http.get(url,
                                    headers=self.HEADERS,
                                    allow_redirects=False)

        return dict(req.headers).get('Location')
Esempio n. 7
0
    def _get_streams(self):
        headers = {"User-Agent": useragents.CHROME}
        hls_url = http.get(self.url, headers=headers, schema=self._schema)
        headers["Referer"] = self.url

        if self.isVod:
            url = self._url_vod.format(quote(hls_url, safe=""))
            hls_url = http.get(url, headers=headers, schema=self._schema_vod)

        return HLSStream.parse_variant_playlist(self.session, hls_url, headers=headers)
Esempio n. 8
0
    def _get_streams(self):
        hls_url = self.session.http.get(self.url, schema=self._schema)

        if "mediathek" in self.url.lower():
            url = self._url_vod.format(quote(hls_url, safe=""))
            hls_url = self.session.http.get(url, headers={
                "Referer": self.url
            }).url

        return HLSStream.parse_variant_playlist(self.session,
                                                hls_url,
                                                headers={"Referer": self.url})
Esempio n. 9
0
    def login(self, username, password):
        log.debug("Logging in as {0}".format(username))

        redirect_to = "https://home.bt.com/ss/Satellite/secure/loginforward?view=btsport&redirectURL={0}".format(
            quote(self.url))
        data = {
            "cookieExpp": "30",
            "Switch": "yes",
            "SMPostLoginUrl": "/appsyouraccount/secure/postlogin",
            "loginforward":
            "https://home.bt.com/ss/Satellite/secure/loginforward?view=btsport",
            "smauthreason": "0",
            "TARGET": redirect_to,
            "USER": username,
            "PASSWORD": password
        }
        res = self.session.http.post(self.login_url, data=data)

        log.debug("Redirected to: {0}".format(res.url))

        if "loginerror" not in res.text:
            self.logger.debug("Login successful, getting SAML token")
            res = self.session.http.get(
                "https://samlfed.bt.com/sportgetfedwebhls?bt.cid={0}".format(
                    self.acid()))
            d = self.saml_re.search(res.text)
            if d:
                saml_data = d.group(1)
                self.logger.debug("BT Sports federated login...")
                res = self.session.http.post(self.api_url,
                                             params={
                                                 "action": "LoginBT",
                                                 "channel": "WEBHLS",
                                                 "bt.cid": self.acid
                                             },
                                             data={"SAMLResponse": saml_data})
                fed_json = self.session.http.json(res)
                success = fed_json['resultCode'] == "OK"
                if not success:
                    self.logger.error("Failed to login: {0} - {1}".format(
                        fed_json['errorDescription'], fed_json['message']))
                return success
        else:
            return False
    def _get_streams(self):

        headers = {'User-Agent': CHROME}

        self.url = self.url.replace(u'ρικ', quote(u'ρικ'.encode('utf-8')))

        get_page = self.session.http.get(self.url, headers=headers)

        tags = list(itertags(get_page.text, 'script'))

        if 'live-tv' in self.url:

            tag = [i for i in tags if 'm3u8' in i.text][0].text

            try:
                stream = re.search(r'''["'](http.+?\.m3u8)['"]''', tag).group(1)
            except IndexError:
                raise NoStreamsError('RIK Broadcast is currently disabled')

        else:

            tag = [i for i in tags if '.mp4' in i.text and 'sources' in i.text][0].text

            stream = re.search(r'''file: ['"](.+?\.mp4)['"]''', tag).group(1)

        headers.update({"Referer": self.url})

        try:
            parse_hls = bool(strtobool(self.get_option('parse_hls')))
        except AttributeError:
            parse_hls = True

        if parse_hls and 'live-tv' in self.url:
            return HLSStream.parse_variant_playlist(self.session, stream, headers=headers)
        else:
            return dict(stream=HTTPStream(self.session, stream, headers=headers))
Esempio n. 11
0
    def _get_streams(self):
        m = self._live_url_re.search(self.page.text)
        playlist_url = m and update_scheme(self.url, m.group(1))
        player_url = self.url
        live_channel = None
        p = urlparse(player_url)
        channelnumber = 0
        if p.netloc.endswith("tvc.com.ec"):
            live_channel = "Canal5"
        elif p.netloc.endswith("rts.com.ec"):
            live_channel = "Guayaquil"
        elif p.netloc.endswith("atv.pe"):
            if p.path.endswith(("ATVMas", "ATVMas/")):
                live_channel = "ATVMas"
                channelnumber = 1
            else:
                live_channel = "ATV"
        token = self._get_token(channelnumber)
        log.debug("token {0}".format(token))
        if playlist_url:
            log.debug("Found playlist URL in the page")
        else:
            if live_channel:
                log.debug("Live channel: {0}".format(live_channel))
                player_url = self._channel_urls[live_channel] + quote(token)
                page = self.session.http.get(player_url, raise_for_status=False)
                if "block access from your country." in page.text:
                    raise PluginError("Content is geo-locked")
                m = self._playlist_re.search(page.text)
                playlist_url = m and update_scheme(self.url, m.group(1))
            else:
                log.error("Could not find the live channel")

        if playlist_url:
            stream_url = "{0}?{1}".format(playlist_url, urlencode({"iut": token}))
            return HLSStream.parse_variant_playlist(self.session, stream_url, headers={"referer": player_url})
Esempio n. 12
0
    def _get_streams(self):
        match = _url_re.match(self.url)
        channel = match.group("channel")

        res = http.get(self.url)

        try:
            channel = int(channel)
        except ValueError:
            channel = _room_id_re.search(res.text).group(1)
            ts = int(time.time())
            url = ROOM_API_V2.format(channel, ts)
            res = http.get(url)

        try:
            status = _status_re.search(res.text).group(1)
            room_key = _room_key_re.search(res.text).group(1)
            hostid = _hostid_re.search(res.text).group(1)
            param = _param_re.search(res.text).group(1)
            tt = _time_re.search(res.text).group(1)
            sign = _sign_re.search(res.text).group(1)
            sd = _sd_re.search(res.text).group(1)
            hd = _hd_re.search(res.text).group(1)
            od = _od_re.search(res.text).group(1)
        except AttributeError:
            self.logger.info("Not a valid room url.")
            return

        if status != '2':
            self.logger.info("Stream currently unavailable.")
            return

        ts = int(time.time())
        param = param.replace("\\", "")
        param = quote(param)
        url = ROOM_API.format(hostid, channel, room_key, ts, param, tt, sign)
        room = http.get(url)
        data = http.json(room, schema=_room_schema)
        if not isinstance(data, dict):
            self.logger.info("Please Check PandaTV Room API")
            return

        videoinfo = data.get('videoinfo')
        plflag_list = videoinfo.get('plflag_list')
        if not videoinfo or not plflag_list:
            self.logger.info("Please Check PandaTV Room API")
            return

        streams = {}
        plflag = videoinfo.get('plflag')
        if not plflag or '_' not in plflag:
            self.logger.info("Please Check PandaTV Room API")
            return

        plflag_list = json.loads(plflag_list)
        backup = plflag_list["backup"]
        rid = plflag_list["auth"]["rid"]
        sign = plflag_list["auth"]["sign"]
        ts = plflag_list["auth"]["time"]

        backup.append(plflag)
        plflag0 = backup
        plflag0 = [i.split('_')[1] for i in plflag0]

        # let wangsu cdn priority, flag can see here in "H5PLAYER_CDN_LINES":
        # https://www.panda.tv/cmstatic/global-config.js
        lines = ["3", "4"]
        try:
            plflag1 = [i for i in plflag0 if i in lines][0]
        except IndexError:
            plflag1 = plflag0[0]

        if sd == '1':
            streams['ehq'] = HTTPStream(self.session, SD_URL_PATTERN.format(plflag1, room_key, sign, ts, rid))

        if hd == '1':
            streams['hq'] = HTTPStream(self.session, HD_URL_PATTERN.format(plflag1, room_key, sign, ts, rid))

        if od == '1':
            streams['sq'] = HTTPStream(self.session, OD_URL_PATTERN.format(plflag1, room_key, sign, ts, rid))

        return streams
Esempio n. 13
0
    def login(self, username, password):
        log.debug("Logging in as {0}".format(username))

        redirect_to = "https://home.bt.com/ss/Satellite/secure/loginforward?view=btsport&redirectURL={0}".format(quote(self.url))
        data = {
            "cookieExpp": "30",
            "Switch": "yes",
            "SMPostLoginUrl": "/appsyouraccount/secure/postlogin",
            "loginforward": "https://home.bt.com/ss/Satellite/secure/loginforward?view=btsport",
            "smauthreason": "0",
            "TARGET": redirect_to,
            "USER": username,
            "PASSWORD": password}
        res = self.session.http.post(self.login_url, data=data)

        log.debug("Redirected to: {0}".format(res.url))

        if "loginerror" not in res.text:
            self.logger.debug("Login successful, getting SAML token")
            res = self.session.http.get("https://samlfed.bt.com/sportgetfedwebhls?bt.cid={0}".format(self.acid()))
            d = self.saml_re.search(res.text)
            if d:
                saml_data = d.group(1)
                self.logger.debug("BT Sports federated login...")
                res = self.session.http.post(self.api_url,
                                params={"action": "LoginBT", "channel": "WEBHLS", "bt.cid": self.acid},
                                data={"SAMLResponse": saml_data})
                fed_json = self.session.http.json(res)
                success = fed_json['resultCode'] == "OK"
                if not success:
                    self.logger.error("Failed to login: {0} - {1}".format(fed_json['errorDescription'],
                                                                          fed_json['message']))
                return success
        else:
            return False
Esempio n. 14
0
    def _get_streams(self):
        if self.response is None:
            infos = self.session.http.get(self.url, schema=self._ctcomp_schema)
        else:
            infos = self.session.http.json(self.response,
                                           schema=self._ctcomp_schema)
        if not infos:
            # playlist infos not found
            raise PluginError('Cannot find playlist infos!')

        vod_prio = len(infos) == 2
        for info in infos:
            try:
                pl = info['ctcomp-data']['source']['playlist'][0]
            except KeyError:
                raise PluginError('Cannot find playlist info!')

            pl = self._playlist_info_schema.validate(pl)
            if vod_prio and pl['type'] != 'VOD':
                continue

            log.trace('{0!r}'.format(info))
            if pl['type'] == 'LIVE':
                data = {
                    "contentType":
                    "live",
                    "items": [{
                        "id": pl["id"],
                        "assetId": pl["assetId"],
                        "key": pl["key"],
                        "playerType": "dash",
                        "date": pl["date"],
                        "requestSource": pl["requestSource"],
                        "drm": pl["drm"],
                        "quality": pl["quality"],
                    }]
                }
            elif pl['type'] == 'VOD':
                data = {
                    "contentType":
                    "vod",
                    "items": [{
                        "id": pl["id"],
                        "key": pl["key"],
                        "playerType": "dash",
                        "date": pl["date"],
                        "requestSource": pl["requestSource"],
                        "drm": pl["drm"],
                        "canBePlay": pl["canBePlay"],
                        "quality": pl["quality"],
                        "region": pl["region"]
                    }]
                }

        headers = {
            "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
        }

        data = json.dumps(data)
        response = self.session.http.post(self._player_api,
                                          data="data={}".format(quote(data)),
                                          headers=headers)
        json_data = self.session.http.json(response,
                                           schema=self._playlist_schema)
        log.trace('{0!r}'.format(json_data))
        playlist = json_data['RESULT']['playlist'][0]['streamUrls']['main']
        for s in DASHStream.parse_manifest(self.session, playlist).items():
            yield s
Esempio n. 15
0
    def _get_streams(self):
        # Get domain name
        self.domain = _url_re.match(self.url).group('domain')

        # Set header data for user-agent
        hdr = {'User-Agent': USER_AGENT.format('sv_SE')}

        # Parse video ID from data received from supplied URL
        res = http.get(self.url, headers=hdr).text
        match = _videoid_re.search(res)
        if not match:   # Video ID not found
            self.logger.error('Failed to parse video ID')
            return {}
        videoId = match.group('id')

        # Get data from general API to validate that stream is playable
        res = http.get(GENERAL_API_URL.format(self.domain, videoId), headers=hdr)
        data = http.json(res, schema=_api_schema)
        if not data['data']:                # No data item found
            self.logger.error('Unable to find "data" item in general API response')
            return {}
        if not self._is_playable(data):    # Stream not playable
            self.logger.error('Stream is not playable (Premium or DRM-protected content)')
            return {}

        # Get geo data, validate and form cookie consisting of
        # geo data + expiry timestamp (current time + 1 hour)
        res = http.get(GEO_DATA_URL.format(self.domain), headers=hdr)
        geo = http.json(res, schema=_geo_schema)
        timestamp = (int(time.time()) + 3600) * 1000
        cookie = 'dsc-geo=%s' % quote('{"countryCode":"%s","expiry":%s}' % (geo, timestamp))

        # Append cookie to headers
        hdr['Cookie'] = cookie

        # Get available streams using stream API
        try:
            res = http.get(STREAM_API_URL.format(self.domain, videoId, 'hls'),
                           headers=hdr, verify=False)
            data = http.json(res, schema=_media_schema)
            media = data.copy()
            res = http.get(STREAM_API_URL.format(self.domain, videoId, 'hds'),
                           headers=hdr, verify=False)
            data = http.json(res, schema=_media_schema)
            media.update(data)
        except PluginError as err:      # Likely geo-restricted
            if any(e in str(err) for e in ('401 Client Error',
                                           '403 Client Error')):
                self.logger.error('Failed to access stream API, '
                                  'may be due to geo-restriction')
                raise NoStreamsError(self.url)
            else:
                raise

        # Reformat data into list with stream format and url
        streams = [{'format': k, 'url': media[k]} for k in media]

        # Create mapper for supported stream types (HLS/HDS)
        mapper = StreamMapper(cmp=lambda type, video: video['format'] == type)
        mapper.map('hls', self._create_streams, HLSStream.parse_variant_playlist)
        mapper.map('hds', self._create_streams, HDSStream.parse_manifest)

        # Feed stream data to mapper and return all streams found
        return mapper(streams)
Esempio n. 16
0
    def _get_streams(self):
        # Get domain name
        self.domain = _url_re.match(self.url).group('domain')

        # Set header data for user-agent
        hdr = {'User-Agent': USER_AGENT.format('sv_SE')}

        # Parse video ID from data received from supplied URL
        res = http.get(self.url, headers=hdr).text
        match = _videoid_re.search(res)
        if not match:  # Video ID not found
            self.logger.error('Failed to parse video ID')
            return {}
        videoId = match.group('id')

        # Get data from general API to validate that stream is playable
        res = http.get(GENERAL_API_URL.format(self.domain, videoId),
                       headers=hdr)
        data = http.json(res, schema=_api_schema)
        if not data['data']:  # No data item found
            self.logger.error(
                'Unable to find "data" item in general API response')
            return {}
        if not self._is_playable(data):  # Stream not playable
            self.logger.error(
                'Stream is not playable (Premium or DRM-protected content)')
            return {}

        # Get geo data, validate and form cookie consisting of
        # geo data + expiry timestamp (current time + 1 hour)
        res = http.get(GEO_DATA_URL.format(self.domain), headers=hdr)
        geo = http.json(res, schema=_geo_schema)
        timestamp = (int(time.time()) + 3600) * 1000
        cookie = 'dsc-geo=%s' % quote('{"countryCode":"%s","expiry":%s}' %
                                      (geo, timestamp))

        # Append cookie to headers
        hdr['Cookie'] = cookie

        # Get available streams using stream API
        try:
            res = http.get(STREAM_API_URL.format(self.domain, videoId, 'hls'),
                           headers=hdr,
                           verify=False)
            data = http.json(res, schema=_media_schema)
            media = data.copy()
            res = http.get(STREAM_API_URL.format(self.domain, videoId, 'hds'),
                           headers=hdr,
                           verify=False)
            data = http.json(res, schema=_media_schema)
            media.update(data)
        except PluginError as err:  # Likely geo-restricted
            if any(e in str(err)
                   for e in ('401 Client Error', '403 Client Error')):
                self.logger.error('Failed to access stream API, '
                                  'may be due to geo-restriction')
                raise NoStreamsError(self.url)
            else:
                raise

        # Reformat data into list with stream format and url
        streams = [{'format': k, 'url': media[k]} for k in media]

        # Create mapper for supported stream types (HLS/HDS)
        mapper = StreamMapper(cmp=lambda type, video: video['format'] == type)
        mapper.map('hls', self._create_streams,
                   HLSStream.parse_variant_playlist)
        mapper.map('hds', self._create_streams, HDSStream.parse_manifest)

        # Feed stream data to mapper and return all streams found
        return mapper(streams)
Esempio n. 17
0
    def _get_streams(self):
        match = _url_re.match(self.url)
        prefix = match.group("prefix")
        channel = match.group("channel")

        res = http.get(self.url)

        if prefix == 'xingyan.':
            roominfo = _roominfo_re.search(res.text).group(1)
            roominfo = json.loads(roominfo)
            videoinfo = roominfo['videoinfo']
            if videoinfo['hlsurl']:
                yield 'source', HLSStream(self.session, videoinfo['hlsurl'])

            #wangsu cdn prior to others, wangsu = 0, alicloud = 1, qcloud = videoinfo['streamurl']
            _cdn = 0
            if videoinfo['zl'][_cdn]['streamurl']:
                yield 'source', HTTPStream(self.session, videoinfo['zl'][_cdn]['streamurl'])
            if videoinfo['zl'][_cdn]['streamtrans']['mid']:
                yield 'medium', HTTPStream(self.session, videoinfo['zl'][_cdn]['streamtrans']['mid'])
            if videoinfo['zl'][_cdn]['streamtrans']['small']:
                yield 'low', HTTPStream(self.session, videoinfo['zl'][_cdn]['streamtrans']['small'])
            return

        try:
            channel = int(channel)
        except ValueError:
            channel = _room_id_re.search(res.text).group(1)

        ts = int(time.time())
        url = ROOM_API_V2.format(channel, ts)
        res = http.get(url)

        try:
            status = _status_re.search(res.text).group(1)
            room_key = _room_key_re.search(res.text).group(1)
            hostid = _hostid_re.search(res.text).group(1)
            param = _param_re.search(res.text).group(1)
            tt = _time_re.search(res.text).group(1)
            sign = _sign_re.search(res.text).group(1)
            sd = _sd_re.search(res.text).group(1)
            hd = _hd_re.search(res.text).group(1)
            od = _od_re.search(res.text).group(1)
        except AttributeError:
            self.logger.info("Not a valid room url.")
            return

        if status != '2':
            self.logger.info("Stream currently unavailable.")
            return

        ts = int(time.time())
        param = param.replace("\\", "")
        param = quote(param)
        url = ROOM_API.format(hostid, channel, room_key, ts, param, tt, sign)
        room = http.get(url)
        data = http.json(room, schema=_room_schema)
        if not isinstance(data, dict):
            self.logger.info("Please Check PandaTV Room API")
            return

        videoinfo = data.get('videoinfo')
        plflag_list = videoinfo.get('plflag_list')
        if not videoinfo or not plflag_list:
            self.logger.info("Please Check PandaTV Room API")
            return

        plflag = videoinfo.get('plflag')
        if not plflag or '_' not in plflag:
            self.logger.info("Please Check PandaTV Room API")
            return

        plflag_list = json.loads(plflag_list)
        backup = plflag_list["backup"]
        rid = plflag_list["auth"]["rid"]
        sign = plflag_list["auth"]["sign"]
        ts = plflag_list["auth"]["time"]

        backup.append(plflag)
        plflag0 = backup
        plflag0 = [i.split('_')[1] for i in plflag0]

        # let wangsu cdn priority, flag can see here in "H5PLAYER_CDN_LINES":
        # https://www.panda.tv/cmstatic/global-config.js
        lines = ["3", "4"]
        try:
            plflag1 = [i for i in plflag0 if i in lines][0]
        except IndexError:
            plflag1 = plflag0[0]

        if sd == '1':
            yield 'source', HTTPStream(self.session, SD_URL_PATTERN.format(plflag1, room_key, sign, ts, rid))

        if hd == '1':
            yield 'medium', HTTPStream(self.session, HD_URL_PATTERN.format(plflag1, room_key, sign, ts, rid))

        if od == '1':
            yield 'low', HTTPStream(self.session, OD_URL_PATTERN.format(plflag1, room_key, sign, ts, rid))

        return