Exemplo n.º 1
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 = http.get(swfurl)
        swf = swfdecompress(res.content)
        match = re.search("customURL[^h]+(https://.*?)\\\\", swf)

        if not match:
            raise NoStreamsError(self.url)

        res = http.get(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)
Exemplo n.º 2
0
    def _get_streams(self):
        self.channelname = self._get_channel_name(self.url)

        if not self.channelname:
            raise NoStreamsError(self.url)

        streams = {}

        if RTMPStream.is_usable(self.session):
            try:
                rtmpstreams = self._get_rtmp_streams()
                streams.update(rtmpstreams)
            except PluginError as err:
                self.logger.error("Error when fetching RTMP stream info: {0}", str(err))
        else:
            self.logger.warning("rtmpdump is not usable, only HLS streams will be available")

        try:
            hlsstreams = self._get_hls_streams()

            for name, stream in hlsstreams.items():
                if name in streams:
                    streams[name] = [streams[name], stream]
                else:
                    streams[name] = stream

        except PluginError as err:
            self.logger.error("Error when fetching HLS stream info: {0}", str(err))

        return streams
Exemplo n.º 3
0
    def _get_live_streams(self, *args, **kwargs):
        streams = defaultdict(list)

        if RTMPStream.is_usable(self.session):
            try:
                for name, stream in self._get_desktop_streams(*args, **kwargs).items():
                    streams[name].append(stream)

            except PluginError as err:
                self.logger.error("Error when fetching desktop streams: {0}",
                                  err)
            except NoStreamsError:
                pass
        else:
            self.logger.warning("rtmpdump is required to access the desktop "
                                "streams, but it could not be found")

        try:
            for name, stream in self._get_mobile_streams(*args, **kwargs).items():
                # Justin.tv streams have a iphone prefix, so let's
                # strip it to keep it consistent with Twitch.
                name = name.replace("iphone", "")
                streams[name].append(stream)

        except PluginError as err:
            self.logger.error("Error when fetching mobile streams: {0}",
                              err)
        except NoStreamsError:
            pass

        return streams
Exemplo n.º 4
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
Exemplo n.º 5
0
    def _get_streams(self):
        self.channelname = self._get_channel_name(self.url)

        if not self.channelname:
            raise NoStreamsError(self.url)

        streams = {}

        if RTMPStream.is_usable(self.session):
            try:
                rtmpstreams = self._get_rtmp_streams()
                streams.update(rtmpstreams)
            except PluginError as err:
                self.logger.error("Error when fetching RTMP stream info: {0}", str(err))
        else:
            self.logger.warning("rtmpdump is not usable, only HLS streams will be available")

        try:
            hlsstreams = self._get_hls_streams()
            if len(streams) > 0:
                hlssuffix = "_hls"
            else:
                hlssuffix = ""

            for name, stream in hlsstreams.items():
                streams[name + hlssuffix] = stream
        except PluginError as err:
            self.logger.error("Error when fetching HLS stream info: {0}", str(err))

        return streams
Exemplo n.º 6
0
    def _get_live_streams(self):
        streams = defaultdict(list)

        if RTMPStream.is_usable(self.session):
            try:
                for name, stream in self._get_desktop_streams().items():
                    streams[name].append(stream)

            except PluginError as err:
                self.logger.error("Error when fetching desktop streams: {0}",
                                  err)
            except NoStreamsError:
                pass
        else:
            self.logger.warning("rtmpdump is not usable, "
                                "only mobile streams may be available")

        try:
            for name, stream in self._get_mobile_streams().items():
                # Justin.tv streams have a iphone prefix, so let's
                # strip it to keep it consistent with Twitch.
                name = name.replace("iphone", "")
                streams[name].append(stream)

        except PluginError as err:
            self.logger.error("Error when fetching mobile streams: {0}",
                              err)
        except NoStreamsError:
            pass

        return streams
Exemplo n.º 7
0
    def _get_streams(self):
        if not RTMPStream.is_usable(self.session):
            raise PluginError("rtmpdump is not usable and required by Filmon plugin")

        self.logger.debug("Fetching stream info")
        self.rsession = requests.session()
        res = urlget(self.url, session=self.rsession)

        match = re.search("movie_id=(\d+)", res.text)
        if match:
            return self._get_vod_stream(match.group(1))

        match = re.search("/channels/(\d+)/extra_big_logo.png", res.text)
        if not match:
            return

        channel_id = match.group(1)
        streams = {}
        for quality in ("low", "high"):
            try:
                streams[quality] = self._get_stream(channel_id, quality)
            except NoStreamsError:
                pass

        return streams
