示例#1
0
 def test_rtmp_stream(self):
     stream = RTMPStream(self.session, {"rtmp": "rtmp://test.se/app/play_path",
                                        "swfVfy": "http://test.se/player.swf",
                                        "swfhash": "test",
                                        "swfsize": 123456,
                                        "playPath": "play_path"})
     expected = "rtmp://test.se/app/play_path playPath=play_path swfUrl=http://test.se/player.swf swfVfy=1"
     self.assertEqual(expected, stream_to_url(stream))
     self.assertEqual(expected, stream.to_url())
 def test_rtmp_stream(self):
     stream = RTMPStream(self.session, {"rtmp": "rtmp://test.se/app/play_path",
                                        "swfVfy": "http://test.se/player.swf",
                                        "swfhash": "test",
                                        "swfsize": 123456,
                                        "playPath": "play_path"})
     self.assertEqual(
         {"type": "rtmp",
          "args": [],
          "params": {"rtmp": "rtmp://test.se/app/play_path",
                     "swfVfy": "http://test.se/player.swf",
                     "swfhash": "test",
                     "swfsize": 123456,
                     "playPath": "play_path"}},
         stream.__json__()
     )
示例#3
0
    def _get_streams(self):
        """
        Get the config object from the page source and call the
        API to get the list of streams
        :return:
        """
        # attempt a login
        self.login()

        res = http.get(self.url)
        # decode the config for the page
        matches = self.config_re.finditer(res.text)
        try:
            config = self.config_schema.validate(dict(
                [m.group("key", "value") for m in matches]
            ))
        except PluginError:
            return

        if config["selectedVideoHID"]:
            self.logger.debug("Found video hash ID: {0}", config["selectedVideoHID"])
            api_url = urljoin(self.url, urljoin(config["videosURL"], config["selectedVideoHID"]))
        elif config["livestreamURL"]:
            self.logger.debug("Found live stream URL: {0}", config["livestreamURL"])
            api_url = urljoin(self.url, config["livestreamURL"])
        else:
            return

        ares = http.get(api_url)
        data = http.json(ares, schema=self.api_schema)
        viewing_urls = data["viewing_urls"]

        if "error" in viewing_urls:
            self.logger.error("Failed to load streams: {0}", viewing_urls["error"])
        else:
            for url in viewing_urls["urls"]:
                try:
                    label = "{0}p".format(url.get("res", url["label"]))
                except KeyError:
                    label = "live"

                if url["type"] == "rtmp/mp4" and RTMPStream.is_usable(self.session):
                    params = {
                        "rtmp": url["src"],
                        "pageUrl": self.url,
                        "live": True,
                    }
                    yield label, RTMPStream(self.session, params)

                elif url["type"] == "application/x-mpegURL":
                    for s in HLSStream.parse_variant_playlist(self.session, url["src"]).items():
                        yield s
示例#4
0
    def _get_streams(self):
        res = self.session.http.get(self.url, headers={'User-Agent': useragents.ANDROID})
        match = self._video_data_re.search(res.text)
        if match is None:
            return

        hls_streams = HLSStream.parse_variant_playlist(
            self.session,
            match.group('hls_url'),
            headers={'Referer': self.url}
        )
        for s in hls_streams.items():
            yield s

        rtmp_video = self._flash_data_schema.validate(match.group('flash_data'))
        rtmp_stream = RTMPStream(self.session, {
            'rtmp': rtmp_video['flashVars']['videoAppUrl'],
            'playpath': rtmp_video['flashVars']['videoPlayUrl'],
            'swfUrl': rtmp_video['playerUrl']
        })
        yield 'live', rtmp_stream
示例#5
0
    def _get_streams(self):
        res = http.get(self.url)
        stream_urls = self.stream_schema.validate(res.text)
        self.logger.debug("Found {0} stream URL{1}", len(stream_urls),
                          "" if len(stream_urls) == 1 else "s")

        for stream_url in stream_urls:
            if "m3u8" in stream_url:
                for _, s in HLSStream.parse_variant_playlist(
                        self.session, stream_url).items():
                    yield "live", s
            if stream_url.startswith("rtmp://"):
                a = stream_url.split("///")
                s = RTMPStream(
                    self.session, {
                        "rtmp": a[0],
                        "playpath": "live",
                        "swfVfy": "http://www.tvr.by/plugines/uppod/uppod.swf",
                        "pageUrl": self.url
                    })
                yield "live", s
