예제 #1
0
    def _get_streams(self):
        streams = {}

        # streaming.media.ccc.de
        match = _url_streaming_media_re.match(self.url)
        if match:
            query_url = API_URL_STREAMING_MEDIA
            live_streams = parse_streaming_media_json(get_json(query_url),\
                                                      match.group('room'))

            for stream_name, stream_url in live_streams.items():
                if re.search(r"m3u8", live_streams[stream_name]):
                    streams[stream_name] = HLSStream(self.session,\
                                                        stream_url)
                else:
                    streams[stream_name] = HTTPStream(self.session,\
                                                        stream_url)

        # media.ccc.de
        elif _url_media_re.search(self.url):
            event_id = get_event_id(self.url)
            query_url = "%s/public/events/%i" % (API_URL_MEDIA, event_id)
            recordings = parse_media_json(get_json(query_url))

            for name, stream_url in recordings.items():
                streams[name] = HTTPStream(self.session, stream_url)

        if not streams:
            raise PluginError("This plugin does not support your "
                              "selected video.")

        return streams
예제 #2
0
    def _create_video_clip(self, chunks, start_offset, stop_offset):
        playlist_duration = stop_offset - start_offset
        playlist_offset = 0
        playlist_streams = []
        playlist_tags = []

        for chunk in chunks:
            chunk_url = chunk["url"]
            chunk_length = chunk["length"]
            chunk_start = playlist_offset
            chunk_stop = chunk_start + chunk_length
            chunk_stream = HTTPStream(self.session, chunk_url)

            if chunk_start <= start_offset <= chunk_stop:
                try:
                    headers = extract_flv_header_tags(chunk_stream)
                except IOError as err:
                    raise StreamError("Error while parsing FLV: {0}", err)

                if not headers.metadata:
                    raise StreamError("Missing metadata tag in the first chunk")

                metadata = headers.metadata.data.value
                keyframes = metadata.get("keyframes")

                if not keyframes:
                    if chunk["upkeep"] == "fail":
                        raise StreamError("Unable to seek into muted chunk, try another timestamp")
                    else:
                        raise StreamError("Missing keyframes info in the first chunk")

                keyframe_offset = None
                keyframe_offsets = keyframes.get("filepositions")
                keyframe_times = [playlist_offset + t for t in keyframes.get("times")]
                for time, offset in zip(keyframe_times, keyframe_offsets):
                    if time > start_offset:
                        break

                    keyframe_offset = offset

                if keyframe_offset is None:
                    raise StreamError("Unable to find a keyframe to seek to "
                                      "in the first chunk")

                chunk_headers = dict(Range="bytes={0}-".format(int(keyframe_offset)))
                chunk_stream = HTTPStream(self.session, chunk_url,
                                          headers=chunk_headers)
                playlist_streams.append(chunk_stream)
                for tag in headers:
                    playlist_tags.append(tag)
            elif start_offset <= chunk_start < stop_offset:
                playlist_streams.append(chunk_stream)

            playlist_offset += chunk_length

        return FLVPlaylist(self.session, playlist_streams,
                           tags=playlist_tags, duration=playlist_duration)
예제 #3
0
    def _get_streams(self):
        match = _url_re.match(self.url)
        channel = match.group("channel")

        http.headers.update({'User-Agent': USER_AGENT})
        http.verify = False
        http.mount('https://', HTTPAdapter(max_retries=99))

        #Thanks to @ximellon for providing method.
        try:
            channel = int(channel)
        except ValueError:
            channel = http.get(self.url, schema=_room_id_schema)
            if channel == 0:
                channel = http.get(self.url, schema=_room_id_alt_schema)

        res = http.get(MAPI_URL.format(channel))
        room = http.json(res, schema=_room_schema)
        if not room:
            return

        if room["show_status"] != SHOW_STATUS_ONLINE:
            return

        ts = int(time.time() / 60)
        did = uuid.uuid4().hex.upper()
        sign = hashlib.md5(
            ("{0}{1}{2}{3}".format(channel, did, LAPI_SECRET,
                                   ts)).encode("utf-8")).hexdigest()

        data = {"cdn": "ws", "rate": "0", "tt": ts, "did": did, "sign": sign}

        res = http.post(LAPI_URL.format(channel), data=data)
        room = http.json(res, schema=_lapi_schema)

        url = "{room[rtmp_url]}/{room[rtmp_live]}".format(room=room)
        stream = HTTPStream(self.session, url)
        yield "source", stream

        data = {"cdn": "ws", "rate": "2", "tt": ts, "did": did, "sign": sign}

        res = http.post(LAPI_URL.format(channel), data=data)
        room = http.json(res, schema=_lapi_schema)

        url = "{room[rtmp_url]}/{room[rtmp_live]}".format(room=room)
        stream = HTTPStream(self.session, url)
        yield "middle", stream

        data = {"cdn": "ws", "rate": "1", "tt": ts, "did": did, "sign": sign}

        res = http.post(LAPI_URL.format(channel), data=data)
        room = http.json(res, schema=_lapi_schema)

        url = "{room[rtmp_url]}/{room[rtmp_live]}".format(room=room)
        stream = HTTPStream(self.session, url)
        yield "low", stream