Exemplo n.º 8
0
    def _get_streams(self, type):
        self.channelname = self._get_channel_name(self.url)

        if not self.channelname:
            raise NoStreamsError(self.url)

        streams = {}
        
        if type in (None, StreamType.RTMP):
            if RTMPStream.is_usable(self.session):
                try:
                    rtmpstreams = self._get_rtmp_streams()
                    streams.update(rtmpstreams)
                except PluginError as err:
                    self.logger.error("Error when fetching RTMP stream info: {0}", str(err))
            else:
                self.logger.warning("rtmpdump is not usable, only HLS streams will be available")

        if type in (None, StreamType.HLS):
            try:
                hlsstreams = self._get_hls_streams()
                if len(streams) > 0:
                    hlssuffix = "_hls"
                else:
                    hlssuffix = ""

                for name, stream in hlsstreams.items():
                    streams[name + hlssuffix] = stream
            except PluginError as err:
                self.logger.error("Error when fetching HLS stream info: {0}", str(err))

        return streams
Exemplo n.º 9
0
    def _get_streams(self):
        if not RTMPStream.is_usable(self.session):
            self.logger.warning("rtmpdump is not usable, only HDS streams will be available")

        self.logger.debug("Fetching stream info")
        match = re.search("/\w*/(live|video)*/(\d+)", self.url)
        if not match:
            return

        stream_id = match.group(2)
        res = http.get(API_URL, params=dict(ak="web", id=stream_id))
        root = parse_xml(res.text.encode("utf8"))

        streams = {}
        for formitaet in root.iter('formitaet'):
            url = formitaet.find('url').text
            quality = formitaet.find('quality').text

            if formitaet.get('basetype') == "h264_aac_f4f_http_f4m_http":
                hds_streams = HDSStream.parse_manifest(self.session, url)
                streams.update(hds_streams)
            elif formitaet.get('basetype') == 'h264_aac_mp4_rtmp_zdfmeta_http':
                streams[quality] = RTMPStream(self.session, {
                    "rtmp": self._get_stream(url),
                    "pageUrl": self.url,
                })

        return streams
Exemplo n.º 10
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 = http.get(swfurl)
        swf = swfdecompress(res.content)
        match = re.search("customURL[^h]+(https://.*?)\\\\", swf)

        if not match:
            raise NoStreamsError(self.url)

        res = http.get(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)
Exemplo n.º 11
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
Exemplo n.º 12
0
    def _get_streams(self):
        if not RTMPStream.is_usable(self.session):
            raise PluginError(
                "rtmpdump is not usable and required by Filmon plugin")

        self.logger.debug("Fetching stream info")
        res = http.get(self.url)

        match = re.search("movie_id=(\d+)", res.text)
        if match:
            return self._get_vod_stream(match.group(1))

        match = re.search("/channels/(\d+)/extra_big_logo.png", res.text)
        if not match:
            return

        channel_id = match.group(1)
        streams = {}
        for quality in ("low", "high"):
            try:
                streams[quality] = self._get_stream(channel_id, quality)
            except NoStreamsError:
                pass

        return streams
Exemplo n.º 13
0
    def _get_streams(self):
        self.logger.debug("Fetching stream info")
        res = urlget(self.url)

        match = re.search("var current_channel = (.*);", res.text)
        if match:
            json = parse_json(match.group(1))
        else:
            raise NoStreamsError(self.url)

        if not isinstance(json, dict):
            raise PluginError("Invalid JSON response")
        elif not "streams" in json:
            raise NoStreamsError(self.url)

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

        match = re.search("var flash_config = (.*);", res.text)
        if match:
            config = parse_json(match.group(1))
            if "streamer" in config:
                self.SWFURL = urljoin(self.SWFURL, config["streamer"])

        streams = {}

        for stream in json["streams"]:
            if not ("url" in stream and "name" in stream):
                continue

            parsed = urlparse(stream["url"])

            if not parsed.scheme.startswith("rtmp"):
                continue

            if parsed.query:
                app = "{0}?{1}".format(parsed.path[1:], parsed.query)
            else:
                app = parsed.path[1:]

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

        return streams
Exemplo n.º 14
0
    def _get_streams(self):
        # If email option given, try to login
        if self.options.get("email"):
            res = http.get(self.LOGINPAGEURL)
            match = re.search('<meta content="([^"]+)" name="csrf-token"',
                              res.text)
            if not match:
                raise PluginError("Missing CSRF Token: " + self.LOGINPAGEURL)
            csrf_token = match.group(1)

            email = self.options.get("email")
            password = self.options.get("password")

            res = http.post(
                self.LOGINPOSTURL,
                data={
                    'authenticity_token': csrf_token,
                    'channel_id': '',
                    'commit': 'Login',
                    'plan_id': '',
                    'session[email]': email,
                    'session[password]': password,
                    'utf8': "\xE2\x9C\x93",  # Check Mark Character
                })

            self.logger.debug("Login account info: {0}", res.text)
            result = http.json(res)
            if result.get('email', 'no-mail') != email:
                raise PluginError("Invalid account")

        res = http.get(self.url)

        streams = {}

        if RTMPStream.is_usable(self.session):
            try:
                rtmpstreams = self._get_rtmp_streams(res.text)
                streams.update(rtmpstreams)
            except PluginError as err:
                self.logger.error("Error when fetching RTMP stream info: {0}",
                                  str(err))
        else:
            self.logger.warning(
                "rtmpdump is not usable, only HLS streams will be available")

        try:
            hlsstreams = self._get_hls_streams(res.text)
            streams.update(hlsstreams)
        except PluginError as err:
            self.logger.error("Error when fetching HLS stream info: {0}",
                              str(err))

        return streams