示例#6
0
    def _get_streams(self):
        self.session.http.headers.update({'Referer': self.url})

        try:
            data = self.session.http.get(self.url, schema=self._data_schema)
        except PluginError:
            log.error('unable to validate _data_schema for {0}'.format(
                self.url))
            return

        metadata = data.get('metadata')
        metadata_url = data.get('metadataUrl')
        if metadata_url and not metadata:
            metadata = self.session.http.post(metadata_url,
                                              schema=self._metadata_schema)

        if metadata:
            log.trace('{0!r}'.format(metadata))
            for hls_url in [
                    metadata.get('hlsManifestUrl'),
                    metadata.get('hlsMasterPlaylistUrl')
            ]:
                if hls_url is not None:
                    yield from HLSStream.parse_variant_playlist(
                        self.session, hls_url).items()

            if metadata.get('videos'):
                for http_stream in metadata['videos']:
                    http_name = http_stream['name']
                    http_url = http_stream['url']
                    try:
                        http_name = '{0}p'.format(
                            self.QUALITY_WEIGHTS[http_name])
                    except KeyError:
                        pass
                    yield http_name, HTTPStream(self.session, http_url)

            if metadata.get('rtmpUrl'):
                yield 'live', RTMPStream(self.session,
                                         params={'rtmp': metadata['rtmpUrl']})
示例#7
0
    def _get_streams(self):
        page_res = http.get(self.url)
        match = _channel_casing_re.search(page_res.text)

        if not match:
            return {}

        channel = match.group("channel")
        visibility = match.group("visibility")

        channel_server_res = http.post(API_CHANNEL_INFO,
                                       data={"loadbalancinginfo": channel})

        streams = {}
        streams["live"] = RTMPStream(
            self.session, {
                "rtmp": RTMP_URL.format(channel_server_res.text),
                "playpath": RTMP_PLAYPATH.format(channel, visibility),
                "pageUrl": self.url,
                "live": True
            })
        return streams
示例#8
0
    def _get_streams(self):
        res = http.get(self.url, schema=_schema)
        streams = {}
        for url in res["urls"]:
            parsed = urlparse(url)
            if parsed.scheme.startswith("rtmp"):
                params = {
                    "rtmp": url,
                    "pageUrl": self.url,
                    "live": True
                }
                if res["swf"]:
                    params["swfVfy"] = res["swf"]

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

        return streams
示例#9
0
    def _get_streams(self):
        match = _url_re.match(self.url)
        channel = match.group("channel")

        headers = {"Referer": self.url}
        url = PLAYER_URL.format(channel)
        res = self.session.http.get(url, headers=headers, schema=_schema)
        if not res or "s" not in res:
            return

        streams = {}
        server = self.session.http.get(BALANCER_URL, headers=headers, schema=_rtmp_schema)
        playpath = "{0}?{1}".format(res["s"], res["id"])
        streams["live"] = RTMPStream(self.session, {
            "rtmp": "rtmp://{0}/live/{1}".format(server, playpath),
            "pageUrl": self.url,
            "swfVfy": SWF_URL,
            "conn": "S:OK",
            "live": True
        })

        return streams
示例#10
0
    def _get_streams(self):
        res = http.get(self.url, schema=_schema)

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

        return
示例#11
0
    def _get_streams(self):
        res = http.get(self.url)
        match = _swf_player_re.search(res.text)
        if match is None:
            return
        swfUrl = "http://vaughnlive.tv" + match.group(1)

        match = _url_re.match(self.url)
        params = {}
        params["channel"] = match.group("channel").lower()
        params["domain"] = DOMAIN_MAP.get(match.group("domain"), match.group("domain"))
        params["version"] = PLAYER_VERSION
        params["ms"] = random.randint(0, 999)
        params["random"] = random.random()
        info = http.get(INFO_URL.format(**params), schema=_schema)

        app = "live"
        if info["server"] in ["198.255.17.18:1337", "198.255.17.66:1337", "50.7.188.2:1337"]:
            if info["ingest"] == "SJC":
                app = "live-sjc"
            elif info["ingest"] == "NYC":
                app = "live-nyc"
            elif info["ingest"] == "ORD":
                app = "live-ord"
            elif info["ingest"] == "AMS":
                app = "live-ams"
            elif info["ingest"] == "DEN":
                app = "live-den"

        stream = RTMPStream(self.session, {
            "rtmp": "rtmp://{0}/live".format(info["server"]),
            "app": "{0}?{1}".format(app, info["token"]),
            "swfVfy": swfUrl,
            "pageUrl": self.url,
            "live": True,
            "playpath": "{domain}_{channel}".format(**params),
        })

        return dict(live=stream)
示例#12
0
文件: tv8cat.py 项目: brinamuc/repo
    def _get_streams(self):
        res = http.get(self.live_iframe)
        britecove_url = self._find_iframe(res)

        if britecove_url:
            self.logger.debug("Found britecove embed url: {0}", britecove_url)
            params = self._britecove_params(britecove_url)
            self.logger.debug("Got britecode params: {0}", params)
            stream_info = self._get_stream_data(**params)
            for source in stream_info.get("sources"):
                if source.get("src"):
                    for s in HLSStream.parse_variant_playlist(
                            self.session, source.get("src")).items():
                        yield s
                else:
                    q = "{0}p".format(source.get("height"))
                    s = RTMPStream(
                        self.session, {
                            "rtmp": source.get("app_name"),
                            "playpath": source.get("stream_name")
                        })
                    yield q, s
