Example #1
0
    def _get_streams(self):
        self.logger.debug("Fetching stream info")
        res = urlget(self.url)

        match = re.search("\"User_channelid\".+?value=\"(.+?)\"", res.text)
        if not match:
            raise NoStreamsError(self.url)

        headers = {
            "Referer": self.url
        }

        res = urlget(self.PlayerURL.format(match.group(1)), headers=headers)

        match = re.search("stream:\s+'(rtmp://.+?)'", res.text)
        if not match:
            raise NoStreamsError(self.url)

        rtmp = match.group(1)
        streams = {}
        streams["live"] = RTMPStream(self.session, {
            "rtmp": rtmp,
            "pageUrl": self.url,
            "swfVfy": self.SWFURL,
            "live": True
        })

        return streams
Example #2
0
    def _get_streams(self):
        res = urlget(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 = urlget(STREAM_API_URL.format(stream_id),
                     params=dict(format="all"))
        json = res_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
Example #3
0
    def _get_streams(self):
        self.logger.debug("Fetching stream info")
        res = urlget(self.url)

        match = re.search(
            "flashplayer: \"(.+.swf)\".+streamer: \"(.+)\".+file: \"(.+).flv\"",
            res.text, re.DOTALL)
        if not match:
            raise NoStreamsError(self.url)

        params = {
            "rtmp": match.group(2),
            "pageUrl": self.url,
            "swfVfy": match.group(1),
            "playpath": match.group(3),
            "live": True
        }

        match = re.search("(http(s)?://.+/server.php\?id=\d+)", res.text)
        if match:
            token_url = match.group(1)
            res = res_json(urlget(token_url, headers=dict(Referer=self.url)))
            token = res.get("token")
            if token:
                params["token"] = token

        streams = {}
        streams["live"] = RTMPStream(self.session, params)

        return streams
Example #4
0
    def _get_rtmp_streams(self, swfurl):
        if not RTMPStream.is_usable(self.session):
            raise NoStreamsError(self.url)

        self.logger.debug("Fetching RTMP stream info")

        res = urlget(swfurl)
        swf = swfdecompress(res.content)
        match = re.search("customURL[^h]+(https://.*?)\\\\", swf)

        if not match:
            raise NoStreamsError(self.url)

        res = urlget(match.group(1))
        rtmp, playpath = rtmpparse(res.text)

        params = {
            "rtmp": rtmp,
            "pageUrl": self.url,
            "playpath": playpath,
            "live": True
        }

        match = re.search("file[^h]+(https?://.*?.swf)", swf)
        if match:
            params["swfUrl"] = match.group(1)

        return RTMPStream(self.session, params)
Example #5
0
    def _get_streams(self):
        channelname = urlparse(
            self.url).path.rstrip("/").rpartition("/")[-1].lower()

        self.logger.debug("Fetching stream info")

        headers = {"Referer": self.url}

        res = urlget(self.PlayerURL.format(channelname), headers=headers)
        match = re.search("'FlashVars', '(id=\d+)&", res.text)
        if not match:
            raise NoStreamsError(self.url)

        channelname += "?" + match.group(1)
        res = urlget(self.BalancerURL, headers=headers)

        match = re.search("redirect=(.+)", res.text)
        if not match:
            raise PluginError(
                "Error retrieving RTMP address from loadbalancer")

        rtmp = match.group(1)
        streams = {}
        streams["live"] = RTMPStream(
            self.session, {
                "rtmp": "rtmp://{0}/live/{1}".format(rtmp, channelname),
                "pageUrl": self.url,
                "swfVfy": self.SWFURL,
                "conn": "S:OK",
                "live": True
            })

        return streams
Example #6
0
    def _get_streams(self):
        channelname = urlparse(self.url).path.rstrip("/").rpartition("/")[-1].lower()

        self.logger.debug("Fetching stream info")

        headers = {
            "Referer": self.url
        }

        res = urlget(self.PlayerURL.format(channelname), headers=headers)
        match = re.search("'FlashVars', '(id=\d+)&s=(.+?)&", res.text)
        if not match:
            raise NoStreamsError(self.url)

        channelname = "{0}?{1}".format(match.group(2), match.group(1))
        res = urlget(self.BalancerURL, headers=headers)

        match = re.search("redirect=(.+)", res.text)
        if not match:
            raise PluginError("Error retrieving RTMP address from loadbalancer")

        rtmp = match.group(1)
        streams = {}
        streams["live"] = RTMPStream(self.session, {
            "rtmp": "rtmp://{0}/live/{1}".format(rtmp, channelname),
            "pageUrl": self.url,
            "swfVfy": self.SWFURL,
            "conn": "S:OK",
            "live": True
        })

        return streams
Example #7
0
    def _choose_server(self, json):
        res = urlget(self.GEOIPURL)
        loc = res_json(res)
        loc = [loc["latitude"], loc["longitude"]]
        sel_dist = float("inf")
        i = 0
        primary = -1
        secondary = -1

        for server in json["server"]:
            res = urlget(self.GEOURL+server["server"]["name"]+"&sensor=false")
            cord = res_json(res)
            cord = [cord["results"][0]["geometry"]["location"]["lat"], cord["results"][0]["geometry"]["location"]["lng"]]
            cur_dist = self._distance(loc, cord)

            if cur_dist < sel_dist:
                sel_dist = cur_dist

                if server["server"]["used"] < 90:
                    # nearest server with load < 90%
                    primary = i
                else:
                    # nearest server with load > 90%
                    secondary = i

            i += 1

        if primary == -1:
            # if all servers have load over 90% use nearest one
            return secondary

        return primary
Example #8
0
    def _get_streams(self):
        self.logger.debug("Fetching stream info")
        res = urlget(self.url)

        match = re.search("\"User_channelid\".+?value=\"(.+?)\"", res.text)
        if not match:
            raise NoStreamsError(self.url)

        headers = {
            "Referer": self.url
        }

        res = urlget(self.PlayerURL.format(match.group(1)), headers=headers)

        match = re.search("stream:\s+'(rtmp://.+?)'", res.text)
        if not match:
            raise NoStreamsError(self.url)

        rtmp = match.group(1)
        streams = {}
        streams["live"] = RTMPStream(self.session, {
            "rtmp": rtmp,
            "pageUrl": self.url,
            "swfVfy": self.SWFURL,
            "live": True
        })

        return streams
Example #9
0
    def _get_streams(self):
        self.logger.debug("Fetching stream info")
        res = urlget(self.url)

        match = re.search("flashplayer: \"(.+.swf)\".+streamer: \"(.+)\".+file: \"(.+).flv\"", res.text, re.DOTALL)
        if not match:
            raise NoStreamsError(self.url)

        params = {
            "rtmp": match.group(2),
            "pageUrl": self.url,
            "swfVfy": match.group(1),
            "playpath" : match.group(3),
            "live": True
        }

        match = re.search("(http(s)?://.+/server/server.php\?id=\d+)",
                          res.text)
        if match:
            token_url = match.group(1)
            res = res_json(urlget(token_url, headers=dict(Referer=self.url)))
            token = res.get("token")
            if token:
                params["token"] = token

        streams = {}
        streams["live"] = RTMPStream(self.session, params, redirect=True)

        return streams
Example #10
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
Example #11
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
Example #12
0
 def grabLivePage(self, gomtvLiveURL):
     response = urlget(gomtvLiveURL, opener=self.opener)
     # If a special event occurs, we know that the live page response
     # will just be some JavaScript that redirects the browser to the
     # real live page. We assume that the entireity of this JavaScript
     # is less than 200 characters long, and that real live pages are
     # more than that.
     if len(response) < 200:
         # Grabbing the real live page URL
         gomtvLiveURL = self.getEventLivePageURL(gomtvLiveURL, response)
         response = urlget(gomtvLiveURL, opener=self.opener)
     return response
Example #13
0
    def _get_stream_info(self, url):
        res = urlget(url)
        config = self._find_config(res.text)

        if not config:
            watch_match = re.search("href=\"/(watch\?v=.+?)\"", res.text)
            if watch_match:
                watch_url = "http://youtube.com/{0}".format(watch_match.group(1))
                res = urlget(watch_url)
                config = self._find_config(res.text)

        if config:
            return parse_json(config, "config JSON")
Example #14
0
    def _get_stream_info(self, url):
        res = urlget(url)
        config = self._find_config(res.text)

        if not config:
            watch_match = re.search("href=\"/(watch\?v=.+?)\"", res.text)
            if watch_match:
                watch_url = "http://youtube.com/%s" % watch_match.group(1)
                res = urlget(watch_url)
                config = self._find_config(res.text)

        if config:
            return parse_json(config, "config JSON")
Example #15
0
    def _get_vod_streams(self):
        res = urlget(self.url)
        flashvars = re.search("FlashVars=\"(.+?)\"", res.text)

        if not flashvars:
            raise PluginError("Unable to find flashvars on page")

        flashvars = parse_qs(flashvars.group(1))
        for var in ("vjoinid", "conid", "leagueid"):
            if not var in flashvars:
                raise PluginError(
                    ("Missing key '{0}' in flashvars").format(var))

        streams = {}
        qualities = ["SQ", "HQ"]

        for quality in qualities:
            params = dict(leagueid=flashvars["leagueid"][0],
                          vjoinid=flashvars["vjoinid"][0],
                          conid=flashvars["conid"][0],
                          title="",
                          ref="",
                          tmpstamp=int(time.time()),
                          strLevel=quality)
            res = urlget(self.GOXVODURL, params=params, session=self.rsession)

            if res.text != "1002" and len(res.text) > 0:
                gox = self._parse_gox_file(res.text)
                entry = gox[0]

                nokey = False
                for var in ("NODEIP", "NODEID", "UNO", "USERIP"):
                    if not var in entry:
                        nokey = True

                if nokey:
                    self.logger.warning(
                        "Unable to fetch key, make sure that you have access to this VOD"
                    )
                    continue

                key = self._check_vod_key(entry["NODEIP"], entry["NODEID"],
                                          entry["UNO"], entry["USERIP"])

                streams[quality.lower()] = HTTPStream(
                    self.session,
                    gox[0]["REF"],
                    params=dict(key=key),
                    headers=self.StreamHeaders)

        return streams
Example #16
0
    def _get_streams(self):
        country_code = urlparse(self.url).netloc.split(".")[0]

        self.logger.debug("Fetching stream info")
        res = urlget(self.APIURL)
        json = res_json(res)

        if not isinstance(json, dict):
            raise PluginError("Invalid JSON response")
        elif not ("primary" in json or "secondary" in json):
            raise PluginError("Invalid JSON response")

        if not RTMPStream.is_usable(self.session):
            raise PluginError(
                "rtmpdump is not usable and required by Euronews plugin")

        streams = {}

        self.logger.debug("Euronews Countries:{0}",
                          " ".join(json["primary"].keys()))

        if not (country_code in json["primary"]
                or country_code in json["secondary"]):
            res = urlget(self.GEOIPURL)
            geo = res_json(res)
            if isinstance(json, dict) and "country_code" in geo:
                country_code = geo["country_code"].lower()
                if not (country_code in json["primary"]
                        or country_code in json["secondary"]):
                    country_code = "en"
            else:
                country_code = "en"

        for site in ("primary", "secondary"):
            for quality in json[site][country_code]["rtmp_flash"]:
                stream = json[site][country_code]["rtmp_flash"][quality]
                name = quality + "k"
                if site == "secondary":
                    name += "_alt"
                streams[name] = RTMPStream(
                    self.session, {
                        "rtmp": stream["server"],
                        "playpath": stream["name"],
                        "swfUrl": self.SWFURL,
                        "live": True
                    })

        if len(streams) == 0:
            raise NoStreamsError(self.url)

        return streams
Example #17
0
    def _get_live_page(self, url):
        res = urlget(url, session=self.rsession)

        # If a special event occurs, we know that the live page response
        # will just be some JavaScript that redirects the browser to the
        # real live page. We assume that the entireity of this JavaScript
        # is less than 200 characters long, and that real live pages are
        # more than that.

        if len(res.text) < 200:
            # Grabbing the real live page URL
            url = self._parse_event_url(url, res.text)
            res = urlget(url, session=self.rsession)

        return res
Example #18
0
    def _get_live_page(self, url):
        res = urlget(url, session=self.rsession)

        # If a special event occurs, we know that the live page response
        # will just be some JavaScript that redirects the browser to the
        # real live page. We assume that the entireity of this JavaScript
        # is less than 200 characters long, and that real live pages are
        # more than that.

        if len(res.text) < 200:
            # Grabbing the real live page URL
            url = self._parse_event_url(url, res.text)
            res = urlget(url, session=self.rsession)

        return res
Example #19
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
Example #20
0
    def _get_streams(self):
        parsed = urlparse(self.url)

        if parsed.fragment:
            channelid = parsed.fragment
        else:
            channelid = parsed.path.rpartition("view/")[-1]

        if not channelid:
            raise NoStreamsError(self.url)

        channelid = channelid.lower().replace("/", "_")

        self.logger.debug("Fetching stream info")
        res = urlget(self.APIURL.format(channelid))
        json = res_json(res)

        if not isinstance(json, dict):
            raise PluginError("Invalid JSON response")
        elif not ("success" in json and "payload" in json):
            raise PluginError("Invalid JSON response")
        elif json["success"] == False:
            raise NoStreamsError(self.url)

        streams = {}
        streams["live"] = HTTPStream(self.session, json["payload"])

        return streams
Example #21
0
    def _get_streams(self):
        self.rsession = requests.session(prefetch=True)

        options = self.options
        if options.get("cookie"):
            self._authenticate(cookies=options.get("cookie"))
        else:
            self._authenticate(options.get("username"), options.get("password"))

        streams = {}
        qualities = ["HQ", "SQ", "HQTest", "SQTest"]

        res = self._get_live_page(self.url)
        urls = self._find_stream_urls(res.text)

        for quality in qualities:
            for url in urls:
                # Grab the response of the URL listed on the Live page for a stream
                url = url.format(quality=quality)
                res = urlget(url, session=self.rsession)

                # The response for the GOX XML if an incorrect stream quality is chosen is 1002.
                if res.text != "1002" and len(res.text) > 0:
                    streamurl = self._parse_gox_file(res.text)
                    streams[quality.lower()] = HTTPStream(self.session, streamurl,
                                                          headers=self.StreamHeaders)

        return streams
Example #22
0
    def _parse_smil(self, url):
        res = urlget(url)

        try:
            dom = xml.dom.minidom.parseString(res.text)
        except Exception as err:
            raise PluginError(("Unable to parse config XML: {0})").format(err))

        httpbase = None
        streams = {}

        for meta in dom.getElementsByTagName("meta"):
            if meta.getAttribute("name") == "httpBase":
                httpbase = meta.getAttribute("content")
                break

        if not httpbase:
            raise PluginError("Missing HTTP base in SMIL")

        for video in dom.getElementsByTagName("video"):
            url = "{0}/{1}".format(httpbase, video.getAttribute("src"))
            bitrate = int(video.getAttribute("system-bitrate"))
            streams[bitrate] = AkamaiHDStream(self.session, url)

        return streams
Example #23
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")
        res = urlget(self.AMFURL.format(channelid))

        try:
            packet = AMF0Packet.deserialize(BytesIO(res.content))
        except (IOError, AMFError) as err:
            raise PluginError(("Failed to parse AMF packet: {0}").format(str(err)))

        result = None
        for message in packet.messages:
            if message.target_uri == "/1/onResult":
                result = message.value
                break

        if not result:
            raise PluginError("No result found in AMF packet")

        streams = {}

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

        if "streamName" in result:
            if "cdnUrl" in result:
                cdn = result["cdnUrl"]
            elif "fmsUrl" in result:
                cdn = result["fmsUrl"]
            else:
                self.logger.warning("Missing cdnUrl and fmsUrl from result")
                return streams

            if "videoCodec" in result and result["videoCodec"]["height"] > 0:
                streamname = "{0}p".format(int(result["videoCodec"]["height"]))
            else:
                streamname = "live"

            streams[streamname] = self._create_stream(cdn, result["streamName"])

        if "streamVersions" in result:
            for version, info in result["streamVersions"].items():
                if "streamVersionCdn" in info:
                    for name, cdn in info["streamVersionCdn"].items():
                        if "cdnStreamUrl" in cdn and "cdnStreamName" in cdn:
                            streams["cdn_" + name] = self._create_stream(cdn["cdnStreamUrl"],
                                                                         cdn["cdnStreamName"])


        return streams
Example #24
0
    def find(self, channel, password=None, **extra_params):
        url = self.url(USHER_FIND_PATH, channel)
        params = dict(p=int(random() * 999999), type="any",
                      private_code=password or "null", **extra_params)

        return res_json(urlget(url, params=params),
                        "stream info JSON")
Example #25
0
    def _get_rtmp_streams(self):
        def clean_tag(tag):
            if tag[0] == "_":
                return tag[1:]
            else:
                return tag

        chansub = self._authenticate()

        url = self.StreamInfoURL.format(self.channelname)
        params = dict(b_id="true", group="", private_code="null",
                      p=int(random.random() * 999999),
                      channel_subscription=chansub, type="any")

        self.logger.debug("Fetching stream info")
        res = urlget(url, params=params)
        data = res.text

        # fix invalid xml
        data = re.sub("<(\d+)", "<_\g<1>", data)
        data = re.sub("</(\d+)", "</_\g<1>", data)

        streams = {}

        try:
            dom = xml.dom.minidom.parseString(data)
        except Exception as err:
            raise PluginError(("Unable to parse config XML: {0})").format(err))

        nodes = dom.getElementsByTagName("nodes")[0]

        if len(nodes.childNodes) == 0:
            return streams

        swfurl = urlresolve(self.SWFURL)

        for node in nodes.childNodes:
            info = {}
            for child in node.childNodes:
                info[child.tagName] = self._get_node_text(child)

            if not ("connect" in info and "play" in info):
                continue

            stream = RTMPStream(self.session, {
                "rtmp": ("{0}/{1}").format(info["connect"], info["play"]),
                "swfVfy": swfurl,
                "live": True
            })

            sname = clean_tag(node.tagName)

            if "token" in info:
                stream.params["jtv"] = info["token"]
            else:
                self.logger.warning("No token found for stream {0}, this stream may fail to play", sname)

            streams[sname] = stream

        return streams
Example #26
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
Example #27
0
    def _get_streams(self):
        res = urlget(self.StreamURL, data={"from": "ongamenet"})

        match = re.search("var stream = \"(.+?)\";", res.text)
        if not match:
            raise NoStreamsError(self.url)

        stream = match.group(1)

        match = re.search("var server = \"(.+?)\";", res.text)
        if not match:
            raise NoStreamsError(self.url)

        server = match.group(1)

        streams = {}
        streams["live"] = RTMPStream(
            self.session, {
                "rtmp": server,
                "playpath": stream,
                "swfUrl": self.SWFURL,
                "pageUrl": self.PageURL,
                "live": True,
            })

        return streams
Example #28
0
    def _get_streams(self):
        self.rsession = requests.session(prefetch=True)

        options = self.options
        if options.get("cookie"):
            self._authenticate(cookies=options.get("cookie"))
        else:
            self._authenticate(options.get("username"),
                               options.get("password"))

        streams = {}
        qualities = ["HQ", "SQ", "HQTest", "SQTest"]

        res = self._get_live_page(self.url)
        urls = self._find_stream_urls(res.text)

        for quality in qualities:
            for url in urls:
                # Grab the response of the URL listed on the Live page for a stream
                url = url.format(quality=quality)
                res = urlget(url, session=self.rsession)

                # The response for the GOX XML if an incorrect stream quality is chosen is 1002.
                if res.text != "1002" and len(res.text) > 0:
                    streamurl = self._parse_gox_file(res.text)
                    streams[quality.lower()] = HTTPStream(
                        self.session, streamurl, headers=self.StreamHeaders)

        return streams
Example #29
0
    def _get_streams(self):
        res = urlget(self.PlayerURL)

        match = re.search("var stream = \"(.+?)\";", res.text)
        if not match:
            raise NoStreamsError(self.url)

        stream = match.group(1)

        match = re.search("var server = \"(.+?)\";", res.text)
        if not match:
            raise NoStreamsError(self.url)

        server = match.group(1)

        streams = {}
        streams["live"] = RTMPStream(self.session, {
            "rtmp": server,
            "playpath": stream,
            "swfUrl": self.SWFURL,
            "pageUrl": self.PageURL,
            "live": True,
        })

        return streams
Example #30
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
Example #31
0
    def _parse_smil(self, url):
        res = urlget(url)

        try:
            dom = xml.dom.minidom.parseString(res.text)
        except Exception as err:
            raise PluginError(("Unable to parse config XML: {0})").format(err))

        httpbase = None
        streams = {}

        for meta in dom.getElementsByTagName("meta"):
            if meta.getAttribute("name") == "httpBase":
                httpbase = meta.getAttribute("content")
                break

        if not httpbase:
            raise PluginError("Missing HTTP base in SMIL")

        for video in dom.getElementsByTagName("video"):
            url = "{0}/{1}".format(httpbase, video.getAttribute("src"))
            bitrate = int(video.getAttribute("system-bitrate"))
            streams[bitrate] = AkamaiHDStream(self.session, url)

        return streams
Example #32
0
    def _get_streams(self):
        def get_amf_value(data, key):
            pattern = ("{0}\x02..(.*?)\x00").format(key)
            match = re.search(bytes(pattern, "ascii"), data)
            if match:
                return str(match.group(1), "ascii")

        streams = {}
        channelid = self._get_channel_id(self.url)

        if not channelid:
            raise NoStreamsError(self.url)

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

        playpath = get_amf_value(data, "streamName")
        cdnurl = get_amf_value(data, "cdnUrl")
        fmsurl = get_amf_value(data, "fmsUrl")

        if playpath:
            stream = RTMPStream(self.session, {
                "rtmp": ("{0}/{1}").format(cdnurl or fmsurl, playpath),
                "pageUrl": self.url,
                "swfUrl": self.SWFURL,
                "live": True
            })
            streams["live"] = stream

        return streams
Example #33
0
    def _find_broadcast(self, username):
        res = urlget(CHANNEL_URL, headers=HEADERS,
                     params=dict(szBjId=username))

        match = re.search(r"<thumb>.+\/(\d+)\.gif</thumb>", res.text)
        if match:
            return match.group(1)
Example #34
0
    def get_live_streams(self):
        res = self._get_live_page(self.res)

        match = re.search("this\.playObj = ({.+?})", res.text, re.DOTALL)
        if not match:
            raise NoStreamsError(self.url)

        flashvars = parse_json(match.group(1), "playObj JSON")

        match = re.search("goxkey=([A-z0-9]+)", res.text)
        if not match:
            raise NoStreamsError(self.url)

        flashvars["goxkey"] = match.group(1)
        flashvars["target"] = "live"

        streams = {}

        for strlevel in self.LiveQualityLevels:
            params = self._create_gox_params(flashvars, strlevel, "live")
            res = urlget(self.GOXURL, params=params, session=self.rsession)

            gox = GOXFile(res.text)

            for entry in gox.entries:
                streams[strlevel.lower()] = HTTPStream(self.session, entry.ref[0],
                                                       headers=self.StreamHeaders)

                break

        return streams
Example #35
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")
        res = urlget(self.AMFURL.format(channelid))

        try:
            packet = AMF0Packet.deserialize(BytesIO(res.content))
        except (IOError, AMFError) as err:
            raise PluginError(
                ("Failed to parse AMF packet: {0}").format(str(err)))

        result = None
        for message in packet.messages:
            if message.target_uri == "/1/onResult":
                result = message.value
                break

        if not result:
            raise PluginError("No result found in AMF packet")

        streams = {}

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

        if "streamName" in result:
            if "cdnUrl" in result:
                cdn = result["cdnUrl"]
            elif "fmsUrl" in result:
                cdn = result["fmsUrl"]
            else:
                self.logger.warning("Missing cdnUrl and fmsUrl from result")
                return streams

            if "videoCodec" in result and result["videoCodec"]["height"] > 0:
                streamname = "{0}p".format(int(result["videoCodec"]["height"]))
            else:
                streamname = "live"

            streams[streamname] = self._create_stream(cdn,
                                                      result["streamName"])

        if "streamVersions" in result:
            for version, info in result["streamVersions"].items():
                if "streamVersionCdn" in info:
                    for name, cdn in info["streamVersionCdn"].items():
                        if "cdnStreamUrl" in cdn and "cdnStreamName" in cdn:
                            streams["cdn_" + name] = self._create_stream(
                                cdn["cdnStreamUrl"], cdn["cdnStreamName"])

        return streams
Example #36
0
    def _get_streams(self):
        self.rsession = requests.session()
        options = self.options

        if options.get("cookie"):
            self._authenticate(cookies=options.get("cookie"))
        else:
            self._authenticate(options.get("username"),
                               options.get("password"))

        res = urlget(self.url, session=self.rsession)
        player = GomTV3(self.url, res, self.rsession)
        streams = {}

        if "/vod/" in self.url:
            return player.get_vod_streams()
        else:
            try:
                streams.update(player.get_live_streams())
            except NoStreamsError:
                pass

            try:
                streams.update(player.get_alt_live_streams())
            except NoStreamsError:
                pass

            try:
                streams.update(player.get_limelight_live_streams())
            except NoStreamsError:
                pass

        return streams
Example #37
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
Example #38
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
Example #39
0
    def _get_streams(self):
        self.logger.debug("Fetching stream info")
        res = urlget(self.url)

        match = re.search("var info = (.*);", res.text)
        if not match:
            raise NoStreamsError(self.url)

        json = parse_json(match.group(1))
        if not isinstance(json, dict):
            return

        ios_url = json.get("ios_url")
        swf_url = json.get("swf_url")
        streams = {}

        if ios_url:
            hls = HLSStream.parse_variant_playlist(self.session, ios_url)
            streams.update(hls)

        if swf_url:
            try:
                streams["live"] = self._get_rtmp_streams(swf_url)
            except NoStreamsError:
                pass

        return streams
Example #40
0
    def _get_channel_info(self, url):
        self.logger.debug("Fetching channel info")

        res = urlget(url)
        data = res.text

        channelid = None
        swfurl = None

        match = re.search('flashvars.config = "livecfg/(\d+)', data)
        if match:
            channelid = int(match.group(1))

        match = re.search("document.location.hash='/live/(\d+)'", data)
        if match:
            channelid = int(match.group(1))

        match = re.search("xajax_load_live_config\((\d+),", data)
        if match:
            channelid = int(match.group(1))

        match = re.search("""swfobject.embedSWF\(\n.+"(.+)", "player",""", data)
        if match:
            swfurl = match.group(1)

        return (channelid, swfurl)
Example #41
0
    def _get_streams(self):
        channelid = urlparse(
            self.url).path.rstrip("/").rpartition("/")[-1].lower()

        self.logger.debug("Fetching stream info")
        headers = {"Referer": self.url}
        options = dict(id=channelid)
        res = urlget(self.StreamInfoURL, headers=headers, params=options)
        json = res_json(res, "stream info JSON")

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

        if not ("rtmp" in json and "streamname" in json):
            raise NoStreamsError(self.url)

        if not RTMPStream.is_usable(self.session):
            raise PluginError(
                "rtmpdump is not usable and required by Owncast plugin")

        rtmp = json["rtmp"]
        playpath = json["streamname"]

        streams = {}
        streams["live"] = RTMPStream(
            self.session, {
                "rtmp": rtmp,
                "pageUrl": self.url,
                "swfUrl": self.SWFURL,
                "playpath": playpath,
                "live": True
            })

        return streams
Example #42
0
    def _authenticate(self, username=None, password=None, cookies=None):
        if (username is None or password is None) and cookies is None:
            raise PluginError("GOMTV.net requires a username and password or a cookie")

        if cookies is not None:
            for cookie in cookies.split(";"):
                try:
                    name, value = cookie.split("=")
                except ValueError:
                    continue

                self.rsession.cookies[name.strip()] = value.strip()

            self.logger.info("Attempting to authenticate with cookies")
        else:
            form = dict(cmd="login", rememberme="1",
                        mb_username=username,
                        mb_password=password)

            self.logger.info("Attempting to authenticate with username and password")

            urlopen(self.LoginURL, data=form, headers=self.LoginHeaders,
                    session=self.rsession)

        res = urlget(self.LoginCheckURL, session=self.rsession)

        if "Please need login" in res.text:
            raise PluginError("Authentication failed")

        if "SES_USERNICK" in self.rsession.cookies:
            username = self.rsession.cookies["SES_USERNICK"]
            self.logger.info(("Successfully logged in as {0}").format(username))
Example #43
0
    def get_live_streams(self):
        res = self._get_live_page(self.res)

        match = re.search("flashvars\s+=\s+({.+?});", res.text)

        if not match:
            raise NoStreamsError(self.url)

        flashvars = parse_json(match.group(1), "flashvars JSON")
        flashvars["uip"] = self._get_user_ip()

        levels = re.findall("setFlashLevel\((\d+)\);", res.text)
        streams = {}

        for level in levels:
            params = self._create_gox_params(flashvars, level)

            res = urlget(self.GOXLiveURL, params=params,
                         session=self.rsession)
            gox = GOXFile(res.text)

            for entry in gox.filter_entries("live"):
                try:
                    s = HDSStream.parse_manifest(self.session, entry.ref[0])
                    streams.update(s)
                except IOError:
                    self.logger.warning("Unable to parse manifest")

                break

        return streams
Example #44
0
    def _get_streams(self):
        options = self.options
        # Setting urllib up so that we can store cookies
        self.cookiejar = cookielib.LWPCookieJar()
        self.opener = urllib.build_opener(urllib.HTTPCookieProcessor(self.cookiejar))

        if options.get("cookie"):
            self.authenticate(cookie=options.get("cookie"))
        else:
            self.authenticate(options.get("username"), options.get("password"))

        streams = {}
        qualities = ["HQ", "SQ", "HQTest", "SQTest"]
        streamChoice = "both"

        response = self.grabLivePage(self.url)

        goxUrls = []
        validGoxFound = False
        failedGoxAll = False
        for quality in qualities:
            urls = self.parseHTML(response, quality)

            for url in urls:
                # Grab the response of the URL listed on the Live page for a stream
                goxFile = urlget(url, opener=self.opener)

                # The response for the GOX XML if an incorrect stream quality is chosen is 1002.
                if goxFile != "1002" and goxFile != "":
                    streamUrl = self.parseStreamURL(goxFile)
                    req = urllib.Request(streamUrl, headers={"User-Agent": "KPeerClient"})
                    streams[quality] = HTTPStream(self.session, req)
                    validGoxFound = True

        return streams
Example #45
0
    def _get_streams(self):
        self.rsession = requests.session()
        options = self.options

        if options.get("cookie"):
            self._authenticate(cookies=options.get("cookie"))
        else:
            self._authenticate(options.get("username"),
                               options.get("password"))

        res = urlget(self.url, session=self.rsession)
        player = GomTV3(self.url, res, self.rsession)
        streams = {}

        if "/vod/" in self.url:
            return player.get_vod_streams()
        else:
            try:
                streams.update(player.get_live_streams())
            except NoStreamsError:
                pass

            try:
                streams.update(player.get_alt_live_streams())
            except NoStreamsError:
                pass

            try:
                streams.update(player.get_limelight_live_streams())
            except NoStreamsError:
                pass

        return streams
Example #46
0
    def _get_streams(self, type):
        if type not in (None, StreamType.HTTP):
            return {}

        self.rsession = requests.session(prefetch=True)

        options = self.options
        if options.get("cookie"):
            self._authenticate(cookies=options.get("cookie"))
        else:
            self._authenticate(options.get("username"), options.get("password"))

        streams = {}
        qualities = ["HQ", "SQ", "HQTest", "SQTest"]

        res = self._get_live_page(self.url)
        goxurl = self._find_gox_url(res.text)

        if not goxurl:
            raise PluginError("Unable to find GOX URL")

        for quality in qualities:
            # Grab the response of the URL listed on the Live page for a stream
            url = goxurl.format(quality=quality)
            res = urlget(url, session=self.rsession)

            # The response for the GOX XML if an incorrect stream quality is chosen is 1002.
            if res.text != "1002" and len(res.text) > 0:
                streamurl = self._parse_gox_file(res.text)
                streams[quality.lower()] = HTTPStream(self.session, streamurl,
                                                      headers=self.StreamHeaders)


        return streams
Example #47
0
    def download_chunk(self, chunk_id):
        self.stream.logger.debug("[{0}] Downloading chunk".format(chunk_id))
        url = self.format_chunk_url(chunk_id)

        attempts = 3
        while attempts and self.running:
            try:
                res = urlget(url, stream=True, exception=IOError, timeout=10)
                break
            except IOError as err:
                self.stream.logger.error("[{0}] Failed to open chunk: {1}".format(
                                         chunk_id, err))
                attempts -= 1
        else:
            return

        while self.running:
            try:
                data = res.raw.read(8192)
            except IOError as err:
                self.stream.logger.error("[{0}] Failed to read chunk {1}".format(
                                         chunk_id, err))
                break

            if not data:
                break

            if not self.header_written:
                flv_header = Header(has_video=True, has_audio=True)
                self.stream.buffer.write(flv_header.serialize())
                self.header_written = True

            self.stream.buffer.write(data)
Example #48
0
    def _get_streams(self):
        self.logger.debug("Fetching stream info")
        res = urlget(self.url)

        match = re.search(
            "flashplayer: \"(.+.swf)\".+streamer: \"(.+)\".+file: \"(.+).flv\"",
            res.text, re.DOTALL)
        if not match:
            raise NoStreamsError(self.url)

        rtmp = match.group(2)
        playpath = match.group(3)
        swfurl = match.group(1)

        streams = {}
        streams["live"] = RTMPStream(self.session, {
            "rtmp": rtmp,
            "pageUrl": self.url,
            "swfVfy": swfurl,
            "playpath": playpath,
            "live": True
        },
                                     redirect=True)

        return streams
Example #49
0
    def get_live_streams(self):
        res = self._get_live_page(self.res)

        match = re.search("flashvars\s+=\s+({.+?});", res.text)

        if not match:
            raise NoStreamsError(self.url)

        flashvars = parse_json(match.group(1), "flashvars JSON")
        flashvars["uip"] = self._get_user_ip()

        levels = re.findall("setFlashLevel\((\d+)\);", res.text)
        streams = {}

        for level in levels:
            params = self._create_gox_params(flashvars, level)

            res = urlget(self.GOXLiveURL, params=params, session=self.rsession)
            gox = GOXFile(res.text)

            for entry in gox.filter_entries("live"):
                try:
                    s = HDSStream.parse_manifest(self.session, entry.ref[0])
                    streams.update(s)
                except IOError:
                    self.logger.warning("Unable to parse manifest")

                break

        return streams
Example #50
0
    def _get_streams(self):
        channelid = urlparse(self.url).path.rstrip("/").rpartition("/")[-1].lower()

        self.logger.debug("Fetching stream info")
        headers = {"Referer": self.url}
        options = dict(id=channelid)
        res = urlget(self.StreamInfoURL, headers=headers, params=options)
        json = res_json(res, "stream info JSON")

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

        if not ("rtmp" in json and "streamname" in json):
            raise NoStreamsError(self.url)

        if not RTMPStream.is_usable(self.session):
            raise PluginError("rtmpdump is not usable and required by Owncast plugin")

        rtmp = json["rtmp"]
        playpath = json["streamname"]

        streams = {}
        streams["live"] = RTMPStream(
            self.session, {"rtmp": rtmp, "pageUrl": self.url, "swfUrl": self.SWFURL, "playpath": playpath, "live": True}
        )

        return streams
Example #51
0
    def _get_rtmp_streams(self, channelname):
        options = dict(l="info",
                       a="xmlClipPath",
                       clip_id=channelname,
                       rid=time())
        res = urlget(self.APIURL, params=options)

        dom = res_xml(res)
        rtmpurl = dom.getElementsByTagName("url")
        rtmp = None

        if len(rtmpurl) > 0:
            rtmp = get_node_text(rtmpurl[0])
        else:
            raise PluginError(
                ("No RTMP Streams found on URL {0}").format(self.url))

        rtmplist = {}
        rtmplist["live"] = RTMPStream(self.session, {
            "rtmp": rtmp,
            "swfVfy": self.SWFURL,
            "live": True
        })

        return rtmplist
Example #52
0
    def _get_channel_info(self, url):
        self.logger.debug("Fetching channel info")

        res = urlget(url)
        data = res.text

        channelid = None
        swfurl = None

        match = re.search('flashvars.config = "livecfg/(\d+)', data)
        if match:
            channelid = int(match.group(1))

        match = re.search("document.location.hash='/live/(\d+)'", data)
        if match:
            channelid = int(match.group(1))

        match = re.search("xajax_load_live_config\((\d+),", data)
        if match:
            channelid = int(match.group(1))

        match = re.search("""swfobject.embedSWF\(\n.+"(.+)", "player",""", data)
        if match:
            swfurl = match.group(1)

        return (channelid, swfurl)
Example #53
0
    def download_chunk(self, chunk_id):
        self.stream.logger.debug("[{0}] Downloading chunk".format(chunk_id))
        url = self.format_chunk_url(chunk_id)

        attempts = 3
        while attempts and self.running:
            try:
                res = urlget(url, stream=True, exception=IOError, timeout=10)
                break
            except IOError as err:
                self.stream.logger.error("[{0}] Failed to open chunk: {1}".format(
                                         chunk_id, err))
                attempts -= 1
        else:
            return

        while self.running:
            try:
                data = res.raw.read(8192)
            except IOError as err:
                self.stream.logger.error("[{0}] Failed to read chunk {1}".format(
                                         chunk_id, err))
                break

            if not data:
                break

            if not self.header_written:
                flv_header = Header(has_video=True, has_audio=True)
                self.stream.buffer.write(flv_header.serialize())
                self.header_written = True

            self.stream.buffer.write(data)
Example #54
0
    def _get_streams(self):
        res = urlget(self.url, headers=HEADERS)

        match = re.search(URL_REGEX, res.text)
        if match:
            url = match.group(0)
            plugin = self.session.resolve_url(url)
            return plugin.get_streams()
Example #55
0
    def _get_channel_id(self, url):
        match = re.search("ustream.tv/embed/(\d+)", url)
        if match:
            return int(match.group(1))

        match = re.search("\"cid\":(\d+)", urlget(url).text)
        if match:
            return int(match.group(1))