Ejemplo n.º 1
0
    def _send_amf_request(self, req, key):
        headers = {"content-type": "application/x-amf"}
        res = http.post(AMF_GATEWAY,
                        data=bytes(req.serialize()),
                        headers=headers,
                        params=dict(playerKey=key))

        return AMFPacket.deserialize(BytesIO(res.content))
Ejemplo n.º 2
0
    def _send_amf_request(self, req, key):
        headers = {
            "content-type": "application/x-amf"
        }
        res = http.post(AMF_GATEWAY, data=bytes(req.serialize()),
                        headers=headers, params=dict(playerKey=key))

        return AMFPacket.deserialize(BytesIO(res.content))
Ejemplo n.º 3
0
    def _create_amf_request(self, key, video_player, player_id):
        content_override = ContentOverride(int(video_player))
        viewer_exp_req = ViewerExperienceRequest(self.url, [content_override],
                                                 int(player_id), key)

        req = AMFPacket(version=3)
        req.messages.append(
            AMFMessage(
                "com.brightcove.experience.ExperienceRuntimeFacade.getDataForExperience",
                "/1", [self.AMFMessagePrefix, viewer_exp_req]))

        return req
Ejemplo n.º 4
0
    def _create_amf_request(self, key, video_player, player_id):
        if video_player.startswith("ref:"):
            content_override = ContentOverride(contentRefId=video_player[4:])
        else:
            content_override = ContentOverride(contentId=int(video_player))
        viewer_exp_req = ViewerExperienceRequest(self.url, [content_override],
                                                 int(player_id), key)

        req = AMFPacket(version=3)
        req.messages.append(
            AMFMessage(
                "com.brightcove.experience.ExperienceRuntimeFacade.getDataForExperience",
                "/1", [AMF_MESSAGE_PREFIX, viewer_exp_req]))

        return req
Ejemplo n.º 5
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
Ejemplo n.º 6
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
Ejemplo n.º 7
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
Ejemplo n.º 8
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 "liveHttpUrl" in result:
            try:
                hlsstreams = HLSStream.parse_variant_playlist(self.session,
                                                              result["liveHttpUrl"])
                streams.update(hlsstreams)
            except IOError as err:
                self.logger.warning("Failed to get variant playlist: {0}", err)

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

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

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

        if "streamVersions" in result:
            for version, info in result["streamVersions"].items():
                if "streamVersionCdn" in info:
                    for name, cdn in info["streamVersionCdn"].items():
                        if "cdnStreamUrl" in cdn and "cdnStreamName" in cdn:
                            cdnname = "live_alt_{0}".format(name)
                            streams[cdnname] = self._create_stream(cdn["cdnStreamUrl"],
                                                                   cdn["cdnStreamName"])



        return streams