Exemplo n.º 15
0
    def _get_streams_from_rtmp(self):
        password = self.options.get("password")
        module_info = self._get_module_info("channel", self.channel_id,
                                            password)
        if not module_info:
            raise NoStreamsError(self.url)

        providers = module_info.get("stream")
        if providers == "offline":
            raise NoStreamsError(self.url)
        elif not isinstance(providers, list):
            raise PluginError("Invalid stream info: {0}".format(providers))

        streams = {}
        for provider in filter(valid_provider, providers):
            provider_url = provider.get("url")
            provider_name = provider.get("name")
            provider_streams = provider.get("streams")

            for stream_index, stream_info in enumerate(provider_streams):
                stream = None
                stream_height = int(stream_info.get("height", 0))
                stream_name = stream_info.get("description")

                if not stream_name:
                    if stream_height:
                        if not stream_info.get("isTranscoded"):
                            stream_name = "{0}p+".format(stream_height)
                        else:
                            stream_name = "{0}p".format(stream_height)
                    else:
                        stream_name = "live"

                if stream_name in streams:
                    provider_name_clean = provider_name.replace("uhs_", "")
                    stream_name += "_alt_{0}".format(provider_name_clean)

                if provider_name.startswith("uhs_"):
                    stream = UHSStream(self.session, self.channel_id,
                                       self.url, provider_name,
                                       stream_index, password)
                elif (provider_url.startswith("rtmp") and
                      RTMPStream.is_usable(self.session)):
                        playpath = stream_info.get("streamName")
                        stream = self._create_rtmp_stream(provider_url,
                                                          playpath)

                if stream:
                    streams[stream_name] = stream

        return streams
Exemplo n.º 16
0
    def _get_streams(self):
        self.logger.debug("Fetching stream info")
        res = urlget(self.url)

        match = re.search("var current_channel = (.*);", res.text)
        if match:
            json = parse_json(match.group(1))
        else:
            raise NoStreamsError(self.url)

        if not isinstance(json, dict):
            raise PluginError("Invalid JSON response")
        elif not "streams" in json:
            raise NoStreamsError(self.url)

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

        match = re.search("var flash_config = (.*);", res.text)
        if match:
            config = parse_json(match.group(1))
            if "streamer" in config:
                self.SWFURL = urljoin(self.SWFURL, config["streamer"])

        streams = {}

        for stream in json["streams"]:
            if not ("url" in stream and "name" in stream):
                continue

            parsed = urlparse(stream["url"])

            if not parsed.scheme.startswith("rtmp"):
                continue

            if parsed.query:
                app = "{0}?{1}".format(parsed.path[1:], parsed.query)
            else:
                app = parsed.path[1:]

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

        return streams
Exemplo n.º 17
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
Exemplo n.º 18
0
    def _get_streams(self):
        # If email option given, try to login
        if self.options.get("email"):
            res = http.get(self.LOGINPAGEURL)
            match = re.search('<meta content="([^"]+)" name="csrf-token"', res.text)
            if not match:
                raise PluginError("Missing CSRF Token: " + self.LOGINPAGEURL)
            csrf_token = match.group(1)

            email = self.options.get("email")
            password = self.options.get("password")

            res = http.post(
                self.LOGINPOSTURL,
                data={
                    "authenticity_token": csrf_token,
                    "channel_id": "",
                    "commit": "Login",
                    "plan_id": "",
                    "session[email]": email,
                    "session[password]": password,
                    "utf8": "\xE2\x9C\x93",  # Check Mark Character
                },
            )

            self.logger.debug("Login account info: {0}", res.text)
            result = http.json(res)
            if result.get("email", "no-mail") != email:
                raise PluginError("Invalid account")

        res = http.get(self.url)

        streams = {}

        if RTMPStream.is_usable(self.session):
            try:
                rtmpstreams = self._get_rtmp_streams(res.text)
                streams.update(rtmpstreams)
            except PluginError as err:
                self.logger.error("Error when fetching RTMP stream info: {0}", str(err))
        else:
            self.logger.warning("rtmpdump is not usable, only HLS streams will be available")

        try:
            hlsstreams = self._get_hls_streams(res.text)
            streams.update(hlsstreams)
        except PluginError as err:
            self.logger.error("Error when fetching HLS stream info: {0}", str(err))

        return streams