예제 #4
0
    def _get_streams(self):
        info = self._get_stream_info(self.url)
        if not info:
            return

        formats = info.get("fmt_list")
        streams = {}
        protected = False
        for stream_info in info.get("url_encoded_fmt_stream_map", []):
            if stream_info.get("s"):
                protected = True
                continue

            stream = HTTPStream(self.session, stream_info["url"])
            name = formats.get(stream_info["itag"]) or stream_info["quality"]

            if stream_info.get("stereo3d"):
                name += "_3d"

            streams[name] = stream

        # Extract audio streams from the DASH format list
        for stream_info in info.get("adaptive_fmts", []):
            if stream_info.get("s"):
                protected = True
                continue

            stream_type, stream_format = stream_info["type"]
            if stream_type != "audio":
                continue

            stream = HTTPStream(self.session, stream_info["url"])
            name = "audio_{0}".format(stream_format)

            streams[name] = stream

        hls_playlist = info.get("hlsvp")
        if hls_playlist:
            try:
                hls_streams = HLSStream.parse_variant_playlist(
                    self.session,
                    hls_playlist,
                    headers=HLS_HEADERS,
                    namekey="pixels")
                streams.update(hls_streams)
            except IOError as err:
                self.logger.warning("Failed to extract HLS streams: {0}", err)

        if not streams and protected:
            raise AccessDeniedError(
                "This plugin does not support protected videos, "
                "try youtube-dl instead")

        return streams
예제 #5
0
    def _create_playlist_streams(self, videos):
        start_offset = int(videos.get("start_offset", 0))
        stop_offset = int(videos.get("end_offset", 0))
        streams = {}

        for quality, chunks in videos.get("chunks").items():
            if not chunks:
                if videos.get("restrictions", {}).get(quality) == "chansub":
                    self.logger.warning(
                        "The quality '{0}' is not available "
                        "since it requires a subscription.", quality)
                continue

            # Rename 'live' to 'source'
            if quality == "live":
                quality = "source"

            chunks_filtered = list(filter(lambda c: c["url"], chunks))
            if len(chunks) != len(chunks_filtered):
                self.logger.warning(
                    "The video '{0}' contains invalid chunks. "
                    "There will be missing data.", quality)
                chunks = chunks_filtered

            chunks_duration = sum(c.get("length") for c in chunks)

            # If it's a full broadcast we just use all the chunks
            if start_offset == 0 and chunks_duration == stop_offset:
                # No need to use the FLV concat if it's just one chunk
                if len(chunks) == 1:
                    url = chunks[0].get("url")
                    stream = HTTPStream(self.session, url)
                else:
                    chunks = [
                        HTTPStream(self.session, c.get("url")) for c in chunks
                    ]
                    stream = FLVPlaylist(self.session,
                                         chunks,
                                         duration=chunks_duration)
            else:
                try:
                    stream = self._create_video_clip(chunks, start_offset,
                                                     stop_offset)
                except StreamError as err:
                    self.logger.error("Error while creating video '{0}': {1}",
                                      quality, err)
                    continue

            streams[quality] = stream

        return streams