示例#13
0
    def _get_streams(self):
        match = _url_re.match(self.url)
        video_id = match.group("video_id")
        params = {
            "client_name": API_CLIENT_NAME,
            "context": API_CONTEXT,
            "raw_user_input": 1,
            "api_key": API_KEY,
            "vid": video_id,
            "r": random()
        }
        res = http.get(API_URL_VIDEO, params=params)
        video = http.json(res, schema=_video_schema)

        error = video.get("error")
        if error:
            raise PluginError(error)

        result = video.get("result")
        if not result:
            return

        url = result["url"]
        if url.startswith("http"):
            stream = HTTPStream(self.session, url)
        elif url.startswith("rtmp"):
            stream = RTMPStream(
                self.session, {
                    "rtmp": url,
                    "playpath": result["id"],
                    "pageUrl": self.url,
                    "live": True
                })

        width, height = result["size"].split("x")
        name = "{0}p".format(height)

        return {name: stream}
示例#14
0
    def _get_streams(self):
        match = _url_re.match(self.url)
        if not match:
            return

        channel_name = match.group(1)

        res = self.session.http.get(STREAMS_URL.format(channel_name))
        streams = self.session.http.json(res, schema=_streams_schema)
        if streams["type"] not in ("multi", "stream"):
            return

        for stream in streams["data"]:
            if stream["slug"] != channel_name:
                continue

            if not stream["live"]:
                return

            streams = {}

            try:
                streams.update(HLSStream.parse_variant_playlist(self.session, HLS_URL))
            except IOError as e:
                # fix for hosted offline streams
                if "404 Client Error" in str(e):
                    return
                raise

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

            return streams

        return
示例#15
0
    def _create_rtmp_stream(self, stream, live=True):
        rtmp = stream["url"]
        playpath = stream["name"]
        parsed = urlparse(rtmp)
        if parsed.query:
            app = "{0}?{1}".format(parsed.path[1:], parsed.query)
        else:
            app = parsed.path[1:]

        if playpath.endswith(".mp4"):
            playpath = "mp4:" + playpath

        params = {
            "rtmp": rtmp,
            "pageUrl": self.url,
            "swfUrl": SWF_URL,
            "playpath": playpath,
            "app": app,
        }
        if live:
            params["live"] = True

        return RTMPStream(self.session, params)
示例#16
0
    def _get_live_stream(self, export_url):
        res = http.get(export_url)
        match = _live_json_re.search(res.text)
        if not match:
            return

        json = parse_json(match.group(1), schema=_live_schema)
        streams = {}
        for stream in json["streams"]:
            stream_name = stream["quality"]
            parsed = urlparse(stream["url"])

            stream = RTMPStream(self.session, {
                "rtmp": stream["url"],
                "app": "{0}?{1}".format(parsed.path[1:], parsed.query),
                "playpath": stream["name"],
                "swfVfy": SWF_LIVE_URL,
                "pageUrl": self.url,
                "live": True
            })
            streams[stream_name] = stream

        return streams
示例#17
0
    def _get_streams(self):
        res = self.url
        streamname = _url_re.search(res).group(1)

        ci = http.get(API_URL.format(channel=streamname))
        api_json = json.loads(ci.text)

        if not api_json or len(api_json) == 0:
            self.logger.error(
                "The channel {0} does not exist or is marked private".format(
                    streamname))
            return

        if api_json[0]["online"] == False:
            self.logger.error(
                "The channel {0} is not online".format(streamname))
            return

        streams = {}
        stream = RTMPStream(
            self.session, {
                "rtmp": ROOT_URL.format(streamname),
                "pageUrl": PAGE_URL,
                "live": True,
                "app": "live",
                "flashVer": "LNX 11,2,202,280",
                "swfVfy":
                "https://www.tigerdile.com/wp-content/jwplayer.flash.swf",
                "playpath": streamname,
            })
        streams["live"] = stream

        stream_hls = HLSStream(self.session,
                               HLS_URL.format(channel=streamname))
        streams["live_hls"] = stream_hls

        return streams
示例#18
0
    def _get_recorded_streams(self, video_id):
        if HAS_LIBRTMP:
            recording = self._get_module_info("recorded",
                                              video_id,
                                              schema=_recorded_schema)

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

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

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

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

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

            url = RECORDED_URL.format(video_id)
            random_hash = "{0:02x}{1:02x}".format(randint(0, 255),
                                                  randint(0, 255))
            params = dict(hash=random_hash)
            stream = HTTPStream(self.session, url, params=params)
            yield "recorded", stream