Exemplo n.º 19
0
    def _get_streams_from_rtmp(self):
        password = self.options.get("password")
        module_info = self._get_module_info("channel", self.channel_id,
                                            password)
        if not module_info:
            raise NoStreamsError(self.url)

        providers = module_info.get("stream")
        if providers == "offline":
            raise NoStreamsError(self.url)
        elif not isinstance(providers, list):
            raise PluginError("Invalid stream info: {0}".format(providers))

        streams = {}
        for provider in filter(valid_provider, providers):
            provider_url = provider.get("url")
            provider_name = provider.get("name")
            provider_streams = provider.get("streams")

            for stream_index, stream_info in enumerate(provider_streams):
                stream = None
                stream_height = int(stream_info.get("height", 0))
                stream_name = stream_info.get("description")

                if not stream_name:
                    if stream_height:
                        if not stream_info.get("isTranscoded"):
                            stream_name = "{0}p+".format(stream_height)
                        else:
                            stream_name = "{0}p".format(stream_height)
                    else:
                        stream_name = "live"

                if stream_name in streams:
                    provider_name_clean = provider_name.replace("uhs_", "")
                    stream_name += "_alt_{0}".format(provider_name_clean)

                if provider_name.startswith("uhs_"):
                    stream = UHSStream(self.session, self.channel_id, self.url,
                                       provider_name, stream_index, password)
                elif (provider_url.startswith("rtmp")
                      and RTMPStream.is_usable(self.session)):
                    playpath = stream_info.get("streamName")
                    stream = self._create_rtmp_stream(provider_url, playpath)

                if stream:
                    streams[stream_name] = stream

        return streams
Exemplo n.º 20
0
    def _get_streams_from_amf(self):
        if not RTMPStream.is_usable(self.session):
            raise NoStreamsError(self.url)

        res = urlget(AMF_URL.format(self.channel_id))

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

        for message in packet.messages:
            if message.target_uri == "/1/onResult":
                result = message.value
                break
        else:
            raise PluginError("No result found in AMF packet")

        streams = {}
        stream_name = result.get("streamName")
        if stream_name:
            cdn = result.get("cdnUrl") or result.get("fmsUrl")
            if cdn:
                stream = self._create_rtmp_stream(cdn, stream_name)

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

                streams[stream_name] = stream
            else:
                self.logger.warning("Missing cdnUrl and fmsUrl from result")

        stream_versions = result.get("streamVersions")
        if stream_versions:
            for version, info in stream_versions.items():
                stream_version_cdn = info.get("streamVersionCdn", {})

                for name, cdn in filter(valid_cdn, stream_version_cdn.items()):
                    stream = self._create_rtmp_stream(cdn["cdnStreamUrl"],
                                                      cdn["cdnStreamName"])
                    stream_name = "live_alt_{0}".format(name)
                    streams[stream_name] = stream

        return streams
Exemplo n.º 21
0
 def _get_streams(self):
     params = parse_qsd(urlparse(self.url).query)
     if not 'watch' in params:
         raise NoStreamsError(self.url)
     channel = params['watch']
     
     if not RTMPStream.is_usable(self.session):
         raise PluginError("rtmpdump is not usable but required by Picarto plugin")
     
     streams = {}
     streams["live"] = RTMPStream(self.session, {
         "rtmp": "rtmp://199.189.86.17/dsapp/{0}.flv".format(channel),
         "pageUrl": self.url,
         "live": True
     })
     return streams
Exemplo n.º 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
Exemplo n.º 23
0
    def _get_streams_from_amf(self):
        if not RTMPStream.is_usable(self.session):
            raise NoStreamsError(self.url)

        res = urlget(AMF_URL.format(self.channel_id))

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

        for message in packet.messages:
            if message.target_uri == "/1/onResult":
                result = message.value
                break
        else:
            raise PluginError("No result found in AMF packet")

        streams = {}
        stream_name = result.get("streamName")
        if stream_name:
            cdn = result.get("cdnUrl") or result.get("fmsUrl")
            if cdn:
                stream = self._create_rtmp_stream(cdn, stream_name)

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

                streams[stream_name] = stream
            else:
                self.logger.warning("Missing cdnUrl and fmsUrl from result")

        stream_versions = result.get("streamVersions")
        if stream_versions:
            for version, info in stream_versions.items():
                stream_version_cdn = info.get("streamVersionCdn", {})

                for name, cdn in filter(valid_cdn, stream_version_cdn.items()):
                    stream = self._create_rtmp_stream(cdn["cdnStreamUrl"],
                                                      cdn["cdnStreamName"])
                    stream_name = "live_alt_{0}".format(name)
                    streams[stream_name] = stream

        return streams