예제 #6
0
    def _get_streams(self):
        res = http.get(self.url)
        match = _info_re.search(res.text)
        if not match:
            return

        info = parse_json(match.group(1), schema=_schema)
        stream_name = info["mode"]
        mp4_url = info.get("mp4_url")
        ios_url = info.get("ios_url")
        swf_url = info.get("swf_url")

        if mp4_url:
            stream = HTTPStream(self.session, mp4_url)
            yield stream_name, stream

        if ios_url:
            if urlparse(ios_url).path.endswith(".m3u8"):
                streams = HLSStream.parse_variant_playlist(
                    self.session, ios_url)
                # TODO: Replace with "yield from" when dropping Python 2.
                for stream in streams.items():
                    yield stream

        if swf_url:
            stream = self._get_rtmp_stream(swf_url)
            if stream:
                yield stream_name, stream
예제 #7
0
    def _get_streams(self):
        match = _url_re.match(self.url)
        videoid = match.group('id')
        
        streams = {}

        # Set header data for user-agent
        hdr = {'User-Agent': USER_AGENT}
        
        # Parse video ID from data received from supplied URL
        res = http.get(VK_VIDEO_URL + videoid.strip(), headers=hdr)

        for match in re.findall(SINGLE_VIDEO_URL, res.text):
            url = match[0].replace("\\/", "/")
            streams[match[2]] = HTTPStream(self.session, url)

        if not streams:
            # try to check is live
            match = VK_LIVE_HASH.search(res.text)
            params = videoid.split('_')

            if match and match.group('hash'):
                url = VK_EXT_URL.format(params[0].replace('video', "").replace('-', ""), params[1], match.group('hash'))
                res = http.get(url, headers=hdr)

                match = SINGLE_HLS_URL.search(res.text)

                if match and match.group('playlist'):
                    hls_streams = HLSStream.parse_variant_playlist(self.session, match.group('playlist').replace("\\/", "/"), namekey="pixels")
                    streams.update(hls_streams)

        return streams
예제 #8
0
    def _get_streams(self):
        self.url = http.resolve_url(self.url)
        match = _url_re.match(self.url)
        parsed = urlparse(self.url)
        if parsed.fragment:
            channel_id = parsed.fragment
        elif parsed.path[:3] == '/v/':
            channel_id = parsed.path.split('/')[-1]
        else:
            channel_id = match.group("channel")

        if not channel_id:
            return

        channel_id = channel_id.lower().replace("/", "_")
        res = http.get(API_URL.format(channel_id))
        info = http.json(res, schema=_schema)

        if not info["success"]:
            return

        if info.get("isLive"):
            name = "live"
        else:
            name = "vod"

        stream = HTTPStream(self.session, info["payload"])
        # Wrap the stream in a FLVPlaylist to verify the FLV tags
        stream = FLVPlaylist(self.session, [stream])

        return {name: stream}
예제 #9
0
    def _get_streams(self):
        # Set header data for user-agent
        hdr = {'User-Agent': USER_AGENT}

        # Parse video ID from data received from supplied URL
        res = http.get(self.url, headers=hdr)

        if not res:
            return {}

        try:
            bs = BeautifulSoup(res.text, "html5lib")
            bs = bs.find('video', {'id': "my-video"})

            if not bs:
                return {}

            src = bs.find('source', {'data-quality': "hd"})

            if not src:
                src = bs.find('video')

            if not src or not src.get('src'):
                return {}

            return {"best": HTTPStream(self.session, src.get('src'))}
        except Exception as e:
            self.logger.error("Failed to decode player params: {0}", e)

            return {}
예제 #10
0
    def _create_stream(self, stream, is_live):
        stream_name = "{0}p".format(stream["height"])
        stream_type = stream["mediaType"]
        stream_url = stream["url"]

        if stream_type in ("hls", "mp4"):
            if urlparse(stream_url).path.endswith("m3u8"):
                try:
                    streams = HLSStream.parse_variant_playlist(
                        self.session, stream_url)

                    # TODO: Replace with "yield from" when dropping Python 2.
                    for stream in streams.items():
                        yield stream
                except IOError as err:
                    self.logger.error("Failed to extract HLS streams: {0}",
                                      err)
            else:
                yield stream_name, HTTPStream(self.session, stream_url)

        elif stream_type == "rtmp":
            params = {
                "rtmp": stream["streamer"],
                "playpath": stream["url"],
                "swfVfy": SWF_URL,
                "pageUrl": self.url,
            }

            if is_live:
                params["live"] = True
            else:
                params["playpath"] = "mp4:{0}".format(params["playpath"])

            stream = RTMPStream(self.session, params)
            yield stream_name, stream
