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))
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))
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
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
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
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
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
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