Exemplo n.º 24
0
    def _get_streams(self):
        country_code = urlparse(self.url).netloc.split(".")[0]

        self.logger.debug("Fetching stream info")
        res = http.get(self.APIURL)
        json = http.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 = http.get(self.GEOIPURL)
            geo = http.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
Exemplo n.º 25
0
    def _get_streams(self):
        params = parse_qsd(urlparse(self.url).query)
        if not 'watch' in params:
            raise NoStreamsError(self.url)
        channel = params['watch']

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

        streams = {}
        streams["live"] = RTMPStream(
            self.session, {
                "rtmp": "rtmp://199.189.86.17/dsapp/{0}.flv".format(channel),
                "pageUrl": self.url,
                "live": True
            })
        return streams
Exemplo n.º 26
0
    def _get_streams(self):
        self.channelname = self._get_channel_name(self.url)

        if not self.channelname:
            raise NoStreamsError(self.url)

        streams = {}

        if RTMPStream.is_usable(self.session):
            try:
                rtmpstreams = self._get_rtmp_streams()

                for name, stream in rtmpstreams.items():
                    if "iphone" in name:
                        name = name.replace("iphone", "mobile_")

                    streams[name] = stream
            except PluginError as err:
                self.logger.error("Error when fetching RTMP stream info: {0}",
                                  str(err))
        else:
            self.logger.warning(
                "rtmpdump is not usable, only HLS streams will be available")

        try:
            hlsstreams = self._get_hls_streams()

            for name, stream in hlsstreams.items():
                if name in ("high", "low"):
                    name = "mobile_{0}".format(name)

                if "iphone" in name:
                    name = name.replace("iphone", "mobile_")

                if name in streams:
                    streams[name] = [streams[name], stream]
                else:
                    streams[name] = stream

        except PluginError as err:
            self.logger.error("Error when fetching HLS stream info: {0}",
                              str(err))

        return streams
Exemplo n.º 27
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
Exemplo n.º 28
0
    def _get_streams(self):
        res = urlget(self.url)
        streams = {}

        if RTMPStream.is_usable(self.session):
            try:
                rtmpstreams = self._get_rtmp_streams(res.text)
                streams.update(rtmpstreams)
            except PluginError as err:
                self.logger.error("Error when fetching RTMP stream info: {0}", str(err))
        else:
            self.logger.warning("rtmpdump is not usable, only HLS streams will be available")

        try:
            hlsstreams = self._get_hls_streams(res.text)
            streams.update(hlsstreams)
        except PluginError as err:
            self.logger.error("Error when fetching HLS stream info: {0}", str(err))

        return streams
Exemplo n.º 29
0
    def _get_streams(self):
        if not RTMPStream.is_usable(self.session):
            raise PluginError("rtmpdump is not usable and required by Filmon_us plugin")

        streams = {}

        try:
            # history video
            if "filmon.us/history" in self.url or "filmon.us/video/history/hid" in self.url:
                streams['default'] = self._get_history()
            # uploaded video
            elif "filmon.us/video" in self.url:
                streams['default'] = self._get_stream_upload()
            # live video
            else:
                streams['default'] = self._get_stream_live()
        except NoStreamsError:
            pass

        return streams
Exemplo n.º 30
0
    def _get_streams(self):
        channelname = urlparse(self.url).path.rstrip("/").rpartition("/")[-1].lower()
        streams = {}

        if RTMPStream.is_usable(self.session):
            try:
                rtmpstreams = self._get_rtmp_streams(channelname)
                streams.update(rtmpstreams)
            except PluginError as err:
                self.logger.error("Error when fetching RTMP stream info: {0}", str(err))
        else:
            self.logger.warning("rtmpdump is not usable, only HLS streams will be available")

        try:
            hlsstreams = self._get_hls_streams(channelname)
            streams.update(hlsstreams)
        except PluginError as err:
            self.logger.error("Error when fetching HLS stream info: {0}", str(err))

        return streams
Exemplo n.º 31
0
    def _get_streams(self):
        self.channelname = self._get_channel_name(self.url)

        if not self.channelname:
            raise NoStreamsError(self.url)

        streams = {}

        if RTMPStream.is_usable(self.session):
            try:
                rtmpstreams = self._get_rtmp_streams()

                for name, stream in rtmpstreams.items():
                    if "iphone" in name:
                        name = name.replace("iphone", "mobile_")

                    streams[name] = stream
            except PluginError as err:
                self.logger.error("Error when fetching RTMP stream info: {0}", str(err))
        else:
            self.logger.warning("rtmpdump is not usable, only HLS streams will be available")

        try:
            hlsstreams = self._get_hls_streams()

            for name, stream in hlsstreams.items():
                if name in ("high", "low"):
                    name = "mobile_{0}".format(name)

                if "iphone" in name:
                    name = name.replace("iphone", "mobile_")

                if name in streams:
                    streams[name] = [streams[name], stream]
                else:
                    streams[name] = stream

        except PluginError as err:
            self.logger.error("Error when fetching HLS stream info: {0}", str(err))

        return streams