예제 #11
0
    def _get_qq_streams(self, vid):
        res = http.get(QQ_STREAM_INFO_URL % (vid, 1))
        info = http.json(res, schema=_qq_schema)
        yield "live", HTTPStream(self.session, info)

        res = http.get(QQ_STREAM_INFO_URL % (vid, 2))
        info = http.json(res, schema=_qq_schema)
        yield "live_http", HLSStream(self.session, info)
예제 #12
0
 def _get_vod_stream(self):
     """
     Find the VOD video url
     :return: video url
     """
     res = http.get(self.url)
     video_urls = self._re_vod.findall(res.text)
     if len(video_urls):
         return dict(vod=HTTPStream(self.session, video_urls[0]))
예제 #13
0
 def _get_clips(self):
     quality_options = self.api.clip_status(self.channel,
                                            self.clip_name,
                                            schema=_quality_options_schema)
     streams = {}
     for quality_option in quality_options:
         streams[quality_option["quality"]] = HTTPStream(
             self.session, quality_option["source"])
     return streams
예제 #14
0
    def _get_http_streams(self, info):
        name = QUALITY_MAP.get(info["_quality"], "vod")
        urls = info["_stream"]
        if not isinstance(info["_stream"], list):
            urls = [urls]

        for url in urls:
            stream = HTTPStream(self.session, url)
            yield name, stream
예제 #15
0
    def _get_streams(self):
        match = _url_re.match(self.url)
        channel = match.group("channel")

        url = ROOM_API + channel
        res = http.get(url)
        data = http.json(res, schema=_room_schema)
        if not isinstance(data, dict):
            self.logger.error("Please Check PandaTV Room API")
            return

        videoinfo = data.get('videoinfo')

        if not videoinfo or not videoinfo.get('status'):
            self.logger.error("Please Check PandaTV Room API")
            return

        if videoinfo.get('status') != '2':
            self.logger.info("Channel offline now!")
            return

        streams = {}
        plflag = videoinfo.get('plflag')
        if not plflag or not '_' in plflag:
            self.logger.error("Please Check PandaTV Room API")
            return
        plflag = plflag.split('_')[1]
        room_key = videoinfo.get('room_key')

        # SD(Super high Definition) has higher quality than HD(High Definition) which
        # conflict with existing code, use ehq and hq instead.
        stream_addr = videoinfo.get('stream_addr')

        if stream_addr and stream_addr.get('SD') == '1':
            streams['ehq'] = HTTPStream(
                self.session, SD_URL_PATTERN.format(plflag, room_key))

        if stream_addr and stream_addr.get('HD') == '1':
            streams['hq'] = HTTPStream(self.session,
                                       HD_URL_PATTERN.format(plflag, room_key))

        return streams
예제 #16
0
    def _get_streams(self):
        res = http.get(self.url, schema=_schema)
        if not res:
            return

        if res["type"] == "channel" and urlparse(
                res["url"]).path.endswith("m3u8"):
            return HLSStream.parse_variant_playlist(self.session, res["url"])
        elif res["type"] == "video":
            stream = HTTPStream(self.session, res["url"])
            return dict(video=stream)
예제 #17
0
    def _get_source_streams(self):
        res = http.get(self.url)

        streams = {}
        sources = _source_re.findall(res.text)
        for source in sources:
            src = _source_src_re.search(source).group("src")
            pixels = _source_type_re.search(source).group("type")

            streams[pixels] = HTTPStream(self.session, src)

        return streams
예제 #18
0
파일: npo.py 프로젝트: partizand/acestream
    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
예제 #19
0
 def _get_plu_streams(self, cid):
     res = http.get(PLU_STREAM_INFO_URL % cid)
     info = http.json(res, schema=_plu_schema)
     for source in info["urls"]:
         quality = self._get_quality(source["resolution"])
         if source["ext"] == "m3u8":
             yield quality, HLSStream(self.session, source["securityUrl"])
         elif source["ext"] == "flv":
             yield quality, HTTPStream(self.session, source["securityUrl"])
         elif source["ext"] == "rtmp":
             yield quality, RTMPStream(self.session, {
                 "rtmp": source["securityUrl"],
                 "live": True
             })