示例#19
0
    def _get_streams(self):
        log.debug('Version 2018-07-12')
        log.info('This is a custom plugin. '
                 'For support visit https://github.com/back-to/plugins')
        headers = {
            'User-Agent': useragents.FIREFOX,
            'Referer': self.url
        }
        self.session.http.headers.update(headers)
        data = self.session.http.get(self.url, schema=self._data_schema)
        metadata = data.get('metadata')
        metadata_url = data.get('metadataUrl')
        if metadata_url:
            metadata = self.session.http.post(metadata_url, schema=self._metadata_schema)

        if metadata:
            list_hls = [
                metadata.get('hlsManifestUrl'),
                metadata.get('hlsMasterPlaylistUrl'),
            ]
            for hls_url in list_hls:
                if hls_url is not None:
                    for s in HLSStream.parse_variant_playlist(self.session, hls_url).items():
                        yield s

            if metadata.get('videos'):
                for http_stream in metadata['videos']:
                    http_name = http_stream['name']
                    http_url = http_stream['url']
                    try:
                        http_name = '{0}p'.format(self.QUALITY_WEIGHTS[http_name])
                    except KeyError:
                        pass
                    yield http_name, HTTPStream(self.session, http_url)

            if metadata.get('rtmpUrl'):
                yield 'live', RTMPStream(self.session, params={'rtmp': metadata['rtmpUrl']})
示例#20
0
    def _get_streams(self):
        match = _url_re.match(self.url)
        channel = match.group("channel")

        self.session.http.headers.update({'User-Agent': useragents.CHROME, 'Referer': self.url})

        payload = '{"liveStreamID": "%s"}' % (channel)
        res = self.session.http.post(API_URL, data=payload)
        status = _status_re.search(res.text)
        if not status:
            self.logger.info("Stream currently unavailable.")
            return

        http_url = _rtmp_re.search(res.text).group(1)
        https_url = http_url.replace("http:", "https:")
        yield "live", HTTPStream(self.session, https_url)

        if 'pull-rtmp' in http_url:
            rtmp_url = http_url.replace("http:", "rtmp:").replace(".flv", "")
            stream = RTMPStream(self.session, {
                "rtmp": rtmp_url,
                "live": True,
                "pageUrl": self.url,
            })
            yield "live", stream

        if 'wansu-' in http_url:
            hls_url = http_url.replace(".flv", "/playlist.m3u8")
        else:
            hls_url = http_url.replace("live-hdl", "live-hls").replace(".flv", ".m3u8")

        s = []
        for s in HLSStream.parse_variant_playlist(self.session, hls_url).items():
            yield s
        if not s:
            yield "live", HLSStream(self.session, hls_url)
示例#21
0
    def _get_streams(self):
        res = self.session.http.get(self.url)
        match = _playlist_url_re.search(res.text)
        if match is None:
            return

        res = self.session.http.get(match.group(1) + RUURL)
        sources = self.session.http.json(res, schema=_playlist_schema)

        streams = {}

        for source in sources:
            if source["type"] == "rtmp":
                streams["rtmp_live"] = RTMPStream(self.session, {
                    "rtmp": source["streamer"],
                    "pageUrl": self.url,
                    "live": True
                })
            elif source["type"] == "hls":
                streams.update(
                    HLSStream.parse_variant_playlist(self.session,
                                                     source["file"]))

        return streams
示例#22
0
    def _get_streams(self):
        match = _url_re.match(self.url)
        page = match.group("page")
        channel = match.group("channel")

        http.headers.update({'User-Agent': useragents.CHROME})

        if page == 'user':
            res = http.get(self.url)
            userid = _userid_re.search(res.text).group(1)
            api = http.post(API_URL, data={"targetUserID": userid})
            data = http.json(api, schema=_user_api_schema)
            rid = data["liveStreamID"]
            if rid == 0:
                self.logger.info("Stream currently unavailable.")
                return

            url = ROOM_URL.format(rid)
            res = http.get(url)
        elif page == 'profile':
            api = http.post(API_URL, data={"targetUserID": channel})
            data = http.json(api, schema=_user_api_schema)
            rid = data["liveStreamID"]
            if rid == 0:
                self.logger.info("Stream currently unavailable.")
                return

            url = ROOM_URL.format(rid)
            res = http.get(url)
        else:
            res = http.get(self.url)

        status = _status_re.search(res.text)
        if not status:
            return

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

        url = _rtmp_re.search(res.text).group(1)
        if 'rtmp:' in url:
            stream = RTMPStream(self.session, {
                    "rtmp": url,
                    "live": True
                    })
            yield "live", stream
        else:
            yield "live", HTTPStream(self.session, url)

        if '17app.co' in url:
            prefix = url.replace("rtmp:", "http:").replace(".flv", "/playlist.m3u8")
            if '/playlist.m3u8' not in prefix:
                url = prefix + "/playlist.m3u8"
            else:
                url = prefix
            for stream in HLSStream.parse_variant_playlist(self.session, url).items():
                yield stream
        else:
            url = url.replace(".flv", ".m3u8")
            yield "live", HLSStream(self.session, url)
示例#23
0
 def _get_rtmp_stream(self, broadcast):
     info = self._get_stream_info(broadcast, "rtmp")
     if "view_url" in info:
         params = dict(rtmp=info["view_url"])
         return RTMPStream(self.session, params=params, redirect=True)