Exemplo n.º 32
0
    def _get_streams(self):
        if not RTMPStream.is_usable(self.session):
            raise PluginError(
                "rtmpdump is not usable and required by Filmon_us plugin")

        streams = {}

        try:
            # history video
            if "filmon.us/history" in self.url or "filmon.us/video/history/hid" in self.url:
                streams['default'] = self._get_history()
            # uploaded video
            elif "filmon.us/video" in self.url:
                streams['default'] = self._get_stream_upload()
            # live video
            else:
                streams['default'] = self._get_stream_live()
        except NoStreamsError:
            pass

        return streams
Exemplo n.º 33
0
    def _get_streams(self):
        if not RTMPStream.is_usable(self.session):
            raise PluginError("rtmpdump is not usable and required by Hashd plugin")

        self.logger.debug("Fetching stream info")
        res = http.get(self.url.rstrip("/").lower()+".json?first=true")
        json = http.json(res)

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

        if "file" in json:
            streams = self._parse_vod(json)
        elif json["live"]:
            streams = self._parse_live(json)
        else:
            raise NoStreamsError(self.url)

        return streams
Exemplo n.º 34
0
    def _get_streams(self):
        if not RTMPStream.is_usable(self.session):
            raise PluginError("rtmpdump is not usable and required by Furstream plugin")

        self.logger.debug("Fetching stream info")
        res = http.get(self.url)

        match = re.search("rtmp://(?:(?!\").)*", res.text)
        if match:
            self.logger.debug("Stream URL: " + match.group(0))
            rtmp = match.group(0)
        else:
            return

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

        return streams
Exemplo n.º 35
0
    def _get_live_streams(self):
        self.channel_id = self._get_channel_id(self.url)

        if not self.channel_id:
            raise NoStreamsError(self.url)

        streams = defaultdict(list)

        if not RTMPStream.is_usable(self.session):
            self.logger.warning("rtmpdump is not usable. "
                                "Not all streams may be available.")

        if HAS_LIBRTMP:
            desktop_streams = self._get_streams_from_rtmp
        else:
            self.logger.warning("python-librtmp is not installed. "
                                "Not all streams may be available.")
            desktop_streams = self._get_streams_from_amf

        try:
            for name, stream in desktop_streams().items():
                streams[name].append(stream)
        except PluginError as err:
            self.logger.error("Unable to fetch desktop streams: {0}", err)
        except NoStreamsError:
            pass

        try:
            mobile_streams = self._get_hls_streams(
                wait_for_transcode=not streams)
            for name, stream in mobile_streams.items():
                streams[name].append(stream)
        except PluginError as err:
            self.logger.error("Unable to fetch mobile streams: {0}", err)
        except NoStreamsError:
            pass

        return streams
Exemplo n.º 36
0
    def _get_streams(self):
        res = urlget(self.url)
        streams = {}

        if RTMPStream.is_usable(self.session):
            try:
                rtmpstreams = self._get_rtmp_streams(res.text)
                streams.update(rtmpstreams)
            except PluginError as err:
                self.logger.error("Error when fetching RTMP stream info: {0}",
                                  str(err))
        else:
            self.logger.warning(
                "rtmpdump is not usable, only HLS streams will be available")

        try:
            hlsstreams = self._get_hls_streams(res.text)
            streams.update(hlsstreams)
        except PluginError as err:
            self.logger.error("Error when fetching HLS stream info: {0}",
                              str(err))

        return streams
Exemplo n.º 37
0
    def _get_live_streams(self):
        self.channel_id = self._get_channel_id(self.url)

        if not self.channel_id:
            raise NoStreamsError(self.url)

        streams = defaultdict(list)

        if not RTMPStream.is_usable(self.session):
            self.logger.warning("rtmpdump is not usable. "
                                "Not all streams may be available.")

        if HAS_LIBRTMP:
            desktop_streams = self._get_streams_from_rtmp
        else:
            self.logger.warning("python-librtmp is not installed. "
                                "Not all streams may be available.")
            desktop_streams = self._get_streams_from_amf

        try:
            for name, stream in desktop_streams().items():
                streams[name].append(stream)
        except PluginError as err:
            self.logger.error("Unable to fetch desktop streams: {0}", err)
        except NoStreamsError:
            pass

        try:
            mobile_streams = self._get_hls_streams(wait_for_transcode=not streams)
            for name, stream in mobile_streams.items():
                streams[name].append(stream)
        except PluginError as err:
            self.logger.error("Unable to fetch mobile streams: {0}", err)
        except NoStreamsError:
            pass

        return streams