예제 #20
0
    def _get_recorded_streams(self, video_id):
        if HAS_LIBRTMP:
            recording = self._get_module_info("recorded",
                                              video_id,
                                              schema=_recorded_schema)

            if not isinstance(recording.get("stream"), list):
                return

            for provider in recording["stream"]:
                base_url = provider.get("url")
                for stream_info in provider["streams"]:
                    bitrate = int(stream_info.get("bitrate", 0))
                    stream_name = (bitrate > 0 and "{0}k".format(bitrate)
                                   or "recorded")

                    url = stream_info["streamName"]
                    if base_url:
                        url = base_url + url

                    if url.startswith("http"):
                        yield stream_name, HTTPStream(self.session, url)
                    elif url.startswith("rtmp"):
                        params = dict(rtmp=url, pageUrl=self.url)
                        yield stream_name, RTMPStream(self.session, params)

        else:
            self.logger.warning(
                "The proper API could not be used without python-librtmp "
                "installed. Stream URL is not guaranteed to be valid")

            url = RECORDED_URL.format(video_id)
            random_hash = "{0:02x}{1:02x}".format(randint(0, 255),
                                                  randint(0, 255))
            params = dict(hash=random_hash)
            stream = HTTPStream(self.session, url, params=params)
            yield "recorded", stream
예제 #21
0
    def _get_streams(self):
        res = http.get(self.url, schema=_schema)

        if res["export_url"]:
            return self._get_live_stream(res["export_url"])
        elif res["video_flashvars"]:
            stream = RTMPStream(
                self.session, {
                    "rtmp": res["video_flashvars"]["_111pix_serverURL"],
                    "playpath":
                    res["video_flashvars"]["en_flash_providerName"],
                    "swfVfy": SWF_VIDEO_URL,
                    "pageUrl": self.url
                })
            return dict(video=stream)
        elif res["standby_video"]:
            for stream in res["standby_video"]:
                stream = HTTPStream(self.session, stream["streamName"])
                return dict(replay=stream)
        elif res["history_video"]:
            stream = HTTPStream(self.session, res["history_video"])
            return dict(history=stream)

        return
예제 #22
0
 def _get_streams(self):
     match = _url_re.match(self.url)
     videoid = match.group('videoid')
     get_return = http.get(VIDEO_GET_URL.format(videoid))
     json_decode = http.json(get_return)
     streams = {}
     quality_list = []
     for stream in json_decode:
         if SINGLE_VIDEO_URL.match(stream['direct_url']):
             quality_list.append(int(stream['video_bitrate']))
     if len(quality_list) == 0:
         return
     quality_dict = get_quality_dict(quality_list)
     for stream in json_decode:
         if SINGLE_VIDEO_URL.match(stream['direct_url']):
             streams[quality_dict[stream['video_bitrate']]] = HTTPStream(self.session, stream['direct_url'])
     return streams
예제 #23
0
    def _get_streams(self):
        res = http.get(self.url, schema=_schema)
        streams = {}
        for url in res["urls"]:
            parsed = urlparse(url)
            if parsed.scheme.startswith("rtmp"):
                params = {"rtmp": url, "pageUrl": self.url, "live": True}
                if res["swf"]:
                    params["swfVfy"] = res["swf"]

                stream = RTMPStream(self.session, params)
                streams["live"] = stream
            elif parsed.scheme.startswith("http"):
                name = splitext(parsed.path)[1][1:]
                stream = HTTPStream(self.session, url)
                streams[name] = stream

        return streams
예제 #24
0
 def _get_streams(self):
     res = http.get(self.url)
     match = _streams_re.findall(res.content.decode('utf-8'))
     for url, stream_type in match:
         if stream_type == "rtmp/mp4" and RTMPStream.is_usable(
                 self.session):
             params = {
                 "rtmp": url,
                 "pageUrl": self.url,
                 "live": True,
             }
             yield 'live', RTMPStream(self.session, params)
         elif stream_type == "application/x-mpegURL":
             for s in HLSStream.parse_variant_playlist(self.session,
                                                       url).items():
                 yield s
         elif stream_type == "video/mp4":
             yield 'vod', HTTPStream(self.session, url)
예제 #25
0
    def _create_flv_playlist(self, template):
        res = http.get(template)
        playlist = http.json(res, schema=_vod_playlist_schema)

        parsed = urlparse(template)
        url_template = "{0}://{1}{2}".format(parsed.scheme, parsed.netloc,
                                             playlist["template"])
        segment_max = reduce(lambda i, j: i + j[0], playlist["fragments"], 0)

        substreams = [
            HTTPStream(self.session,
                       url_template.replace("$fragment$", str(i)))
            for i in range(1, segment_max + 1)
        ]

        return FLVPlaylist(self.session,
                           duration=playlist["duration"],
                           flatten_timestamps=True,
                           skip_header=True,
                           streams=substreams)