示例#24
0
    def _get_rtmp_stream(self, stream_info):
        rtmp_url = '/'.join((stream_info['url'], stream_info['stream_name']))
        quality = _rtmp_quality_lookup.get(stream_info['label'], "other")

        params = dict(rtmp=rtmp_url, live=True)
        return quality, RTMPStream(self.session, params=params)
示例#25
0
    def _get_streams(self):
        match = _url_re.match(self.url)
        subdomain = match.group("subdomain")

        http.verify = False
        http.mount('https://', HTTPAdapter(max_retries=99))

        if subdomain == 'v':
            vid = match.group("vid")
            headers = {
                "User-Agent": useragents.ANDROID,
                "X-Requested-With": "XMLHttpRequest"
            }
            res = http.get(VAPI_URL.format(vid), headers=headers)
            room = http.json(res, schema=_vapi_schema)
            yield "source", HLSStream(self.session, room["video_url"])
            return

        channel = match.group("channel")
        try:
            channel = int(channel)
        except ValueError:
            channel = http.get(self.url, schema=_room_id_schema)
            if channel is None:
                channel = http.get(self.url, schema=_room_id_alt_schema)

        http.headers.update({'User-Agent': useragents.ANDROID})
        cdns = ["ws", "tct", "ws2", "dl"]
        ts = int(time.time())
        suffix = "room/{0}?aid=androidhd1&cdn={1}&client_sys=android&time={2}".format(
            channel, cdns[0], ts)
        sign = hashlib.md5((suffix + API_SECRET).encode()).hexdigest()

        res = http.get(API_URL.format(suffix, sign))
        room = http.json(res, schema=_room_schema)
        if not room:
            self.logger.info("Not a valid room url.")
            return

        if room["show_status"] != SHOW_STATUS_ONLINE:
            self.logger.info("Stream currently unavailable.")
            return

        url = room["hls_url"]
        yield "source", HLSStream(self.session, url)

        url = "{room[rtmp_url]}/{room[rtmp_live]}".format(room=room)
        if 'rtmp:' in url:
            stream = RTMPStream(self.session, {"rtmp": url, "live": True})
            yield "source", stream
        else:
            yield "source", HTTPStream(self.session, url)

        multi_streams = {"middle": "low", "middle2": "medium"}
        for name, url in room["rtmp_multi_bitrate"].items():
            url = "{room[rtmp_url]}/{url}".format(room=room, url=url)
            name = multi_streams[name]
            if 'rtmp:' in url:
                stream = RTMPStream(self.session, {"rtmp": url, "live": True})
                yield name, stream
            else:
                yield name, HTTPStream(self.session, url)
示例#26
0
    def _get_streams(self):
        res = http.get(self.url)
        match = _swf_player_re.search(res.text)
        if match is None:
            return
        swf_url = "http://vaughnlive.tv" + match.group(1)
        self.logger.debug("Using swf url: {0}", swf_url)

        swfres = http.get(swf_url)
        swfdata = swfdecompress(swfres.content).decode("latin1")

        player_version_m = re.search(r"0\.\d+\.\d+\.\d+", swfdata)
        info_url_domain_m = re.search(r"\w+\.vaughnsoft\.net", swfdata)
        info_url_path_m = re.search(r"/video/edge/[a-zA-Z0-9_]+-", swfdata)

        player_version = player_version_m and player_version_m.group(0)
        info_url_domain = info_url_domain_m and info_url_domain_m.group(0)
        info_url_path = info_url_path_m and info_url_path_m.group(0)

        if player_version and info_url_domain and info_url_path:
            self.logger.debug(
                "Found player_version={0}, info_url_domain={1}, info_url_path={2}",
                player_version, info_url_domain, info_url_path)
            match = _url_re.match(self.url)
            params = {
                "channel":
                match.group("channel").lower(),
                "domain":
                DOMAIN_MAP.get(match.group("domain"), match.group("domain")),
                "version":
                player_version,
                "ms":
                random.randint(0, 999),
                "random":
                random.random(),
                "site":
                info_url_domain,
                "path":
                info_url_path
            }
            info_url = INFO_URL.format(**params)
            self.logger.debug("Loading info url: {0}",
                              INFO_URL.format(**params))

            info = http.get(info_url, schema=_schema)
            if not info:
                self.logger.info("This stream is currently unavailable")
                return

            app = "live"
            self.logger.debug("Streaming server is: {0}", info["server"])
            if info["server"].endswith(":1337"):
                app = "live-{0}".format(info["ingest"].lower())

            stream = RTMPStream(
                self.session, {
                    "rtmp": "rtmp://{0}/live".format(info["server"]),
                    "app": "{0}?{1}".format(app, info["token"]),
                    "swfVfy": swf_url,
                    "pageUrl": self.url,
                    "live": True,
                    "playpath": "{domain}_{channel}".format(**params),
                })

            return dict(live=stream)
        else:
            self.logger.info(
                "Found player_version={0}, info_url_domain={1}, info_url_path={2}",
                player_version, info_url_domain, info_url_path)
            if not player_version:
                self.logger.error("Could not detect player_version")
            if not info_url_domain:
                self.logger.error("Could not detect info_url_domain")
            if not info_url_path:
                self.logger.error("Could not detect info_url_path")
