<s> import re <EOL> from io import BytesIO <EOL> from time import sleep <EOL> from livestreamer . exceptions import PluginError <EOL> from livestreamer . packages . flashmedia import AMFPacket , AMFMessage <EOL> from livestreamer . packages . flashmedia . types import AMF3ObjectBase <EOL> from livestreamer . plugin import Plugin <EOL> from livestreamer . plugin . api import http , validate <EOL> from livestreamer . stream import AkamaiHDStream <EOL> AMF_GATEWAY = "<STR_LIT>" <EOL> AMF_MESSAGE_PREFIX = "<STR_LIT>" <EOL> STREAM_NAMES = [ "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT:source>" ] <EOL> HTTP_HEADERS = { <EOL> "<STR_LIT>" : ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> } <EOL> _url_re = re . compile ( "<STR_LIT>" ) <EOL> CHANNEL_INFO_URL = "<STR_LIT>" <EOL> _viewerexp_schema = validate . Schema ( <EOL> validate . attr ( { <EOL> "<STR_LIT>" : { <EOL> "<STR_LIT>" : validate . attr ( { <EOL> "<STR_LIT>" : validate . attr ( { <EOL> "<STR_LIT>" : { <EOL> int : validate . attr ( { <EOL> "<STR_LIT>" : int , <EOL> "<STR_LIT>" : validate . text <EOL> } ) <EOL> } <EOL> } ) <EOL> } ) <EOL> } <EOL> } ) <EOL> ) <EOL> @ AMF3ObjectBase . register ( "<STR_LIT>" ) <EOL> class ViewerExperienceRequest ( AMF3ObjectBase ) : <EOL> __members__ = [ "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" ] <EOL> def __init__ ( self , URL , contentOverrides , experienceId , playerKey , TTLToken = "<STR_LIT>" ) : <EOL> self . URL = URL <EOL> self . deliveryType = float ( "<STR_LIT>" ) <EOL> self . contentOverrides = contentOverrides <EOL> self . experienceId = experienceId <EOL> self . playerKey = playerKey <EOL> self . TTLToken = TTLToken <EOL> @ AMF3ObjectBase . register ( "<STR_LIT>" ) <EOL> class ContentOverride ( AMF3ObjectBase ) : <EOL> __members__ = [ "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT:target>" ] <EOL> def __init__ ( self , contentId = float ( "<STR_LIT>" ) , contentRefId = None , contentType = <NUM_LIT:0> , <EOL> target = "<STR_LIT>" ) : <EOL> self . contentType = contentType <EOL> self . contentId = contentId <EOL> self . target = target <EOL> self . contentIds = None <EOL> self . contentRefId = contentRefId <EOL> self . contentRefIds = None <EOL> self . contentType = <NUM_LIT:0> <EOL> self . featuredId = float ( "<STR_LIT>" ) <EOL> self . featuredRefId = None <EOL> class AzubuTV ( Plugin ) : <EOL> @ classmethod <EOL> def can_handle_url ( cls , url ) : <EOL> return _url_re . match ( url ) <EOL> @ classmethod <EOL> def stream_weight ( cls , stream ) : <EOL> if stream == "<STR_LIT:source>" : <EOL> weight = <NUM_LIT> <EOL> else : <EOL> weight , group = Plugin . stream_weight ( stream ) <EOL> return weight , "<STR_LIT>" <EOL> def _create_amf_request ( self , key , video_player , player_id ) : <EOL> if video_player . startswith ( "<STR_LIT>" ) : <EOL> content_override = ContentOverride ( contentRefId = video_player [ <NUM_LIT:4> : ] ) <EOL> else : <EOL> content_override = ContentOverride ( contentId = int ( video_player ) ) <EOL> viewer_exp_req = ViewerExperienceRequest ( self . url , <EOL> [ content_override ] , <EOL> int ( player_id ) , key ) <EOL> req = AMFPacket ( version = <NUM_LIT:3> ) <EOL> req . messages . append ( AMFMessage ( <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> [ AMF_MESSAGE_PREFIX , viewer_exp_req ] <EOL> ) ) <EOL> return req <EOL> def _send_amf_request ( self , req , key ) : <EOL> headers = { <EOL> "<STR_LIT>" : "<STR_LIT>" <EOL> } <EOL> res = http . post ( AMF_GATEWAY , data = bytes ( req . serialize ( ) ) , <EOL> headers = headers , params = dict ( playerKey = key ) ) <EOL> return AMFPacket . deserialize ( BytesIO ( res . content ) ) <EOL> def _get_player_params ( self , retries = <NUM_LIT:5> ) : <EOL> match = _url_re . match ( self . url ) ; <EOL> domain = match . group ( '<STR_LIT>' ) ; <EOL> try : <EOL> res = http . get ( CHANNEL_INFO_URL % str ( domain ) ) <EOL> except PluginError as err : <EOL> if "<STR_LIT>" in str ( err ) and retries : <EOL> sleep ( <NUM_LIT:1> ) <EOL> return self . _get_player_params ( retries - <NUM_LIT:1> ) <EOL> else : <EOL> raise <EOL> channel_info = http . json ( res ) <EOL> channel_info = channel_info [ '<STR_LIT:data>' ] <EOL> key = channel_info [ '<STR_LIT>' ] ; <EOL> is_live = channel_info [ '<STR_LIT>' ] ; <EOL> stream_video = channel_info [ '<STR_LIT>' ] <EOL> if stream_video : <EOL> video_player = "<STR_LIT>" + stream_video [ '<STR_LIT>' ] <EOL> else : <EOL> is_live = False <EOL> video_player = None <EOL> player_id = channel_info [ '<STR_LIT>' ] <EOL> return key , video_player , player_id , is_live <EOL> def _parse_result ( self , res ) : <EOL> res = _viewerexp_schema . validate ( res ) <EOL> player = res . programmedContent [ "<STR_LIT>" ] <EOL> renditions = sorted ( player . mediaDTO . renditions . values ( ) , <EOL> key = lambda r : r . encodingRate or <NUM_LIT> ) <EOL> streams = { } <EOL> for stream_name , rendition in zip ( STREAM_NAMES , renditions ) : <EOL> stream = AkamaiHDStream ( self . session , rendition . defaultURL ) <EOL> streams [ stream_name ] = stream <EOL> return streams <EOL> def _get_streams ( self ) : <EOL> key , video_player , player_id , is_live = self . _get_player_params ( ) <EOL> if not is_live : <EOL> return <EOL> req = self . _create_amf_request ( key , video_player , player_id ) <EOL> res = self . _send_amf_request ( req , key ) <EOL> streams = { } <EOL> for message in res . messages : <EOL> if message . target_uri == "<STR_LIT>" : <EOL> streams = self . _parse_result ( message . value ) <EOL> return streams <EOL> __plugin__ = AzubuTV </s>