Exemplo n.º 38
0
    def _get_streams(self):
        if not RTMPStream.is_usable(self.session):
            raise PluginError(
                "rtmpdump is not usable and required by Cybergame plugin")

        if "/videos/" in self.url:
            return self._get_vod_streams()

        self.logger.debug("Fetching live stream info")
        res = http.get(self.url)

        match = re.search("channel=([^\"]+)", res.text)
        if not match:
            raise NoStreamsError(self.url)

        channelname = match.group(1)

        res = http.get(CONFIG_URL, params=dict(c=channelname, ports="y"))
        json = http.json(res)
        servers = json.get("servers")
        if not servers:
            raise NoStreamsError(self.url)

        alternative = ""
        streams = {}

        for server in servers:
            srv, port = server.split(":")
            params = dict(channel=channelname, server=srv, port=port)
            tmpstreams = self._get_rtmp_streams(params, alternative)
            streams.update(tmpstreams)
            if not alternative:
                alternative = "_alt"
            else:
                break

        return streams
Exemplo n.º 39
0
    def _get_streams(self):
        channelname = urlparse(
            self.url).path.rstrip("/").rpartition("/")[-1].lower()
        streams = {}

        if RTMPStream.is_usable(self.session):
            try:
                rtmpstreams = self._get_rtmp_streams(channelname)
                streams.update(rtmpstreams)
            except PluginError as err:
                self.logger.error("Error when fetching RTMP stream info: {0}",
                                  str(err))
        else:
            self.logger.warning(
                "rtmpdump is not usable, only HLS streams will be available")

        try:
            hlsstreams = self._get_hls_streams(channelname)
            streams.update(hlsstreams)
        except PluginError as err:
            self.logger.error("Error when fetching HLS stream info: {0}",
                              str(err))

        return streams
Exemplo n.º 40
0
    def _get_streams(self):
        if not RTMPStream.is_usable(self.session):
            raise PluginError("rtmpdump is not usable and required by Cybergame plugin")

        if "/videos/" in self.url:
            return self._get_vod_streams()

        self.logger.debug("Fetching live stream info")
        res = http.get(self.url)

        match = re.search("channel=([^\"]+)", res.text)
        if not match:
            raise NoStreamsError(self.url)

        channelname = match.group(1)

        res = http.get(CONFIG_URL, params=dict(c=channelname, ports="y"))
        json = http.json(res)
        servers = json.get("servers")
        if not servers:
            raise NoStreamsError(self.url)

        alternative = ""
        streams  = {}

        for server in servers:
            srv, port = server.split(":")
            params = dict(channel=channelname, server=srv, port=port)
            tmpstreams = self._get_rtmp_streams(params, alternative)
            streams.update(tmpstreams)
            if not alternative:
                alternative = "_alt"
            else:
                break

        return streams
Exemplo n.º 41
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 = AMFPacket.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 RTMPStream.is_usable(self.session) and "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 RTMPStream.is_usable(self.session) and "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:
                            cdnname = "live_alt_{0}".format(name)
                            streams[cdnname] = self._create_stream(cdn["cdnStreamUrl"],
                                                                   cdn["cdnStreamName"])

        # On some channels the AMF API will not return any streams,
        # attempt to access the HLS playlist directly instead.
        #
        # HLS streams are created on demand, so we may have to wait
        # for a transcode to be started.
        attempts = 10
        playlist_url = result.get("liveHttpUrl",
                                  self.HLSPlaylistURL.format(channelid))

        while attempts:
            try:
                hls_streams = HLSStream.parse_variant_playlist(self.session,
                                                               playlist_url)
                streams.update(hls_streams)
            except IOError:
                # Channel is probably offline
                break

            if streams:
                break

            attempts -= 1
            sleep(3)

        return streams