示例#27
0
 def _create_flash_stream(self, server, channel, token):
     params = {
         "rtmp": self.RTMP_URL.format(server=server),
         "playpath": self.RTMP_PLAYPATH.format(token=token, channel=channel)
     }
     return RTMPStream(self.session, params=params)
示例#28
0
    def _get_streams(self):
        match = url_re.match(self.url)

        stream_page_scheme = 'https'
        stream_page_domain = match.group(4)
        stream_page_path = match.group(5)
        country_code = CONST_DEFAULT_COUNTRY_CODE
        is_paid_show = False

        # create http session and set headers
        http_session = http
        http_session.headers.update(CONST_HEADERS)

        # get swf url and cookies
        r = http_session.get(
            urlunparse((stream_page_scheme, stream_page_domain,
                        stream_page_path, '', '', '')))

        # redirect to profile page means stream is offline
        if '/profile/' in r.url:
            raise NoStreamsError(self.url)
        if not r.ok:
            self.logger.debug("Status code for {}: {}", r.url, r.status_code)
            raise NoStreamsError(self.url)
        if len(http_session.cookies) == 0:
            raise PluginError("Can't get a cookies")

        if urlparse(r.url).netloc != stream_page_domain:
            # then redirected to regional subdomain
            country_code = urlparse(r.url).netloc.split('.')[0].lower()

        # time to set variables
        baseurl = urlunparse(
            (stream_page_scheme, urlparse(r.url).netloc, '', '', '', ''))
        amf_gateway_url = urljoin(baseurl, CONST_AMF_GATEWAY_LOCATION)
        stream_page_url = urljoin(baseurl, stream_page_path)

        match = swf_re.search(r.text)
        if match:
            swf_url = urljoin(baseurl, match.group())
            self.logger.debug("swf url found: {}", swf_url)
        else:
            # most likely it means that country/region banned
            # can try use default swf-url
            swf_url = urljoin(baseurl, CONST_DEFAULT_SWF_LOCATION)
            self.logger.debug("swf url not found. Will try {}", swf_url)

        # create amf query
        amf_message = AMFMessage("svDirectAmf.getRoomData", "/1",
                                 [stream_page_path, is_paid_show])
        amf_packet = AMFPacket(version=0)
        amf_packet.messages.append(amf_message)

        # send request and close http-session
        r = http_session.post(url=amf_gateway_url,
                              params={CONST_AMF_GATEWAY_PARAM: country_code},
                              data=bytes(amf_packet.serialize()))
        http_session.close()

        if r.status_code != 200:
            raise PluginError("unexpected status code for {}: {}", r.url,
                              r.status_code)

        amf_response = AMFPacket.deserialize(BytesIO(r.content))

        if len(amf_response.messages
               ) != 1 or amf_response.messages[0].target_uri != "/1/onResult":
            raise PluginError("unexpected response from amf gate")

        stream_source_info = amf_msg_schema.validate(
            amf_response.messages[0].value)
        self.logger.debug("source stream info:\n{}", stream_source_info)

        stream_params = {
            "live":
            True,
            "realtime":
            True,
            "flashVer":
            CONST_FLASH_VER,
            "swfUrl":
            swf_url,
            "tcUrl":
            stream_source_info['localData']['NC_ConnUrl'],
            "rtmp":
            stream_source_info['localData']['NC_ConnUrl'],
            "pageUrl":
            stream_page_url,
            "playpath":
            "%s?uid=%s" %
            (''.join(('stream_', stream_page_path)),
             self._get_stream_uid(stream_source_info['userData']['username'])),
            "conn": [
                "S:{0}".format(stream_source_info['userData']['username']),
                "S:{0}".format(
                    stream_source_info['localData']['NC_AccessKey']), "B:0",
                "S:{0}".format(stream_source_info['localData']['dataKey'])
            ]
        }

        self.logger.debug("Stream params:\n{}", stream_params)
        stream = RTMPStream(self.session, stream_params)

        return {'live': stream}
