Beispiel #1
0
    def _get_streams(self):
        res = http.get(self.url)
        channel_id = self._find_channel_id(res.text)
        if not channel_id:
            return

        stream_id = self._get_stream_id(channel_id)
        if not stream_id:
            return

        res = http.get(STREAM_API_URL.format(stream_id),
                       params=dict(format="all"))
        json = http.json(res)
        data = verifyjson(json, "data")
        items = verifyjson(data, "items")

        streams = {}
        for stream in filter(valid_stream, items):
            parser = STREAM_TYPES[stream["format"]]

            try:
                streams.update(parser(self.session, stream["url"]))
            except IOError as err:
                if not re.search(r"(404|400) Client Error", str(err)):
                    self.logger.error("Failed to extract {0} streams: {1}",
                                      stream["format"].upper(), err)

        return streams
Beispiel #2
0
    def _get_streams(self):
        info = self._get_stream_info(self.url)

        if not info:
            raise NoStreamsError(self.url)

        args = verifyjson(info, "args")

        if not "live_playback" in args or args["live_playback"] == "0":
            raise NoStreamsError(self.url)

        streams = {}

        uestreammap = verifyjson(args, "url_encoded_fmt_stream_map")
        fmtlist = verifyjson(args, "fmt_list")

        streammap = self._parse_stream_map(uestreammap)
        formatmap = self._parse_format_map(fmtlist)

        for streaminfo in streammap:
            if not ("url" in streaminfo and "sig" in streaminfo):
                continue

            stream = HTTPStream(self.session,
                                streaminfo["url"][0],
                                params=dict(signature=streaminfo["sig"][0]))

            if streaminfo["itag"][0] in formatmap:
                quality = formatmap[streaminfo["itag"][0]]
            else:
                quality = streaminfo["quality"]

            streams[quality] = stream

        return streams
Beispiel #3
0
    def _get_streams(self):
        self.logger.debug("Fetching stream info")
        info = self._get_stream_info()

        if not info:
            raise NoStreamsError(self.url)

        streaminfo = verifyjson(info, "stream_info")

        if not streaminfo:
            raise NoStreamsError(self.url)

        qualities = verifyjson(streaminfo, "qualities")

        streams = {}

        if not streaminfo["is_live"]:
            raise NoStreamsError(self.url)

        if "play_url" in streaminfo:
            smil = self._parse_smil(streaminfo["play_url"])

            for bitrate, stream in smil.items():
                sname = "{0}k".format(bitrate / 1000)

                for quality in qualities:
                    if quality["bitrate"] == bitrate:
                        sname = "{0}p".format(quality["height"])

                streams[sname] = stream

        return streams
Beispiel #4
0
    def _get_streams(self):
        self.logger.debug("Fetching stream info")
        res = urlget(self.url, params=dict(output="json"))

        if res.json is None:
            raise PluginError("No JSON data in stream info")

        streams = {}
        video = verifyjson(res.json, "video")
        videos = verifyjson(video, "videoReferences")

        for video in videos:
            if not ("url" in video and "playerType" in video):
                continue

            if video["playerType"] == "flash":
                if video["url"].startswith("rtmp"):
                    stream = RTMPStream(
                        self.session, {
                            "rtmp": video["url"],
                            "pageUrl": self.PageURL,
                            "swfVfy": self.SWFURL,
                            "live": True
                        })
                    streams[str(video["bitrate"]) + "k"] = stream
            elif video["playerType"] == "ios":
                try:
                    hlsstreams = HLSStream.parse_variant_playlist(
                        self.session, video["url"])
                    streams.update(hlsstreams)
                except IOError as err:
                    self.logger.warning("Failed to get variant playlist: {0}",
                                        err)

        return streams
Beispiel #5
0
    def _get_live_streams(self):
        self._authenticate()
        sig, token = self._access_token()
        url = self.usher.select(self.channel,
                                password=self.options.get("password"),
                                nauthsig=sig,
                                nauth=token)

        try:
            streams = HLSStream.parse_variant_playlist(self.session, url)
        except IOError as err:
            err = str(err)
            if "404 Client Error" in err or "Failed to parse playlist" in err:
                return
            else:
                raise PluginError(err)

        try:
            token = parse_json(token)
            chansub = verifyjson(token, "chansub")
            restricted_bitrates = verifyjson(chansub, "restricted_bitrates")

            for name in filter(
                    lambda n: not re.match(r"(.+_)?archives|live", n),
                    restricted_bitrates):
                self.logger.warning(
                    "The quality '{0}' is not available "
                    "since it requires a subscription.", name)
        except PluginError:
            pass

        return dict(starmap(self._check_stream_name, streams.items()))