Exemplo n.º 42
0
    def _get_streams(self):
        self.logger.debug("Fetching stream info")

        headers = {"Referer": self.url}

        res = urlget(self.url, headers=headers)
        match = re.search("flashvars.*?cid[^\d]+?(\d+)", res.text)
        if not match:
            raise NoStreamsError(self.url)

        headers = {"Referer": self.SWFURL}

        form = dict(cid=match.group(1),
                    watchTime="0",
                    firstConnect="1",
                    ip="NaN")

        res = urlopen(self.APIURL, data=form, headers=headers)

        params = parse_qsd(res.text)

        if "0" in params and int(params["0"]) <= 0:
            raise StreamError("Server refused to send required parameters.")

        rtmp = params["10"]
        playpath = params["11"]
        multibitrate = int(params["20"])
        premiumuser = params["5"]
        blocktype = int(params["13"])

        if blocktype != 0:
            if blocktype == 1:
                blocktime = params["14"]
                reconnectiontime = params["16"]
                msg = ("You have crossed free viewing limit. ",
                       "You have been blocked for %s minutes. " % blocktime,
                       "Try again in %s minutes." % reconnectiontime)
                raise StreamError(msg)
            elif blocktype == 11:
                raise StreamError("No free slots available.")

        if "73" in params:
            token = params["73"]
        else:
            raise StreamError("Server seems busy, please try after some time.")

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

        streams = {}

        if multibitrate:
            streams["low"] = RTMPStream(
                self.session, {
                    "rtmp": "{0}/{1}".format(rtmp, playpath),
                    "pageUrl": self.url,
                    "swfVfy": self.SWFURL,
                    "weeb": token,
                    "live": True
                })
            playpath += "HI"

        streams["live"] = RTMPStream(
            self.session, {
                "rtmp": "{0}/{1}".format(rtmp, playpath),
                "pageUrl": self.url,
                "swfVfy": self.SWFURL,
                "weeb": token,
                "live": True
            })

        return streams
Exemplo n.º 43
0
    def _get_streams(self):
        channelname = urlparse(self.url).path.rstrip("/").rpartition("/")[-1].lower()
        self.logger.debug("Fetching stream info")

        headers = {
            "Referer": self.SWFURL
        }

        form = dict(cid=channelname, watchTime="0",
                    firstConnect="1", ip="NaN")

        res = urlopen(self.APIURL, data=form, headers=headers)

        params = parse_qsd(res.text)

        if "0" in params and int(params["0"]) <= 0:
            raise PluginError("Server refused to send required parameters.")

        rtmp = params["10"]
        playpath = params["11"]
        multibitrate = int(params["20"])
        premiumuser = params["5"]
        blocktype = int(params["13"])

        if blocktype != 0:
            if blocktype == 1:
                blocktime = params["14"]
                reconnectiontime = params["16"]
                msg = ("You have crossed free viewing limit. ",
                       "You have been blocked for %s minutes. " % blocktime,
                       "Try again in %s minutes." % reconnectiontime)
                raise PluginError(msg)
            elif blocktype == 11:
                raise PluginError("No free slots available.")

        if "73" in params:
            token = params["73"]
        else:
            raise PluginError("Server seems busy, please try after some time.")

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

        streams = {}
        stream_name = "sd"

        if multibitrate:
            streams[stream_name] = RTMPStream(self.session, {
                "rtmp": "{0}/{1}".format(rtmp, playpath),
                "pageUrl": self.url,
                "swfVfy": self.SWFURL,
                "weeb": token,
                "live": True
            })
            playpath += "HI"
            stream_name = "hd"

        streams[stream_name] = RTMPStream(self.session, {
            "rtmp": "{0}/{1}".format(rtmp, playpath),
            "pageUrl": self.url,
            "swfVfy": self.SWFURL,
            "weeb": token,
            "live": True
        })

        return streams
Exemplo n.º 44
0
    def _get_streams(self):
        channelname = urlparse(
            self.url).path.rstrip("/").rpartition("/")[-1].lower()
        self.logger.debug("Fetching stream info")

        headers = {"Referer": self.SWFURL}

        form = dict(cid=channelname, watchTime="0", firstConnect="1", ip="NaN")

        res = http.post(self.APIURL, data=form, headers=headers)

        params = parse_qsd(res.text)

        if "0" in params and int(params["0"]) <= 0:
            raise PluginError("Server refused to send required parameters.")

        rtmp = params["10"]
        playpath = params["11"]
        multibitrate = int(params["20"])
        premiumuser = params["5"]
        blocktype = int(params["13"])

        if blocktype != 0:
            if blocktype == 1:
                blocktime = params["14"]
                reconnectiontime = params["16"]
                msg = ("You have crossed free viewing limit. ",
                       "You have been blocked for %s minutes. " % blocktime,
                       "Try again in %s minutes." % reconnectiontime)
                raise PluginError(msg)
            elif blocktype == 11:
                raise PluginError("No free slots available.")

        if "73" in params:
            token = params["73"]
        else:
            raise PluginError("Server seems busy, please try after some time.")

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

        streams = {}
        stream_name = "sd"

        if multibitrate:
            streams[stream_name] = RTMPStream(
                self.session, {
                    "rtmp": "{0}/{1}".format(rtmp, playpath),
                    "pageUrl": self.url,
                    "swfVfy": self.SWFURL,
                    "weeb": token,
                    "live": True
                })
            playpath += "HI"
            stream_name = "hd"

        streams[stream_name] = RTMPStream(
            self.session, {
                "rtmp": "{0}/{1}".format(rtmp, playpath),
                "pageUrl": self.url,
                "swfVfy": self.SWFURL,
                "weeb": token,
                "live": True
            })

        return streams