示例#29
0
    def _get_streams(self):
        res = http.get(self.url)
        m = self.cam_name_re.search(res.text)
        cam_name = m and m.group("name")
        json_base = self.cam_data_schema.validate(res.text)

        cam_data = json_base["cam"][cam_name]

        self.logger.debug("Found cam for {0} - {1}", cam_data["group"],
                          cam_data["title"])

        is_live = (cam_data["liveon"] == "true"
                   and cam_data["defaulttab"] == "live")

        # HLS data
        hls_domain = cam_data["html5_streamingdomain"]
        hls_playpath = cam_data["html5_streampath"]

        # RTMP data
        rtmp_playpath = ""
        if is_live:
            n = "live"
            rtmp_domain = cam_data["streamingdomain"]
            rtmp_path = cam_data["livestreamingpath"]
            rtmp_live = cam_data["liveon"]

            if rtmp_path:
                match = self.playpath_re.search(rtmp_path)
                rtmp_playpath = match.group("file")
                rtmp_url = rtmp_domain + match.group("folder")
        else:
            n = "vod"
            rtmp_domain = cam_data["archivedomain"]
            rtmp_path = cam_data["archivepath"]
            rtmp_live = cam_data["archiveon"]

            if rtmp_path:
                rtmp_playpath = rtmp_path
                rtmp_url = rtmp_domain

        # RTMP stream
        if rtmp_playpath:
            self.logger.debug("RTMP URL: {0}{1}", rtmp_url, rtmp_playpath)

            params = {
                "rtmp": rtmp_url,
                "playpath": rtmp_playpath,
                "pageUrl": self.url,
                "swfUrl": self.swf_url,
                "live": rtmp_live
            }

            yield n, RTMPStream(self.session, params)

        # HLS stream
        if hls_playpath and is_live:
            hls_url = hls_domain + hls_playpath
            hls_url = update_scheme(self.url, hls_url)

            self.logger.debug("HLS URL: {0}", hls_url)

            for s in HLSStream.parse_variant_playlist(self.session,
                                                      hls_url).items():
                yield s

        if not (rtmp_playpath or hls_playpath):
            self.logger.error(
                "This cam stream appears to be in offline or "
                "snapshot mode and not live stream can be played.")
            return
示例#30
0
    def _get_streams(self):
        res = http.get(self.url, headers={'User-Agent': useragents.ANDROID})
        match = self._video_data_re.search(res.text)
        if match is None:
            print(colored("\n => Performer is OFFLINE <=", "yellow", "on_red"))
            print(colored("\n => END <= ", 'yellow', 'on_blue'))
            time.sleep(3)
            sys.exit()

        if match:
            try:
                hls_streams = HLSStream.parse_variant_playlist(
                    self.session,
                    match.group('hls_url'),
                    headers={'Referer': self.url})
                for s in hls_streams.items():
                    rtmp_video = self._flash_data_schema.validate(
                        match.group('flash_data'))
                    swf = rtmp_video['playerUrl']
                    flashvars = rtmp_video['flashVars']
                    rtmp_stream = RTMPStream(
                        self.session, {
                            'rtmp': rtmp_video['flashVars']['videoAppUrl'],
                            'playpath':
                            rtmp_video['flashVars']['videoPlayUrl'],
                            'swfUrl': rtmp_video['playerUrl']
                        })
                    vpu = flashvars['videoPlayUrl']
                    rname = vpu.split('-')[0]
                    wcdn = vpu.split('-')[1]
                    print(
                        colored("\n => PLAY URL => {} <=\n", "yellow",
                                "on_blue")).format(vpu)
                    vau = flashvars['videoAppUrl']
                    print(
                        colored(" => APP URL => {} <=\n", "yellow",
                                "on_blue")).format(vau)

                    timestamp = str(time.strftime("%d%m%Y-%H%M%S"))
                    path = config.get('folders', 'output_folder_C4')
                    fn = rname + '_C4_' + timestamp + '.flv'
                    pf1 = (path + fn)
                    rtmp = config.get('files', 'rtmpdump')
                    print(
                        colored(' => RTMP-24/7-REC => {} <=', 'yellow',
                                'on_red')).format(fn)
                    print
                    command = '{} -r"{}" -a"cam4-edge-live" -W"{}" --live -y"{}" -o"{}"'.format(
                        rtmp, vau, swf, vpu, pf1)
                    os.system(command)
                    sys.exit()

            except Exception as e:
                if '404' in str(e):
                    print(
                        colored("\n => Performer is AWAY or PRIVATE <=",
                                "yellow", "on_red"))
                    print
                    print(colored("\n => END <= ", 'yellow', 'on_blue'))
                    time.sleep(3)
                    sys.exit()
示例#31
0
 def _create_flash_stream(self, server, args):
     params = {
         "rtmp": self.RTMP_URL.format(server=server),
         "playpath": self.RTMP_PLAYPATH.format(**args)
     }
     return RTMPStream(self.session, params=params)