Beispiel #6
0
    def _get_streams(self):
        self.logger.debug("Fetching stream info")
        res = urlget(self.url, params=dict(output="json"))
        json = res_json(res)

        if not isinstance(json, dict):
            raise PluginError("Invalid JSON response")

        streams = {}
        video = verifyjson(json, "video")
        videos = verifyjson(video, "videoReferences")

        for video in videos:
            if not ("url" in video and "playerType" in video):
                continue

            if video["playerType"] == "flash":
                if video["url"].startswith("rtmp"):
                    stream = RTMPStream(
                        self.session,
                        {"rtmp": video["url"], "pageUrl": self.PageURL, "swfVfy": self.SWFURL, "live": True},
                    )
                    streams[str(video["bitrate"]) + "k"] = stream
            elif video["playerType"] == "ios":
                try:
                    hlsstreams = HLSStream.parse_variant_playlist(self.session, video["url"])
                    streams.update(hlsstreams)
                except IOError as err:
                    self.logger.warning("Failed to get variant playlist: {0}", err)

        return streams
    def _get_live_streams(self):
        self._authenticate()
        sig, token = self._access_token()
        url = self.usher.select(self.channel, password=self.options.get("password"), nauthsig=sig, nauth=token)

        try:
            streams = HLSStream.parse_variant_playlist(self.session, url)
        except ValueError:
            return
        except IOError as err:
            if "404 Client Error" in str(err):
                return
            else:
                raise PluginError(err)

        try:
            token = parse_json(token)
            chansub = verifyjson(token, "chansub")
            restricted_bitrates = verifyjson(chansub, "restricted_bitrates")

            for name in filter(lambda n: n not in ("archives", "live"), restricted_bitrates):
                self.logger.warning("The quality '{0}' is not available " "since it requires a subscription.", name)
        except PluginError:
            pass

        return dict(starmap(self._check_stream_name, streams.items()))
Beispiel #8
0
    def _get_streams(self):
        info = self._get_stream_info(self.url)

        if not info:
            raise NoStreamsError(self.url)

        args = verifyjson(info, "args")

        if not "live_playback" in args or args["live_playback"] == "0":
            raise NoStreamsError(self.url)

        streams = {}

        uestreammap = verifyjson(args, "url_encoded_fmt_stream_map")
        fmtlist = verifyjson(args, "fmt_list")

        streammap = self._parse_stream_map(uestreammap)
        formatmap = self._parse_format_map(fmtlist)

        for streaminfo in streammap:
            if not ("url" in streaminfo and "sig" in streaminfo):
                continue

            stream = HTTPStream(self.session, streaminfo["url"][0],
                                params=dict(signature=streaminfo["sig"][0]))

            if streaminfo["itag"][0] in formatmap:
                quality = formatmap[streaminfo["itag"][0]]
            else:
                quality = streaminfo["quality"]

            streams[quality] = stream

        return streams
Beispiel #9
0
    def _get_streams(self):
        res = http.get(self.url)
        channel_id = self._find_channel_id(res.text)
        if not channel_id:
            return

        stream_id = self._get_stream_id(channel_id)
        if not stream_id:
            return

        res = http.get(STREAM_API_URL.format(stream_id),
                       params=dict(format="all"))
        json = http.json(res)
        data = verifyjson(json, "data")
        items = verifyjson(data, "items")

        streams = {}
        for stream in filter(valid_stream, items):
            parser = STREAM_TYPES[stream["format"]]

            try:
                streams.update(parser(self.session, stream["url"]))
            except IOError as err:
                if not re.search(r"(404|400) Client Error", str(err)):
                    self.logger.error("Failed to extract {0} streams: {1}",
                                      stream["format"].upper(), err)

        return streams
Beispiel #10
0
    def _get_streams(self):
        self.logger.debug("Fetching stream info")
        info = self._get_stream_info()

        if not info:
            raise NoStreamsError(self.url)

        streaminfo = verifyjson(info, "stream_info")

        if not streaminfo:
            raise NoStreamsError(self.url)

        qualities = verifyjson(streaminfo, "qualities")

        streams = {}

        if not streaminfo["is_live"]:
            raise NoStreamsError(self.url)

        if "play_url" in streaminfo:
            smil = self._parse_smil(streaminfo["play_url"])

            for bitrate, stream in smil.items():
                sname = "{0}k".format(bitrate/1000)

                for quality in qualities:
                    if quality["bitrate"] == bitrate:
                        sname = "{0}p".format(quality["height"])

                streams[sname] = stream

        return streams
Beispiel #11
0
    def _get_streams(self):
        info = self._get_stream_info(self.url)

        if not info:
            raise NoStreamsError(self.url)

        args = verifyjson(info, "args")

        streams = {}

        uestreammap = verifyjson(args, "url_encoded_fmt_stream_map")
        fmtlist = verifyjson(args, "fmt_list")

        streammap = self._parse_stream_map(uestreammap)
        formatmap = self._parse_format_map(fmtlist)

        for streaminfo in streammap:
            if "s" in streaminfo and self._decrypt_signature(streaminfo["s"]):
                streaminfo["sig"] = self._decrypt_signature(streaminfo["s"])

            if not ("url" in streaminfo and "sig" in streaminfo):
                continue

            stream = HTTPStream(self.session,
                                streaminfo["url"],
                                params=dict(signature=streaminfo["sig"]))

            if streaminfo["itag"] in formatmap:
                quality = formatmap[streaminfo["itag"]]
            else:
                quality = streaminfo["quality"]

            if streaminfo.get("stereo3d") == "1":
                quality += "_3d"

            streams[quality] = stream

        if "hlsvp" in args:
            url = args["hlsvp"]

            try:
                hlsstreams = HLSStream.parse_variant_playlist(self.session,
                                                              url,
                                                              namekey="pixels")
                streams.update(hlsstreams)
            except IOError as err:
                self.logger.warning("Failed to get variant playlist: {0}", err)

        if not streams and args.get("live_playback", "0") == "0":
            self.logger.warning(
                "VOD support may not be 100% complete. Try youtube-dl instead."
            )

        return streams