예제 #26
0
    def _get_streams(self):
        match = self._url_re.match(self.url)
        film_id, episode_id = match.groups()

        headers = {"Referer": self.url, "User-Agent": self._user_agent}

        # Get the info about the Episode, including the Grabber API URL
        info_res = http.get(self._episode_info_url,
                            params=dict(update=0, film=film_id, id=episode_id),
                            headers=headers)
        info = http.json(info_res, schema=self._info_schema)

        # Get the data about the streams from the Grabber API
        stream_list_res = http.get(info["grabber"],
                                   params=info["params"],
                                   headers=headers)
        stream_data = http.json(stream_list_res, schema=self._streams_schema)

        for stream in stream_data["data"]:
            yield stream["label"], HTTPStream(self.session, stream["file"])
예제 #27
0
    def _get_streams(self):
        match = _url_re.match(self.url)
        videoid = match.group('id')

        # Set header data for user-agent
        hdr = {'User-Agent': USER_AGENT}

        # Parse video ID from data received from supplied URL
        res = http.get(self.url, headers=hdr)

        if not res:
            return {}

        for match in re.findall(_direct_url, res.text):
            try:
                return {"original": HTTPStream(self.session, match)}
            except Exception as e:
                self.logger.error("Failed to extract video url: {0}", e)

                return {}
예제 #28
0
    def _get_streams(self):
        match = _url_re.match(self.url)
        channel = match.group("channel")

        html_page = http.get(self.url).content.decode('utf-8')
        room_id = _room_re.search(html_page).group(1)

        ts = int(time.time() / 60)
        sign = hashlib.md5(("{0}{1}".format(channel, API_SECRET,
                                            ts)).encode("utf-8")).hexdigest()

        res = http.get(API_URL.format(room_id, sign))
        room = http.json(res)
        if not room:
            return

        for stream_list in room["durl"]:
            name = "source"
            url = stream_list["url"]
            stream = HTTPStream(self.session, url)
            yield name, stream
예제 #29
0
 def _make_stream(self, url):
     if url and url.endswith("flv"):
         return HTTPStream(self.session, url)
     elif url and url.endswith("m3u8"):
         return HLSStream(self.session, url)
예제 #30
0
    def _get_streams(self):
        streams = {}

        match = _url_re.match(self.url)
        videoid = match.group('id')
        embed_params = match.group('embed_params')

        if not videoid and embed_params:
            query_params = urlparse.parse_qs(embed_params, True)

            if not 'oid' in query_params:
                self.logger.error("missing 'oid'")
                return streams

            if not 'id' in query_params:
                self.logger.error("missing 'id'")
                return streams

            _oid = query_params['oid'][0]
            _id = query_params['id'][0]
            # _hash = query_params['hash'][0]
            videoid = "video%s_%s" % (_oid, _id)

        # Set header data for user-agent
        hdr = {'User-Agent': USER_AGENT}

        # Parse video ID from data received from supplied URL
        res = http.get(VK_VIDEO_URL + videoid.strip(), headers=hdr)

        for match in re.findall(SINGLE_VIDEO_URL, res.text):
            url = match[0].replace("\\/", "/")
            try:
                # follow possible redirects and get final url
                res = http.get(url,
                               headers=hdr,
                               verify=False,
                               allow_redirects=True,
                               stream=True)
                streams[match[2]] = HTTPStream(self.session, res.url)
            except:
                pass

        if not streams:
            # try live
            for match in re.findall(SINGLE_HLS_URL, res.text):
                url = match.replace("\\/", "/")
                streams = {"variant": HLSStream(self.session, url)}
                break

        if not streams:
            # try to check is live
            match = VK_LIVE_HASH.search(res.text)
            params = videoid.split('_')

            if match and match.group('hash'):
                url = VK_EXT_URL.format(
                    params[0].replace('video', "").replace('-', ""), params[1],
                    match.group('hash'))
                res = http.get(url, headers=hdr)

                match = SINGLE_HLS_URL.search(res.text)

                if match and match.group('playlist'):
                    url = match.group('playlist').replace("\\/", "/")
                    streams = {"variant": HLSStream(self.session, url)}

        return streams