示例#32
0
    def _get_streams(self):
        log.debug('Version 2018-07-01')
        log.info('This is a custom plugin. '
                 'For support visit https://github.com/back-to/plugins')
        log.info('only FREE content is available.')
        http.headers.update({'User-Agent': useragents.FIREFOX})

        channel = self._url_re.match(self.url).group('channel')
        log.info('Channel: {0}'.format(channel))

        res = http.get(self.url_id.format(channel))
        m = self._channel_id_re.search(res.text)
        if not m:
            raise PluginError('Invalid channel name, can\'t find channel id.')

        channel_id = m.group('id')

        data = (b'\x00\x00\x00\x00\x00\x01\x00\x10remoting.doEvent\x00\x02/1' +
                b'\x00\x00\x00;\n\x00\x00\x00\x02\x02\x00\n' +
                b'getChannel\x03\x00\x0bperformerID\x02\x00\x08' +
                channel_id.encode('ascii') +
                b'\x00\x04type\x02\x00\x04free\x00\x00\x09')

        res = http.post(
            self.url_gateway,
            headers={
                'Content-Type': 'application/x-amf',
                'Referer': self.url_swf,
            },
            data=data,
        )
        data = AMFPacket.deserialize(BytesIO(res.content))
        result = data.messages[0].value

        log.debug('--- DEBUG DATA ---'.format())
        for _r in result:
            log.debug('{0}: {1}'.format(_r, result[_r]))
        log.debug('--- DEBUG DATA ---'.format())

        if result['result'] != 'true':
            _err = self.error_code.get(str(int(result['errorCode'])))
            if _err:
                raise PluginError(_err)
            else:
                raise PluginError('Unknown error_code')

        channel_seq = result['channelSeq']
        host = random.choice(result['freeServerIP'].split(','))
        app = 'video_chat3_free_dx/{0}'.format(channel_seq)

        conn = [
            'O:1',
            'NS:channel:{0}'.format(channel_id, result['channelID']),
            'NS:pServer:{0}'.format(result['serverIP']),
            'NS:langID:en',
            'NS:channelSeq:{0}'.format(result['channelSeq']),
            'O:O',
        ]

        params = {
            'app': app,
            'flashVer': 'WIN 29,0,0,171',
            'swfVfy': self.url_swf,
            'rtmp': 'rtmp://{0}/{1}'.format(host, app),
            'live': True,
            'pageUrl': self.url,
            'playpath': 'free_performer',
            'conn': conn
        }

        yield 'live', RTMPStream(self.session, params)
示例#33
0
    def _get_streams(self):
        """
            Find all the streams for the ITV url
            :return: Mapping of quality to stream
        """
        soap_message = self._soap_request()

        headers = {'Content-Length': '{0:d}'.format(len(soap_message)),
                   'Content-Type': 'text/xml; charset=utf-8',
                   'Host': 'secure-mercury.itv.com',
                   'Origin': 'http://www.itv.com',
                   'Referer': 'http://www.itv.com/Mercury/Mercury_VideoPlayer.swf?v=null',
                   'SOAPAction': "http://tempuri.org/PlaylistService/GetPlaylist",
                   'User-Agent': ITV_PLAYER_USER_AGENT,
                   "X-Requested-With": "ShockwaveFlash/16.0.0.305"}

        res = http.post("https://secure-mercury.itv.com/PlaylistService.svc?wsdl",
                        headers=headers,
                        data=soap_message)

        # Parse XML
        xmldoc = http.xml(res)

        # Check that geo region has been accepted
        faultcode = xmldoc.find('.//faultcode')
        if faultcode is not None:
            if 'InvalidGeoRegion' in faultcode.text:
                self.logger.error('Failed to retrieve playlist data '
                                  '(invalid geo region)')
            return None

        # Look for <MediaFiles> tag (RTMP streams)
        mediafiles = xmldoc.find('.//VideoEntries//MediaFiles')

        # Look for <ManifestFile> tag (HDS streams)
        manifestfile = xmldoc.find('.//VideoEntries//ManifestFile')

        # No streams
        if not mediafiles and not manifestfile:
            return None

        streams = {}

        # Proxy not needed for media retrieval (Note: probably better to use flag)
        # for x in ('http', 'https'):
        #     if x in http.proxies:
        #         http.proxies.pop(x);

        # Parse RTMP streams
        if mediafiles:
            rtmp = mediafiles.attrib['base']

            for mediafile in mediafiles.findall("MediaFile"):
                playpath = mediafile.find("URL").text

                rtmp_url = urlparse(rtmp)
                app = (rtmp_url.path[1:] + '?' + rtmp_url.query).rstrip('?')
                live = app == "live"

                params = dict(rtmp="{u.scheme}://{u.netloc}{u.path}".format(u=rtmp_url),
                              app=app.rstrip('?'),
                              playpath=playpath,
                              swfVfy=LIVE_SWF_URL if live else ONDEMAND_SWF_URL,
                              timeout=10)
                if live:
                    params['live'] = True

                bitrate = int(mediafile.attrib['bitrate']) / 1000
                quality = "{0:d}k".format(int(bitrate))
                streams[quality] = RTMPStream(self.session, params)

        # Parse HDS streams
        if manifestfile:
            url = manifestfile.find('URL').text

            if urlparse(url).path.endswith('f4m'):
                streams.update(
                    HDSStream.parse_manifest(self.session, url, pvswf=LIVE_SWF_URL)
                )

        return streams