Beispiel #12
0
    def _get_streams(self):
        info = self._get_stream_info(self.url)

        if not info:
            raise NoStreamsError(self.url)

        args = verifyjson(info, "args")

        streams = {}

        uestreammap = verifyjson(args, "url_encoded_fmt_stream_map")
        fmtlist = verifyjson(args, "fmt_list")

        streammap = self._parse_stream_map(uestreammap)
        formatmap = self._parse_format_map(fmtlist)

        for streaminfo in streammap:
            if "s" in streaminfo and self._decrypt_signature(streaminfo["s"]):
                streaminfo["sig"] = self._decrypt_signature(streaminfo["s"])

            if not ("url" in streaminfo and "sig" in streaminfo):
                continue

            stream = HTTPStream(self.session, streaminfo["url"],
                                params=dict(signature=streaminfo["sig"]))

            if streaminfo["itag"] in formatmap:
                quality = formatmap[streaminfo["itag"]]
            else:
                quality = streaminfo["quality"]

            if streaminfo.get("stereo3d") == "1":
                quality += "_3d"

            streams[quality] = stream

        if "hlsvp" in args:
            url = args["hlsvp"]

            try:
                hlsstreams = HLSStream.parse_variant_playlist(self.session, url,
                                                              namekey="pixels")
                streams.update(hlsstreams)
            except IOError as err:
                self.logger.warning("Failed to get variant playlist: {0}", err)

        if not streams and args.get("live_playback", "0") == "0":
            self.logger.warning("VOD support may not be 100% complete. Try youtube-dl instead.")

        return streams
Beispiel #13
0
    def _get_hls_streams(self):
        url = self.HLSStreamTokenURL.format(self.channelname)

        try:
            res = urlget(url, params=dict(type="any", connection="wifi"),
                         exception=IOError)
        except IOError:
            self.logger.debug("HLS streams not available")
            return {}

        json = res_json(res, "stream token JSON")

        if not isinstance(json, list):
            raise PluginError("Invalid JSON response")

        if len(json) == 0:
            raise PluginError("No stream token in JSON")

        streams = {}

        token = verifyjson(json[0], "token")
        hashed = hmac.new(self.HLSStreamTokenKey, bytes(token, "utf8"), sha1)
        fulltoken = hashed.hexdigest() + ":" + token
        url = self.HLSSPlaylistURL.format(self.channelname)

        try:
            params = dict(token=fulltoken, hd="true")
            playlist = HLSStream.parse_variant_playlist(self.session, url,
                                                        params=params)
        except IOError as err:
            raise PluginError(err)

        return playlist
Beispiel #14
0
    def _get_hls_streams(self):
        url = self.HLSStreamTokenURL.format(self.channelname)

        try:
            res = urlget(url, params=dict(type="any", connection="wifi"),
                         exception=IOError)
        except IOError:
            return {}

        if not isinstance(res.json, list):
            raise PluginError("Stream info response is not JSON")

        if len(res.json) == 0:
            raise PluginError("No stream token in JSON")

        streams = {}

        token = verifyjson(res.json[0], "token")
        hashed = hmac.new(self.HLSStreamTokenKey, bytes(token, "utf8"), sha1)
        fulltoken = hashed.hexdigest() + ":" + token
        url = self.HLSSPlaylistURL.format(self.channelname)

        try:
            params = dict(token=fulltoken, hd="true")
            playlist = HLSStream.parse_variant_playlist(self.session, url,
                                                        params=params)
        except IOError as err:
            raise PluginError(err)

        return playlist
Beispiel #15
0
    def _get_streams_from_id(self, stream_id):
        res = urlget(CONFIG_URL, params=dict(id=stream_id))
        config = res_json(res)
        media = verifyjson(config, "media")

        if not (media and isinstance(media, list)):
            return

        streams = {}
        media = media[0]
        hds_manifest = media.get("name")
        hls_manifest = media.get("hlsUrl")

        if hds_manifest:
            try:
                hds_streams = HDSStream.parse_manifest(self.session,
                                                       hds_manifest)
                streams.update(hds_streams)
            except IOError as err:
                if not re.search(r"(404|400) Client Error", str(err)):
                    self.logger.error("Failed to parse HDS manifest: {0}", err)

        if hls_manifest:
            try:
                hls_streams = HLSStream.parse_variant_playlist(self.session,
                                                               hls_manifest,
                                                               nameprefix="mobile_")
                streams.update(hls_streams)
            except IOError as err:
                if not re.search(r"(404|400) Client Error", str(err)):
                    self.logger.error("Failed to parse HLS playlist: {0}", err)

        return streams
Beispiel #16
0
    def _get_streams(self):
        match = re.search("/v/(\d+)", self.url)
        if not match:
            return

        vid = match.group(1)
        params = dict(client_name="Bambuser AS2",
                      context="b_broadcastpage",
                      raw_user_input=1,
                      api_key="005f64509e19a868399060af746a00aa",
                      vid=vid,
                      r=random.random())

        self.logger.debug("Fetching stream info")
        res = http.get(PLAYER_URL, params=params)
        json = http.json(res)

        error = json and json.get("errorCode")
        if error:
            error = error and json.get("error")
            self.logger.error(error)
            return

        json = verifyjson(json, "result")
        playpath = verifyjson(json, "id")
        url = verifyjson(json, "url")
        (width, height) = verifyjson(json, "size").split("x")
        name = "{0}p".format(height)

        parsed = urlparse(url)
        streams = {}

        if parsed.scheme.startswith("rtmp"):
            if not RTMPStream.is_usable(self.session):
                raise PluginError(
                    "rtmpdump is not usable and required by Bambuser plugin")
            streams[name] = RTMPStream(
                self.session, {
                    "rtmp": url,
                    "playpath": playpath,
                    "pageUrl": self.url,
                    "live": True
                })
        elif parsed.scheme == "http":
            streams[name] = HTTPStream(self.session, url)

        return streams
Beispiel #17
0
    def _get_streams(self):
        self.logger.debug("Fetching stream info")
        res = http.get(self.url, params=dict(output="json"))
        json = http.json(res)

        if not isinstance(json, dict):
            raise PluginError("Invalid JSON response")

        streams = {}
        video = verifyjson(json, "video")
        videos = verifyjson(video, "videoReferences")

        for video in videos:
            if not ("url" in video and "playerType" in video):
                continue

            url = video["url"]

            if video["playerType"] == "flash":
                if url.startswith("rtmp"):
                    stream = RTMPStream(
                        self.session, {
                            "rtmp": url,
                            "pageUrl": PAGE_URL,
                            "swfVfy": SWF_URL,
                            "live": True
                        })
                    streams[str(video["bitrate"]) + "k"] = stream
                elif "manifest.f4m" in url:
                    try:
                        hdsstreams = HDSStream.parse_manifest(
                            self.session, url)
                        streams.update(hdsstreams)
                    except IOError as err:
                        self.logger.warning("Failed to get HDS manifest: {0}",
                                            err)

            elif video["playerType"] == "ios":
                try:
                    hlsstreams = HLSStream.parse_variant_playlist(
                        self.session, url)
                    streams.update(hlsstreams)
                except IOError as err:
                    self.logger.warning("Failed to get variant playlist: {0}",
                                        err)

        return streams
Beispiel #18
0
    def _get_streams(self):
        info = self._get_stream_info(self.url)

        if not info:
            raise NoStreamsError(self.url)

        args = verifyjson(info, "args")

        if not "live_playback" in args or args["live_playback"] == "0":
            raise NoStreamsError(self.url)

        streams = {}

        uestreammap = verifyjson(args, "url_encoded_fmt_stream_map")
        fmtlist = verifyjson(args, "fmt_list")

        streammap = self._parse_stream_map(uestreammap)
        formatmap = self._parse_format_map(fmtlist)

        for streaminfo in streammap:
            if not ("url" in streaminfo and "sig" in streaminfo):
                continue

            stream = HTTPStream(self.session,
                                streaminfo["url"],
                                params=dict(signature=streaminfo["sig"]))

            if streaminfo["itag"] in formatmap:
                quality = formatmap[streaminfo["itag"]]
            else:
                quality = streaminfo["quality"]

            streams[quality] = stream

        if "hlsvp" in args:
            url = args["hlsvp"]

            try:
                hlsstreams = HLSStream.parse_variant_playlist(
                    self.session, url)
                streams.update(hlsstreams)
            except IOError as err:
                self.logger.warning("Failed to get variant playlist: {0}", err)

        return streams
Beispiel #19
0
    def _check_channel_live(self, channelname):
        url = self.MetadataURL.format(channelname)
        res = urlget(url, params=dict(fields="mode"))

        if len(res.json) == 0:
            raise PluginError("Error retrieving stream live status")

        mode = verifyjson(res.json, "mode")

        return mode == "live"
Beispiel #20
0
    def _check_channel_live(self, channelname):
        url = self.MetadataURL.format(channelname)
        res = urlget(url, params=dict(fields="mode"))

        if len(res.json) == 0:
            raise PluginError("Error retrieving stream live status")

        mode = verifyjson(res.json, "mode")

        return mode == "live"
Beispiel #21
0
    def _get_streams(self):
        info = self._get_stream_info(self.url)

        if not info:
            raise NoStreamsError(self.url)

        args = verifyjson(info, "args")

        if not "live_playback" in args or args["live_playback"] == "0":
            raise NoStreamsError(self.url)

        streams = {}

        uestreammap = verifyjson(args, "url_encoded_fmt_stream_map")
        fmtlist = verifyjson(args, "fmt_list")

        streammap = self._parse_stream_map(uestreammap)
        formatmap = self._parse_format_map(fmtlist)

        for streaminfo in streammap:
            if not ("url" in streaminfo and "sig" in streaminfo):
                continue

            stream = HTTPStream(self.session, streaminfo["url"],
                                params=dict(signature=streaminfo["sig"]))

            if streaminfo["itag"] in formatmap:
                quality = formatmap[streaminfo["itag"]]
            else:
                quality = streaminfo["quality"]

            streams[quality] = stream

        if "hlsvp" in args:
            url = args["hlsvp"]

            try:
                hlsstreams = HLSStream.parse_variant_playlist(self.session, url)
                streams.update(hlsstreams)
            except IOError as err:
                self.logger.warning("Failed to get variant playlist: {0}", err)

        return streams
Beispiel #22
0
    def _get_streams(self):
        match = re.search("/v/(\d+)", self.url)
        if not match:
            return

        vid = match.group(1)
        params = dict(client_name="Bambuser AS2", context="b_broadcastpage",
                      raw_user_input=1, api_key="005f64509e19a868399060af746a00aa",
                      vid=vid, r=random.random())

        self.logger.debug("Fetching stream info")
        res = http.get(PLAYER_URL, params=params)
        json = http.json(res)

        error = json and json.get("errorCode")
        if error:
            error = error and json.get("error")
            self.logger.error(error)
            return

        json = verifyjson(json, "result")
        playpath = verifyjson(json, "id")
        url = verifyjson(json, "url")
        (width, height) = verifyjson(json, "size").split("x")
        name = "{0}p".format(height)

        parsed = urlparse(url)
        streams  = {}

        if parsed.scheme.startswith("rtmp"):
            if not RTMPStream.is_usable(self.session):
                raise PluginError("rtmpdump is not usable and required by Bambuser plugin")
            streams[name] = RTMPStream(self.session, {
                "rtmp": url,
                "playpath": playpath,
                "pageUrl": self.url,
                "live": True
            })
        elif parsed.scheme == "http":
            streams[name] = HTTPStream(self.session, url)

        return streams
Beispiel #23
0
    def _find_channel_config(self, data):
        match = re.search(r'meta itemprop="channelId" content="([^"]+)"', data)
        if not match:
            return

        channel_id = match.group(1)
        query = dict(channelId=channel_id, type="video", eventType="live",
                     part="id", key=API_KEY)
        res = http.get(API_SEARCH_URL, params=query)
        res = http.json(res)
        videos = verifyjson(res, "items")

        for video in videos:
            info = verifyjson(video, "id")
            video_id = info.get("videoId")
            url = "http://youtube.com/watch?v={0}".format(video_id)

            config = self._get_stream_info(url)
            if config:
                return config
Beispiel #24
0
    def _check_channel_live(self, channelname):
        url = self.MetadataURL.format(channelname)
        res = urlget(url, params=dict(fields="mode"))
        json = res_json(res)

        if not isinstance(json, dict):
            raise PluginError("Invalid JSON response")

        mode = verifyjson(json, "mode")

        return mode == "live"
Beispiel #25
0
    def _get_stream_id(self, channel_id):
        res = http.get(CONFIG_API_URL, params=dict(id=channel_id))
        config = http.json(res)
        media = verifyjson(config, "media")

        if not (media and isinstance(media, list)):
            return

        media = media[0]
        if not isinstance(media, dict):
            return

        return media.get("channel")
Beispiel #26
0
    def _get_streams(self):
        self.logger.debug("Fetching stream info")
        info = self._get_stream_info()

        if not info:
            raise NoStreamsError(self.url)

        event = verifyjson(info, "event")
        streaminfo = verifyjson(event, "stream_info")

        if not streaminfo or not streaminfo.get("is_live"):
            raise NoStreamsError(self.url)

        streams = defaultdict(list)
        play_url = streaminfo.get("play_url")
        if play_url:
            swfurl = info.get("viewerPlusSwfUrl") or info.get("hdPlayerSwfUrl")
            if not swfurl.startswith("http"):
                swfurl = "http://" + swfurl

            qualities = streaminfo.get("qualities", [])
            smil = self._parse_smil(streaminfo["play_url"], swfurl)
            for bitrate, stream in smil.items():
                name = "{0}k".format(bitrate/1000)
                for quality in qualities:
                    if quality["bitrate"] == bitrate:
                        name = "{0}p".format(quality["height"])

                streams[name].append(stream)

        m3u8_url = streaminfo.get("m3u8_url")
        if m3u8_url:
            hls_streams = HLSStream.parse_variant_playlist(self.session,
                                                           m3u8_url,
                                                           namekey="pixels")
            for name, stream in hls_streams.items():
                streams[name].append(stream)

        return streams
Beispiel #27
0
    def _get_streams(self):
        self.logger.debug("Fetching stream info")
        info = self._get_stream_info()

        if not info:
            raise NoStreamsError(self.url)

        event = verifyjson(info, "event")
        streaminfo = verifyjson(event, "stream_info")

        if not streaminfo or not streaminfo.get("is_live"):
            raise NoStreamsError(self.url)

        streams = defaultdict(list)
        play_url = streaminfo.get("play_url")
        if play_url:
            swfurl = info.get("viewerPlusSwfUrl") or info.get("hdPlayerSwfUrl")
            if not swfurl.startswith("http"):
                swfurl = "http://" + swfurl

            qualities = streaminfo.get("qualities", [])
            smil = self._parse_smil(streaminfo["play_url"], swfurl)
            for bitrate, stream in smil.items():
                name = "{0}k".format(bitrate / 1000)
                for quality in qualities:
                    if quality["bitrate"] == bitrate:
                        name = "{0}p".format(quality["height"])

                streams[name].append(stream)

        m3u8_url = streaminfo.get("m3u8_url")
        if m3u8_url:
            hls_streams = HLSStream.parse_variant_playlist(self.session,
                                                           m3u8_url,
                                                           namekey="pixels")
            for name, stream in hls_streams.items():
                streams[name].append(stream)

        return streams
Beispiel #28
0
    def _get_stream_id(self, channel_id):
        res = http.get(CONFIG_API_URL, params=dict(id=channel_id))
        config = http.json(res)
        media = verifyjson(config, "media")

        if not (media and isinstance(media, list)):
            return

        media = media[0]
        if not isinstance(media, dict):
            return

        return media.get("channel")
Beispiel #29
0
    def _get_streams(self):
        self.logger.debug("Fetching stream info")
        res = urlget(self.url, params=dict(output="json"))

        if res.json is None:
            raise PluginError("No JSON data in stream info")

        streams = {}
        video = verifyjson(res.json, "video")
        videos = verifyjson(video, "videoReferences")
        swfhash, swfsize = (None, None)

        for video in videos:
            if not ("url" in video and "playerType" in video):
                continue

            if video["playerType"] == "flash":
                if video["url"].startswith("rtmp"):
                    if not swfhash:
                        self.logger.debug("Verifying SWF: {0}", self.SWFURL)
                        swfhash, swfsize = swfverify(self.SWFURL)

                    stream = RTMPStream(self.session, {
                        "rtmp": video["url"],
                        "pageUrl": self.PageURL,
                        "swfhash": swfhash,
                        "swfsize": swfsize,
                        "live": True
                    })
                    streams[str(video["bitrate"]) + "k"] = stream
            elif video["playerType"] == "ios":
                try:
                    hlsstreams = HLSStream.parse_variant_playlist(self.session, video["url"])
                    streams.update(hlsstreams)
                except IOError as err:
                    self.logger.warning("Failed to get variant playlist: {0}", err)

        return streams
Beispiel #30
0
    def _get_streams(self):
        channelid = self._get_channel_id(self.url)

        if not channelid:
            raise NoStreamsError(self.url)

        self.logger.debug("Fetching stream info")
        data = urlget(self.JSONURL.format(channelid))

        try:
            info = json.loads(str(data, "utf8"))
        except ValueError as err:
            raise PluginError(("Unable to parse JSON: {0})").format(err))

        streams = {}
        video = verifyjson(info, "video")
        videos = verifyjson(video, "videoReferences")

        self.logger.debug("Verifying SWF: {0}", self.SWFURL)
        swfhash, swfsize = swfverify(self.SWFURL)

        for video in videos:
            if not ("url" in video and "playerType" in video and video["playerType"] == "flash"):
                continue

            stream = RTMPStream(self.session, {
                "rtmp": video["url"],
                "pageUrl": self.PageURL,
                "swfhash": swfhash,
                "swfsize": swfsize,
                "live": True
            })
            streams[str(video["bitrate"]) + "k"] = stream


        return streams
Beispiel #31
0
    def _get_hls_streams(self):
        url = self.HLSStreamTokenURL.format(self.channelname)

        try:
            res = urlget(url,
                         params=dict(type="iphone",
                                     connection="wifi",
                                     allow_cdn="true"),
                         exception=IOError)
        except IOError:
            self.logger.debug("HLS streams not available")
            return {}

        json = res_json(res, "stream token JSON")

        if not isinstance(json, list):
            raise PluginError("Invalid JSON response")

        if len(json) == 0:
            raise PluginError("No stream token in JSON")

        token = verifyjson(json[0], "token")
        hashed = hmac.new(self.HLSStreamTokenKey, bytes(token, "utf8"), sha1)
        fulltoken = hashed.hexdigest() + ":" + token
        url = self.HLSSPlaylistURL.format(self.channelname)

        try:
            params = dict(token=fulltoken, hd="true", allow_cdn="true")
            playlist = HLSStream.parse_variant_playlist(self.session,
                                                        url,
                                                        params=params)
        except IOError as err:
            if "404" in err:
                raise PluginError(err)
            else:
                self.logger.debug("Requesting mobile transcode")

                payload = dict(channel=self.channelname, type="iphone")
                urlopen("http://usher.twitch.tv/stream/transcode_iphone.json",
                        data=payload)

                return {}

        return playlist
    def create_playlist_token(self, channel):
        url = self.url(HLS_TOKEN_PATH, channel)
        params = dict(type="iphone", allow_cdn="true")

        try:
            res = urlget(url, params=params, exception=IOError)
        except IOError:
            return None

        json = res_json(res, "stream token JSON")

        if not (isinstance(json, list) and json):
            raise PluginError("Invalid JSON response")

        token = verifyjson(json[0], "token")
        hashed = hmac.new(HLS_TOKEN_KEY,
                          bytes(token, "utf8"),
                          sha1)

        return "{0}:{1}".format(hashed.hexdigest(), token)
Beispiel #33
0
    def _get_hls_streams(self):
        url = self.HLSStreamTokenURL.format(self.channelname)

        try:
            res = urlget(url, params=dict(type="iphone", connection="wifi",
                         allow_cdn="true"), exception=IOError)
        except IOError:
            self.logger.debug("HLS streams not available")
            return {}

        json = res_json(res, "stream token JSON")

        if not isinstance(json, list):
            raise PluginError("Invalid JSON response")

        if len(json) == 0:
            raise PluginError("No stream token in JSON")

        token = verifyjson(json[0], "token")
        hashed = hmac.new(self.HLSStreamTokenKey, bytes(token, "utf8"), sha1)
        fulltoken = hashed.hexdigest() + ":" + token
        url = self.HLSPlaylistURL.format(self.channelname)

        try:
            params = dict(token=fulltoken, hd="true", allow_cdn="true")
            playlist = HLSStream.parse_variant_playlist(self.session, url,
                                                        nameprefix="mobile_",
                                                        params=params)
        except IOError as err:
            if "404" not in str(err):
                raise PluginError(err)
            else:
                self.logger.debug("Requesting mobile transcode")

                payload = dict(channel=self.channelname, type="iphone")
                urlopen(self.HLSTranscodeRequest, data=payload)

                return {}

        return playlist
Beispiel #34
0
    def _get_streams(self):
        match = re.match(URL_REGEX, self.url)
        if not match:
            return

        stream_id = match.group("stream_id")
        res = http.get(STREAM_API.format(stream_id))
        json = http.json(res)
        stream_info = verifyjson(json, "streams")

        streams = {}
        swf_url = None
        for name, stream_url in stream_info.items():
            stream_url = str(stream_url)
            if stream_url.endswith(".m3u8"):
                try:
                    hls_streams = HLSStream.parse_variant_playlist(self.session,
                                                                   stream_url)
                    streams.update(hls_streams)
                except IOError as err:
                    self.logger.error("Failed to fetch HLS streams: {0}", err)
            elif stream_url.startswith("rtmp://"):
                swf_url = swf_url or self._get_swf_url()
                params = {
                    "rtmp": stream_url,
                    "pageUrl": self.url,
                    "swfVfy": swf_url,
                }

                if stream_url.endswith(".mp4"):
                    tcurl, playpath = rtmpparse(stream_url)
                    params["rtmp"] = tcurl
                    params["playpath"] = playpath
                else:
                    params["live"] = True

                streams[name] = RTMPStream(self.session, params)

        return streams
Beispiel #35
0
    def _get_streams(self):
        self.logger.debug("Fetching stream info")
        media_is_live = 0

        match = re.search(r".*hitbox.tv/([^/]*)/?(\d+)?", self.url)
        if not match:
            return

        stream_name, media_id = match.groups()
        if stream_name != "video":
            res = http.get(LIVE_API.format(stream_name))
            json = http.json(res)
            livestream = verifyjson(json, "livestream")
            media_id = verifyjson(livestream[0], "media_id")
            media_is_live = int(verifyjson(livestream[0], "media_is_live"))
            if not media_is_live:
                return

        media_type = "live" if media_is_live else "video"
        res = http.get(PLAYER_API.format(media_type, media_id))
        json = http.json(res)
        clip = verifyjson(json, "clip")
        live = verifyjson(clip, "live")
        plugins = verifyjson(json, "plugins")

        streams = {}
        if live:
            playlists = verifyjson(json, "playlist") or []
            swf_url = SWF_URL
            for playlist in playlists:
                bitrates = playlist.get("bitrates")
                provider = playlist.get("connectionProvider")
                rtmp = None

                if bitrates:
                    rtmp = playlist.get("netConnectionUrl")
                elif provider and provider in plugins:
                    provider = plugins[provider]
                    swf_name = verifyjson(provider, "url")
                    swf_url = SWF_BASE + swf_name
                    rtmp = verifyjson(provider, "netConnectionUrl")
                    bitrates = clip.get("bitrates", [])
                else:
                    continue

                for bitrate in bitrates:
                    quality = self._get_quality(verifyjson(bitrate, "label"))
                    url = verifyjson(bitrate, "url")
                    stream = RTMPStream(self.session, {
                        "rtmp": rtmp,
                        "pageUrl": self.url,
                        "playpath": url,
                        "swfVfy": swf_url,
                        "live": True
                    })
                    if quality in streams:
                        quality += "_alt"

                    streams[quality] = stream
        else:
            bitrates = verifyjson(clip, "bitrates")
            for bitrate in bitrates:
                base_url = verifyjson(clip, "baseUrl")
                url = verifyjson(bitrate, "url")
                quality = self._get_quality(verifyjson(bitrate, "label"))
                streams[quality] = HTTPStream(self.session,
                                              base_url + "/" + url)

        return streams
Beispiel #36
0
    def _get_streams(self):
        self.logger.debug("Fetching stream info")
        media_is_live = 0

        match = re.search(r".*hitbox.tv/([^/]*)/?(\d+)?", self.url)
        if not match:
            raise NoStreamsError(self.url)

        stream_name, media_id = match.groups()

        if stream_name != "video":
            res = urlget(LIVE_API.format(stream_name))
            json = res_json(res)
            livestream = verifyjson(json, "livestream")
            media_id = verifyjson(livestream[0], "media_id")
            media_is_live = int(verifyjson(livestream[0], "media_is_live"))
            if not media_is_live:
                raise NoStreamsError(self.url)

        media_type = "live" if media_is_live else "video"
        res = urlget(PLAYER_API.format(media_type, media_id))
        json = res_json(res)
        clip = verifyjson(json, "clip")
        live = verifyjson(clip, "live")
        bitrates = verifyjson(clip, "bitrates")

        streams = {}
        if live:
            for bitrate in bitrates:
                connection_provider = clip.get("connectionProvider",
                                               "clustering")
                plugins = verifyjson(json, "plugins")
                provider_plugin = verifyjson(plugins, connection_provider)
                swf = verifyjson(provider_plugin, "url")
                rtmp = verifyjson(provider_plugin, "netConnectionUrl")
                quality = self._get_quality(verifyjson(bitrate, "label"))
                url = verifyjson(bitrate, "url")

                streams[quality] = RTMPStream(
                    self.session, {
                        "rtmp": rtmp,
                        "pageUrl": self.url,
                        "playpath": url,
                        "swfVfy": SWF_BASE + swf,
                        "live": True
                    })
        else:
            for bitrate in bitrates:
                base_url = verifyjson(clip, "baseUrl")
                url = verifyjson(bitrate, "url")
                quality = self._get_quality(verifyjson(bitrate, "label"))
                streams[quality] = HTTPStream(self.session,
                                              base_url + "/" + url)

        return streams
Beispiel #37
0
    def _get_streams(self):
        self.logger.debug("Fetching stream info")
        media_is_live = 0

        match = re.search(r".*hitbox.tv/([^/]*)/?(\d+)?", self.url)
        if not match:
            return

        stream_name, media_id = match.groups()
        if stream_name != "video":
            res = http.get(LIVE_API.format(stream_name))
            json = http.json(res)
            livestream = verifyjson(json, "livestream")
            media_id = verifyjson(livestream[0], "media_id")
            media_is_live = int(verifyjson(livestream[0], "media_is_live"))
            if not media_is_live:
                return

        media_type = "live" if media_is_live else "video"
        res = http.get(PLAYER_API.format(media_type, media_id))
        json = http.json(res)
        clip = verifyjson(json, "clip")
        live = verifyjson(clip, "live")

        streams = {}
        if live:
            playlists = verifyjson(json, "playlist") or []
            for playlist in filter(valid_playlist, playlists):
                bitrates = playlist.get("bitrates")
                rtmp = playlist.get("netConnectionUrl")
                for bitrate in bitrates:
                    quality = self._get_quality(verifyjson(bitrate, "label"))
                    url = verifyjson(bitrate, "url")
                    streams[quality] = RTMPStream(self.session, {
                        "rtmp": rtmp,
                        "pageUrl": self.url,
                        "playpath": url,
                        "swfVfy": SWF_URL,
                        "live": True
                    })
        else:
            bitrates = verifyjson(clip, "bitrates")
            for bitrate in bitrates:
                base_url = verifyjson(clip, "baseUrl")
                url = verifyjson(bitrate, "url")
                quality = self._get_quality(verifyjson(bitrate, "label"))
                streams[quality] = HTTPStream(self.session,
                                              base_url + "/" + url)

        return streams
Beispiel #38
0
    def _get_streams(self):
        self.logger.debug("Fetching stream info")
        media_is_live = 0

        match = re.search(r".*hitbox.tv/([^/]*)/?(\d+)?", self.url)
        if not match:
            raise NoStreamsError(self.url)

        stream_name, media_id = match.groups()

        if stream_name != "video":
            res = urlget(LIVE_API.format(stream_name))
            json = res_json(res)
            livestream = verifyjson(json, "livestream")
            media_id = verifyjson(livestream[0], "media_id")
            media_is_live = int(verifyjson(livestream[0], "media_is_live"))
            if not media_is_live:
                raise NoStreamsError(self.url)

        media_type = "live" if media_is_live else "video"
        res = urlget(PLAYER_API.format(media_type, media_id))
        json = res_json(res)
        clip = verifyjson(json, "clip")
        live = verifyjson(clip, "live")
        bitrates = verifyjson(clip, "bitrates")

        streams = {}
        if live:
            for bitrate in bitrates:
                connection_provider = clip.get("connectionProvider", "clustering")
                plugins = verifyjson(json, "plugins")
                provider_plugin = verifyjson(plugins, connection_provider)
                swf = verifyjson(provider_plugin, "url")
                rtmp = verifyjson(provider_plugin, "netConnectionUrl")
                quality = self._get_quality(verifyjson(bitrate, "label"))
                url = verifyjson(bitrate, "url")

                streams[quality] = RTMPStream(self.session, {
                    "rtmp": rtmp,
                    "pageUrl": self.url,
                    "playpath": url,
                    "swfVfy": SWF_BASE + swf,
                    "live": True
                })
        else:
            for bitrate in bitrates:
                base_url = verifyjson(clip, "baseUrl")
                url = verifyjson(bitrate, "url")
                quality = self._get_quality(verifyjson(bitrate, "label"))
                streams[quality] = HTTPStream(self.session,
                                              base_url + "/" + url)

        return streams
Beispiel #39
0
    def _get_streams(self):
        self.logger.debug("Fetching stream info")
        media_is_live = 0

        match = re.search(r".*hitbox.tv/([^/]*)/?(\d+)?", self.url)
        if not match:
            return

        stream_name, media_id = match.groups()
        if stream_name != "video":
            res = http.get(LIVE_API.format(stream_name))
            json = http.json(res)
            livestream = verifyjson(json, "livestream")
            media_id = verifyjson(livestream[0], "media_id")
            media_is_live = int(verifyjson(livestream[0], "media_is_live"))
            if not media_is_live:
                return

        media_type = "live" if media_is_live else "video"
        res = http.get(PLAYER_API.format(media_type, media_id))
        json = http.json(res)
        clip = verifyjson(json, "clip")
        live = verifyjson(clip, "live")
        plugins = verifyjson(json, "plugins")

        streams = {}
        if live:
            playlists = verifyjson(json, "playlist") or []
            swf_url = SWF_URL
            for playlist in playlists:
                bitrates = playlist.get("bitrates")
                provider = playlist.get("connectionProvider")
                rtmp = None

                if bitrates:
                    rtmp = playlist.get("netConnectionUrl")
                elif provider and provider in plugins:
                    provider = plugins[provider]
                    swf_name = verifyjson(provider, "url")
                    swf_url = SWF_BASE + swf_name
                    rtmp = verifyjson(provider, "netConnectionUrl")
                    bitrates = clip.get("bitrates", [])
                else:
                    continue

                for bitrate in bitrates:
                    quality = self._get_quality(verifyjson(bitrate, "label"))
                    url = verifyjson(bitrate, "url")
                    stream = RTMPStream(
                        self.session, {
                            "rtmp": rtmp,
                            "pageUrl": self.url,
                            "playpath": url,
                            "swfVfy": swf_url,
                            "live": True
                        })
                    if quality in streams:
                        quality += "_alt"

                    streams[quality] = stream
        else:
            bitrates = verifyjson(clip, "bitrates")
            for bitrate in bitrates:
                base_url = verifyjson(clip, "baseUrl")
                url = verifyjson(bitrate, "url")
                quality = self._get_quality(verifyjson(bitrate, "label"))
                streams[quality] = HTTPStream(self.session,
                                              base_url + "/" + url)

        return streams