
    \Jj7                        d dl Z d dlZd dlmZmZ d dlmZmZ d dlm	Z	m
Z
mZmZmZmZ  G d de      Z G d d      Z G d	 d
e      Z G d dee      Z G d de      Z G d dee      Z G d de      Z G d de      Z G d de      Z G d de      Z G d de      Z G d d      Z G d de      Z G d d e      Z G d! d"ee      Z G d# d$ee      Z  G d% d&e      Z! G d' d(      Z" G d) d*e      Z# G d+ d,ee      Z$ G d- d.      Z% G d/ d0      Z& G d1 d2      Z' G d3 d4e      Z( G d5 d6      Z) G d7 d8e      Z* G d9 d:      Z+ G d; d<e      Z, G d= d>e      Z- G d? d@e      Z.dA Z/dB Z0dC Z1dD Z2y)E    N)BasePathMixinGroupedBasePathMixin)format_date_timeparse)ext_oatcls_scte35ext_x_asset	ext_x_key	ext_x_mapext_x_session_keyext_x_startc                       e Zd Zy)MalformedPlaylistErrorN__name__
__module____qualname__     E/var/www/html/Extract/venv/lib/python3.12/site-packages/m3u8/model.pyr   r          r   r   c                       e Zd ZdZdZ	 	 	 	 	 ddZd Zd Zed        Z	e	j                  d        Z	ed	        Zej                  d
        Zd Zd Zd Zd Zd Zd Zd ZddZd Zd Zy)M3U8a,  
    Represents a single M3U8 playlist. Should be instantiated with
    the content as string.

    Parameters:

     `content`
       the m3u8 content as string

     `base_path`
       all urls (key and segments url) will be updated with this base_path,
       ex.:
           base_path = "http://videoserver.com/hls"

            /foo/bar/key.bin           -->  http://videoserver.com/hls/key.bin
            http://vid.com/segment1.ts -->  http://videoserver.com/hls/segment1.ts

       can be passed as parameter or setted as an attribute to ``M3U8`` object.
     `base_uri`
      uri the playlist comes from. it is propagated to SegmentList and Key
      ex.: http://example.com/path/to

    Attributes:

     `keys`
       Returns the list of `Key` objects used to encrypt the segments from m3u8.
       It covers the whole list of possible situations when encryption either is
       used or not.

       1. No encryption.
       `keys` list will only contain a `None` element.

       2. Encryption enabled for all segments.
       `keys` list will contain the key used for the segments.

       3. No encryption for first element(s), encryption is applied afterwards
       `keys` list will contain `None` and the key used for the rest of segments.

       4. Multiple keys used during the m3u8 manifest.
       `keys` list will contain the key used for each set of segments.

     `session_keys`
       Returns the list of `SessionKey` objects used to encrypt multiple segments from m3u8.

     `segments`
       a `SegmentList` object, represents the list of `Segment`s from this playlist

     `is_variant`
        Returns true if this M3U8 is a variant playlist, with links to
        other M3U8s with different bitrates.

        If true, `playlists` is a list of the playlists available,
        and `iframe_playlists` is a list of the i-frame playlists available.

     `is_endlist`
        Returns true if EXT-X-ENDLIST tag present in M3U8.
        http://tools.ietf.org/html/draft-pantos-http-live-streaming-07#section-3.3.8

      `playlists`
        If this is a variant playlist (`is_variant` is True), returns a list of
        Playlist objects

      `iframe_playlists`
        If this is a variant playlist (`is_variant` is True), returns a list of
        IFramePlaylist objects

      `playlist_type`
        A lower-case string representing the type of the playlist, which can be
        one of VOD (video on demand) or EVENT.

      `media`
        If this is a variant playlist (`is_variant` is True), returns a list of
        Media objects

      `target_duration`
        Returns the EXT-X-TARGETDURATION as an integer
        http://tools.ietf.org/html/draft-pantos-http-live-streaming-07#section-3.3.2

      `media_sequence`
        Returns the EXT-X-MEDIA-SEQUENCE as an integer
        http://tools.ietf.org/html/draft-pantos-http-live-streaming-07#section-3.3.3

      `program_date_time`
        Returns the EXT-X-PROGRAM-DATE-TIME as a string
        http://tools.ietf.org/html/draft-pantos-http-live-streaming-07#section-3.3.5

      `version`
        Return the EXT-X-VERSION as is

      `allow_cache`
        Return the EXT-X-ALLOW-CACHE as is

      `files`
        Returns an iterable with all files from playlist, in order. This includes
        segments and key uri, if present.

      `base_uri`
        It is a property (getter and setter) used by
        SegmentList and Key to have absolute URIs.

      `is_i_frames_only`
        Returns true if EXT-X-I-FRAMES-ONLY tag present in M3U8.
        http://tools.ietf.org/html/draft-pantos-http-live-streaming-07#section-3.3.12

      `is_independent_segments`
        Returns true if EXT-X-INDEPENDENT-SEGMENTS tag present in M3U8.
        https://tools.ietf.org/html/draft-pantos-http-live-streaming-13#section-3.4.16

      `image_playlists`
        If this is a variant playlist (`is_variant` is True), returns a list of
        ImagePlaylist objects

      `is_images_only`
        Returns true if EXT-X-IMAGES-ONLY tag present in M3U8.
        https://github.com/image-media-playlist/spec/blob/master/image_media_playlist_v0_4.pdf
    ))
is_variantr   )
is_endlistr   )is_i_frames_onlyr   )target_durationtargetduration)media_sequencer   )program_date_timer   )is_independent_segmentsr    )versionr!   )allow_cacher"   )playlist_typer#   )discontinuity_sequencer$   )is_images_onlyr%   Nc                     |t        |||      | _        ni | _        || _        | j                  r0| j                  j                  d      s| xj                  dz  c_        | j	                          || _        y )N/)r   data	_base_uriendswith_initialize_attributes	base_path)selfcontentr,   base_uristrictcustom_tags_parsers         r   __init__zM3U8.__init__   sc     gv/ABDIDI!>>>>**3/#%##%"r   c                 L   | j                   j                  dg       D cg c]  }|rt        dd| j                  i|nd  c}| _        | j                   j                  dg       D cg c]  }|rt        dd| j                  i|nd  c}| _        t        | j                   j                  dg       D cg c]>  }t        d| j                  t        |j                  di       | j                        d|@ c}      | _
        | j                  D ]+  \  }}t        | || j                   j                  |             - t        | j                  | j                  xs d      D ]  \  }}||_         g | _        | j                  D ]C  }|s|j                   | j                  vs| j                  j#                  |j                          E | j                  j%                  | j                  j                          t'        | j                   j                  dg       D cg c]  }t)        dd| j                  i| c}      | _        t-        | j                   j                  d	g       D cg c]$  }t/        d| j                  | j*                  d
|& c}      | _        t-               | _        | j                   j                  dg       D ]9  }	| j2                  j#                  t5        | j                  |	d   |	d                ; t-               | _        | j                   j                  dg       D ]9  }
| j6                  j#                  t9        | j                  |
d   |
d                ; | j                   j                  dd       }|xr t;        di || _        | j                   j                  dd       }|xr t?        di || _         | j                   j                  dd       }|xr tC        di || _"        | j                   j                  dd       }|xr tG        di || _$        tK        | j                   j                  dg       D cg c]  }tM        dd| j                  i| c}      | _'        tQ        | j                   j                  dg       D cg c]  }d|v rtS        di | c}      | _*        | j                   j                  dg       D cg c]  }|rtW        dd| j                  i|nd  c}| _,        | j                   j                  dd       }|xr t[        dd| j                  i|| _.        | j                   j                  dd       }|xr t_        dd| j                  i|| _0        y c c}w c c}w c c}w c c}w c c}w c c}w c c}w c c}w )Nkeysr/   segment_mapsegmentskey)r/   	keyobjectr   media	playlists)r/   r9   iframe_playlistsuriiframe_stream_info)r/   r<   r=   image_playlistsimage_stream_info)r/   r<   r?   startserver_controlpart_infskiprendition_reportssession_datadata_idsession_keyspreload_hintcontent_steeringr   )1r(   getKeyr/   r4   InitializationSectionr5   SegmentListSegmentfind_keyr6   simple_attributessetattr	enumerater   filesr<   appendextend	MediaListMediar9   PlaylistListPlaylistr:   r;   IFramePlaylistr>   ImagePlaylistStartr@   ServerControlrA   PartInformationrB   SkiprC   RenditionReportListRenditionReportrD   SessionDataListSessionDatarE   
SessionKeyrG   PreloadHintrH   ContentSteeringrI   )r-   paramssegmentattrparamir7   r9   playlistifr_plimg_plr@   rA   rB   rC   rendition_reportrE   rH   rI   s                      r   r+   zM3U8._initialize_attributes   s'    ))--3
 6<C11&1E
	 ))--r:
 HN!C4==CFCSWW
 $  $yy}}Z<   !]]&w{{5"'=tyyI 	
  11 	6KD%D$		e 45	6 $DMM43F3F3K!L 	'JAw%&G"	' 
99 	+Cswwdjj0

!!#''*	+ 	

$--++, "YY]]7B7 6t}}66

 & !%		k2 > N$--tzzNXN
 !-iimm$6; 	F!!((!]]u'-.B'C	  ,~iimm$5r: 	F  ''!]]u&,-@&A	 		gt,-u~u~
'7>,P1P1P99==T2 @_%@x%@yy}}VT*)T\D\	!4 )-		6I2(N$  KK:JK"
 , %)IIMM."$E , +l+
 ))--;
 =CJ888L

 yy}}^T:( 
[ .
]].
&2.
  99==);TB 0 !
_ 6
]]6
&66
Q


0N
s0   "U>'"V4AVV()VVV"V!c                 "    | j                         S Ndumpsr-   s    r   __unicode__zM3U8.__unicode__      zz|r   c                     | j                   S rq   r)   rt   s    r   r/   zM3U8.base_uri!      ~~r   c                    || _         || j                  _        || j                  _        || j                  _        || j
                  _        || j                  _        || j                  _        | j                  D ]  }|s||_         | j                  D ]  }|s||_         | j                  r|| j                  _        | j                  r|| j                  _        y y rq   )r)   r9   r/   r:   r;   r6   rD   r>   r4   rG   rH   rI   )r-   new_base_urir7   s      r   r/   zM3U8.base_uri%  s    %*

".)5&!-*6'(4%99 	,C+	, $$ 	,C+	, )5D&  -9D!!* !r   c                     | j                   S rq   )
_base_pathrt   s    r   r,   zM3U8.base_path9  s    r   c                 2    || _         | j                          y rq   )r}   _update_base_path)r-   newbase_paths     r   r,   zM3U8.base_path=  s    & r   c                    | j                   y | j                  D ]  }|s| j                   |_         | j                  D ]  }|s| j                   |_         | j                   | j                  _        | j                   | j
                  _        | j                   | j                  _        | j                   | j                  _        | j                   | j                  _        | j                   | j                  _        | j                  r| j                   | j                  _        | j                  r| j                   | j                  _        y y rq   )r}   r4   r,   rG   r9   r6   r:   r;   r>   rD   rH   rI   )r-   r7   s     r   r   zM3U8._update_base_pathB  s    ??"99 	0C $	0 $$ 	0C $	0  $

"&//#'?? *.//')-&+/??(*.//D'  .2ooD!!+ !r   c                 H    d| _         | j                  j                  |       y NT)r   r:   rT   )r-   rl   s     r   add_playlistzM3U8.add_playlistV  s    h'r   c                 N    |#d| _         | j                  j                  |       y y r   )r   r;   rT   )r-   iframe_playlists     r   add_iframe_playlistzM3U8.add_iframe_playlistZ  s(    &"DO!!((9 'r   c                 N    |#d| _         | j                  j                  |       y y r   )r   r>   rT   )r-   image_playlists     r   add_image_playlistzM3U8.add_image_playlist_  s(    %"DO  ''7 &r   c                 :    | j                   j                  |       y rq   )r9   rT   r-   r9   s     r   	add_mediazM3U8.add_mediad  s    

% r   c                 :    | j                   j                  |       y rq   )r6   rT   )r-   rh   s     r   add_segmentzM3U8.add_segmentg  s    W%r   c                 :    | j                   j                  |       y rq   )rD   rT   r-   reports     r   add_rendition_reportzM3U8.add_rendition_reportj  s    %%f-r   c                 (	   dg}| j                   r$|j                  t        | j                                | j                  r'|j                  dt        | j                        z          | j                  r|j                  d| j                          | j
                  r,|j                  d| j
                  j                         z          | j                  r'|j                  dt        | j                        z          | j                  r|j                  d       | j                  r'|j                  dt        | j                        z          | j                  D| j                  dk(  s5|j                  d	t        | j                        j                         z         | j                  r$|j                  t        | j                               | j                  r|j                  d
       | j                  r|j                  d       | j                  r$|j                  t        | j                               | j                   r| j"                  r$|j                  t        | j"                               |j                  t        | j$                               | j&                  r$|j                  t        | j&                               | j(                  r$|j                  t        | j(                               | j*                  r$|j                  t        | j*                               | j,                  r$|j                  t        | j,                               | j.                  r$|j                  t        | j.                               | j0                  D ]  }|j                  t        |              |j                  | j2                  j5                  ||             | j6                  r$|j                  t        | j6                               | j8                  r$|j                  t        | j8                               | j:                  r|j                  d       |d   r%|d   j=                  d      s|j                  d       dj?                  |      S )zy
        Returns the current m3u8 as a string.
        You could also use unicode(<this obj>) or str(<this obj>)
        z#EXTM3Uz#EXT-X-MEDIA-SEQUENCE:z#EXT-X-DISCONTINUITY-SEQUENCE:z#EXT-X-ALLOW-CACHE:z#EXT-X-VERSION:z#EXT-X-INDEPENDENT-SEGMENTSz#EXT-X-TARGETDURATION: z#EXT-X-PLAYLIST-TYPE:%sz#EXT-X-I-FRAMES-ONLYz#EXT-X-IMAGES-ONLYz#EXT-X-ENDLIST
) rI   rT   strr   r$   r"   upperr!   r    r   number_to_stringr#   r@   r   r%   rA   r   r9   r:   r;   r>   rB   rC   rE   rG   r6   rs   rH   rD   r   r*   join)r-   timespecinfspecoutputr7   s        r   rs   z
M3U8.dumpsm  sG   
   MM#d3345MM2S9L9L5MMN&&MM01L1L0MN MM/$2B2B2H2H2JJK<<MM+c$,,.??@''MM78MM(+;D<P<P+QQ ""*d.@.@B.FMM3c$:L:L6M6S6S6UUV::MM#djj/*  MM01MM./MM#d1123??zzc$**o.MM#dnn-.$$c$"7"789##c$"6"678==MM#dmm,-99MM#dii.)MM#d//01$$ 	$CMM#c(#	$ 	dmm))(G<=MM#d//01!!MM#d4456??MM*+ ":fRj11$7MM"yy  r   c                     | j                  |       t        |d      5 }|j                  | j                                ddd       y# 1 sw Y   yxY w)z8
        Saves the current m3u8 to ``filename``
        wN)_create_sub_directoriesopenwriters   )r-   filenamefileobjs      r   dumpz	M3U8.dump  sE     	$$X.(C  	(GMM$**,'	( 	( 	(s    AAc                    t         j                  j                  |      s2t         j                  j                  t        j                         |      }t         j                  j                  |      }|rt        j                  |d       y y )NT)exist_ok)ospathisabsr   getcwddirnamemakedirs)r-   r   basenames      r   r   zM3U8._create_sub_directories  sT    ww}}X&ww||BIIK:H77??8,KK40 r   )NNNFNmillisecondsauto)r   r   r   __doc__rP   r2   r+   ru   propertyr/   setterr,   r   r   r   r   r   r   r   rs   r   r   r   r   r   r   r      s    sj$ #(k
Z   __: :&   ! !>((:
8
!&.C!J(1r   r   c                        e Zd ZdZ	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d
dZd ZddZd Ze fd       Z	e	j                   fd       Z	ed        Zej                  d	        Z xZS )rN   a  
    A video segment from a M3U8 playlist

    `uri`
      a string with the segment uri

    `title`
      title attribute from EXTINF parameter

    `program_date_time`
      Returns the EXT-X-PROGRAM-DATE-TIME as a datetime. This field is only set
      if EXT-X-PROGRAM-DATE-TIME exists for this segment
      http://tools.ietf.org/html/draft-pantos-http-live-streaming-07#section-3.3.5

    `current_program_date_time`
      Returns a datetime of this segment, either the value of `program_date_time`
      when EXT-X-PROGRAM-DATE-TIME is set or a calculated value based on previous
      segments' EXT-X-PROGRAM-DATE-TIME and EXTINF values

    `discontinuity`
      Returns a boolean indicating if a EXT-X-DISCONTINUITY tag exists
      http://tools.ietf.org/html/draft-pantos-http-live-streaming-13#section-3.4.11

    `cue_out`
      Returns a boolean indicating if a EXT-X-CUE-OUT-CONT tag exists
      Note: for backwards compatibility, this will be True when cue_out_start
            is True, even though this tag did not exist in the input, and
            EXT-X-CUE-OUT-CONT will not exist in the output

    `cue_out_start`
      Returns a boolean indicating if a EXT-X-CUE-OUT tag exists

    `cue_out_explicitly_duration`
      Returns a boolean indicating if a EXT-X-CUE-OUT have the DURATION parameter when parsing

    `cue_in`
      Returns a boolean indicating if a EXT-X-CUE-IN tag exists

    `scte35`
      Base64 encoded SCTE35 metadata if available

    `scte35_duration`
      Planned SCTE35 duration

    `duration`
      duration attribute from EXTINF parameter

    `base_uri`
      uri the key comes from in URI hierarchy. ex.: http://example.com/path/to

    `bitrate`
      bitrate attribute from EXT-X-BITRATE parameter

    `byterange`
      byterange attribute from EXT-X-BYTERANGE parameter

    `key`
      Key used to encrypt the segment (EXT-X-KEY)

    `parts`
      partial segments that make up this segment

    `dateranges`
      any dateranges that should  precede the segment

    `gap_tag`
      GAP tag indicates that a Media Segment is missing

    `custom_parser_values`
        Additional values which custom_tags_parser might store per segment
    c           
      b   || _         || _        || _        || _        || _        || _        || _        || _        || _        || _	        |
| _
        || _        |	| _        || _        || _        || _        || _        || _        || _        || _        t)        |r%|D cg c]  }t+        dd| j                  i| c}ng       | _        |t/        | j                  fi || _        nd | _        t3        |r|D cg c]  }t5        di | c}ng       | _        || _        |xs i | _        y c c}w c c}w )Nr/   r   )r   r<   durationtitler)   bitrate	byteranger   current_program_date_timediscontinuitycue_out_startcue_out_explicitly_durationcue_outcue_inscte35oatcls_scte35scte35_durationscte35_elapsedtimeasset_metadatar7   PartialSegmentListPartialSegmentpartsrL   init_sectionDateRangeList	DateRange
daterangesgap_tagcustom_parser_values)r-   r<   r/   r   r   r   r   r   r   r   r   r   r   r   r7   r   r   r   r   r   r8   r   r   r   r   r   r   partial	dateranges                                r   r2   zSegment.__init__  s>   : - 
!"!2)B&**+F(*."4,' PUUG^?T^^?w?U


 # 5dnn U UD $D'DNZ@	Y##@TV
 $8$>B! V As   D'4D,c                 :    | j                   j                  |       y rq   )r   rT   )r-   parts     r   add_partzSegment.add_partM  s    

$r   c                 f
   g }|rO| j                   |j                   k7  r6|j                  t        | j                                |j                  d       nC| j                   r7|5|j                  t        | j                                |j                  d       | j                  rP|r| j                  |j                  k7  r5|j                  t        | j                               |j                  d       | j                  r|j                  d       | j
                  r)|j                  dt        | j
                  |      z         t        | j                        r5|j                  t        | j                               |j                  d       | j                  r| j                  r%|j                  t         d| j                   d       | j                  rrg }| j                  j                         D ])  \  }}|j                  |j                          d|        + |j                  t         ddj!                  |       d       | j"                  rdnd}| j$                  r| | j$                   nd	}	|j                  d
|	 d       n
| j&                  rg }
| j(                  r|
j                  d| j(                          | j$                  r|
j                  d| j$                          | j*                  r|
j                  d| j*                          |
rddj!                  |
      z   }
nd	}
|j                  d|
 d       nO| j,                  r|j                  d       n1| j                  r%|j                  t         d| j                   d       | j.                  r5|j                  t        | j.                               |j                  d       | j0                  r;| j2                  |dk(  rdj5                  | j2                        }n6|dk(  rdj5                  | j2                        }nt7        | j2                        }|j                  d|z         | j8                  r|j                  | j8                         |j                  d       | j:                  r|j                  d| j:                  z         | j<                  r|j                  d| j<                  z         | j>                  r|j                  d       |j                  | j0                         d	j!                  |      S )Nr   z#EXT-X-DISCONTINUITY
z#EXT-X-PROGRAM-DATE-TIME:%s
)r   :=,z
:DURATION=r   z#EXT-X-CUE-OUTzElapsedTime=z	Duration=zSCTE35=z#EXT-X-CUE-OUT-CONTz#EXT-X-CUE-IN
r   z{:.3f}microsecondsz{:.6f}z#EXTINF:%s,z#EXT-X-BYTERANGE:%s
z#EXT-X-BITRATE:%d
#EXT-X-GAP
) r7   rT   r   r   r   r   r   lenr   r   r   r   r   itemsr   r   r   r   r   r   r   r   r   r   r<   r   formatr   r   r   r   r   )r-   last_segmentr   r   r   asset_suffixmetadata_keymetadata_valueprefixcue_infocue_out_cont_suffixr   s               r   rs   zSegment.dumpsP  s   DHH(8(88MM#dhh-(MM$ xxL0c$((m,d# d&7&7<;T;T&Tc$"3"345d#MM23!!MM/"4#9#9HMN
 tMM#doo./MM$!!!2 31T5G5G4HKL""!484G4G4M4M4O T0L. ''<+=+=+?*@.AQ(RSTQsxx/E.FbIJ%)%E%E\3F<@<P<P&$"6"6!78VXHMMN8*B78\\"$&&#**\$:Q:Q9R+ST###**Yt7K7K6L+MN{{#**WT[[M+BC"&)CHH5H,I&I#&(#MM/0C/DBGH[[MM+,MM./q1C1C0DBGH::MM#djj/*MM$88}}(n,'t}}=H.'t}}=H/>Hmh67::MM$**-d#~~5FG||3dllBC||n-MM$((#wwvr   c                 $    | j                  d       S rq   rr   rt   s    r   __str__zSegment.__str__      zz$r   c                     t         |   S rq   )superr,   )r-   	__class__s    r   r,   zSegment.base_path  s    w  r   c                     t         t        | j                    j	                  | |       || j
                  _        | j                  || j                  _        y y rq   )r   rN   r   r,   fsetr   r   )r-   r   r   s     r   r,   zSegment.base_path  sI    gt~~055dLI+

(*6D' )r   c                     | j                   S rq   rx   rt   s    r   r/   zSegment.base_uri  ry   r   c                 p    || _         || j                  _        | j                  || j                  _        y y rq   )r)   r   r/   r   )r-   newbase_uris     r   r/   zSegment.base_uri  s4    $)

()4D& )r   )NNNNNNNNFFFFFNNNNNNNNNNNNNr   )r   r   r   r   r2   r   rs   r   r   r,   r   r/   __classcell__)r   s   @r   rN   rN     s    FT "&$)!7>?@ Yv  ! ! 7 7   __5 5r   rN   c                   0    e Zd ZddZd Zed        Zd Zy)rM   c                     g }d }| D ]&  }|j                  |j                  |||             |}( dj                  |      S Nr   )rT   rs   r   )r-   r   r   r   r   rh   s         r   rs   zSegmentList.dumps  sJ     	#GMM'--hHI"L	# yy  r   c                 "    | j                         S rq   rr   rt   s    r   r   zSegmentList.__str__  rv   r   c                 @    | D cg c]  }|j                    c}S c c}w rq   r<   )r-   segs     r   r<   zSegmentList.uri  s    #'(C(((   c                 L    | D cg c]  }|j                   |k(  s| c}S c c}w rq   )r7   )r-   r7   rh   s      r   by_keyzSegmentList.by_key  s!    '+BGw{{c/ABBBs   !!Nr   )r   r   r   rs   r   r   r<   r   r   r   r   rM   rM     s&    ! ) )Cr   rM   c                   2    e Zd ZdZ	 	 	 	 	 	 	 ddZd Zd Zy)r   a  
    A partial segment from a M3U8 playlist

    `uri`
      a string with the segment uri

    `program_date_time`
      Returns the EXT-X-PROGRAM-DATE-TIME as a datetime. This field is only set
      if EXT-X-PROGRAM-DATE-TIME exists for this segment
      http://tools.ietf.org/html/draft-pantos-http-live-streaming-07#section-3.3.5

    `current_program_date_time`
      Returns a datetime of this segment, either the value of `program_date_time`
      when EXT-X-PROGRAM-DATE-TIME is set or a calculated value based on previous
      segments' EXT-X-PROGRAM-DATE-TIME and EXTINF values

    `duration`
      duration attribute from EXTINF parameter

    `byterange`
      byterange attribute from EXT-X-BYTERANGE parameter

    `independent`
      the Partial Segment contains an independent frame

    `gap`
      GAP attribute indicates the Partial Segment is not available

    `dateranges`
      any dateranges that should precede the partial segment

    `gap_tag`
      GAP tag indicates one or more of the parent Media Segment's Partial
      Segments have a GAP=YES attribute. This tag should appear immediately
      after the first EXT-X-PART tag in the Parent Segment with a GAP=YES
      attribute.
    Nc           
          || _         || _        || _        || _        || _        || _        || _        || _        t        |	r|	D cg c]  }t        di | c}ng       | _
        |
| _        y c c}w )Nr   )r/   r<   r   r   r   r   independentgapr   r   r   r   )r-   r/   r<   r   r   r   r   r   r   r   r   r   s               r   r2   zPartialSegment.__init__   su     ! !2)B&"&'DNZ@	Y##@TV
  As   A,c                 \   g }t        | j                        r5|j                  t        | j                               |j                  d       | j                  r|j                  d       |j                  dt        | j                        d| j                  d       | j                  r|j                  d| j                  z         | j                  r|j                  d| j                  z         | j                  r|j                  d| j                  z         d	j                  |      S )
Nr   r   z#EXT-X-PART:DURATION=z,URI=""z,INDEPENDENT=%sz,BYTERANGE=%sz,GAP=%sr   )r   r   rT   r   r   r   r   r<   r   r   r   r   )r-   r   r   s      r   rs   zPartialSegment.dumps  s    tMM#doo./MM$<<MM.).:	

 MM+d.>.>>?>>MM/DNN:;88MM)dhh./wwvr   c                 $    | j                  d       S rq   rr   rt   s    r   r   zPartialSegment.__str__4  r   r   )NNNNNNNr   r   r   r   r2   rs   r   r   r   r   r   r     s.    $V "&44 r   r   c                       e Zd Zd Zy)r   c                 ^    | D cg c]  }t        |       }}dj                  |      S c c}w r   r   r   )r-   r   r   s      r   r   zPartialSegmentList.__str__9  s-    (,-#d)--yy   .   *Nr   r   r   r   r   r   r   r   r   8      !r   r   c                   6    e Zd ZdZeZ	 	 	 	 ddZd Zd Zd Z	y)rK   a  
    Key used to encrypt the segments in a m3u8 playlist (EXT-X-KEY)

    `method`
      is a string. ex.: "AES-128"

    `uri`
      is a string. ex:: "https://priv.example.com/key.php?r=52"

    `base_uri`
      uri the key comes from in URI hierarchy. ex.: http://example.com/path/to

    `iv`
      initialization vector. a string representing a hexadecimal number. ex.: 0X12A

    Nc                 f    || _         || _        || _        || _        || _        || _        || _        y rq   )methodr<   iv	keyformatkeyformatversionsr/   _extra_params)r-   r  r/   r<   r  r  r  kwargss           r   r2   zKey.__init__R  s7     "!2 #r   c                    d| j                   z  g}| j                  r|j                  d| j                  z         | j                  r|j                  d| j                  z         | j                  r|j                  d| j                  z         | j
                  r|j                  d| j
                  z         | j                  dz   dj                  |      z   S )Nz	METHOD=%szURI="%s"zIV=%szKEYFORMAT="%s"zKEYFORMATVERSIONS="%s"r   r   )r  r<   rT   r  r  r  tagr   r-   r   s     r   r   zKey.__str__d  s    $++%
 88MM*txx/077MM'DGG+,>>MM*T^^;<!!MM2T5K5KKLxx#~ 000r   c                 H   |sy| j                   |j                   k(  xr | j                  |j                  k(  xrj | j                  |j                  k(  xrO | j                  |j                  k(  xr4 | j                  |j                  k(  xr | j
                  |j
                  k(  S NF)r  r<   r  r/   r  r  r-   others     r   __eq__z
Key.__eq__s  s    KK5<<' BEII%B588#B /B %//1	B
 &&%*A*AA	
r   c                 &    | j                  |       S rq   r  r  s     r   __ne__z
Key.__ne__      ;;u%%%r   )NNNN)
r   r   r   r   r	   r  r2   r   r  r  r   r   r   rK   rK   >  s0    " C $$1

&r   rK   c                   .    e Zd ZdZeZddZd Zd Zd Z	y)rL   aW  
    Used to obtain Media Initialization Section required to
    parse the applicable Media Segments (EXT-X-MAP)

    `uri`
      is a string. ex:: "https://priv.example.com/key.php?r=52"

    `byterange`
      value of BYTERANGE attribute

    `base_uri`
      uri the segment comes from in URI hierarchy. ex.: http://example.com/path/to
    Nc                 .    || _         || _        || _        y rq   )r/   r<   r   )r-   r/   r<   r   s       r   r2   zInitializationSection.__init__  s     "r   c                 *   g }| j                   r'|j                  dt        | j                         z          | j                  r'|j                  dt        | j                        z          dj	                  | j
                  dj                  |            S )NURI=z
BYTERANGE=z{tag}:{attributes}r   )r  
attributes)r<   rT   quotedr   r   r  r   r  s     r   r   zInitializationSection.__str__  sl    88MM&6$((#334>>MM,)??@#**txxCHHVDT*UUr   c                     |sy| j                   |j                   k(  xr4 | j                  |j                  k(  xr | j                  |j                  k(  S r  )r<   r   r/   r  s     r   r  zInitializationSection.__eq__  sG    HH		! 0%//10/	
r   c                 &    | j                  |       S rq   r  r  s     r   r  zInitializationSection.__ne__  r  r   rq   )
r   r   r   r   r
   r  r2   r   r  r  r   r   r   rL   rL     s#     C#
V
&r   rL   c                       e Zd ZeZy)rd   N)r   r   r   r   r  r   r   r   rd   rd     s    
Cr   rd   c                       e Zd ZdZd Zd Zy)rY   a  
    Playlist object representing a link to a variant M3U8 with a specific bitrate.

    Attributes:

    `stream_info` is a named tuple containing the attributes: `program_id`,
    `bandwidth`, `average_bandwidth`, `resolution`, `codecs` and `resolution`
    which is a a tuple (w, h) of integers

    `media` is a list of related Media entries.

    More info: http://tools.ietf.org/html/draft-pantos-http-live-streaming-07#section-3.3.10
    c                   	 || _         || _        |j                  d      }|?|j                  d      }|j	                  d      }t        |d         t        |d         f}nd }t        |d   |j                  d      |j                  d      |j                  d	      |j                  d
      |j                  d      |j                  d      ||j                  d      |j                  d      |j                  d      |j                  d      |j                  d      |j                  d      |j                  d            | _        g | _        dD ]8  }|j                  |      		s| xj                  t        	fd|      z  c_        : y )N
resolutionr   xr      	bandwidthvideoaudio	subtitlesclosed_captionsaverage_bandwidth
program_idcodecs
frame_ratevideo_range
hdcp_level
pathway_idstable_variant_idreq_video_layout)r+  r,  r-  r.  r/  r0  r1  r(  r2  r3  r4  r5  r6  r7  r8  )r-  r,  r.  c                 "    | j                   k(  S rq   )group_id)mr:  s    r   <lambda>z#Playlist.__init__.<locals>.<lambda>  s    1::+A r   )
r<   r/   rJ   stripsplitint
StreamInfostream_infor9   filter)
r-   r<   rA  r9   r/   r(  valuesresolution_pair
media_typer:  s
            @r   r2   zPlaylist.__init__  s`     __\2
!#))#.J%%c*F"6!9~s6!9~>O"O%!+.//'*//'*!ook2'OO,=>)oo.AB"|4&??8,"|4#6"|4"|4)oo.AB(__-?@
" 
9 	JJ"z2HJJ&!A5IIJ	Jr   c                 P   g }t        | j                        g}| j                  D ]\  }|j                  |v r||j                  gz  }|j                  j	                         }|j                  | d|j                   d       ^ ddj                  |      z   dz   | j                  z   S )Nz="r   z#EXT-X-STREAM-INF:r   r   )	r   rA  r9   typer   rT   r:  r   r<   )r-   media_types
stream_infr9   rE  s        r   r   zPlaylist.__str__  s    $**+,
ZZ 	FEzz[(

|+"ZZ--/
!!ZL5>>2B!"DE	F $chhz&::TADHHLLr   Nr   r   r   r   r2   r   r   r   r   rY   rY     s    #JJMr   rY   c                       e Zd ZdZd Zd Zy)rZ   a  
    IFramePlaylist object representing a link to a
    variant M3U8 i-frame playlist with a specific bitrate.

    Attributes:

    `iframe_stream_info` is a named tuple containing the attributes:
     `program_id`, `bandwidth`, `average_bandwidth`, `codecs`, `video_range`,
     `hdcp_level` and `resolution` which is a tuple (w, h) of integers

    More info: http://tools.ietf.org/html/draft-pantos-http-live-streaming-07#section-3.3.13
    c                    || _         || _        |j                  d      }|.|j                  d      }t	        |d         t	        |d         f}nd }t        |j                  d      |j                  d      |j                  d      d d d |j                  d      ||j                  d	      |j                  d
      |j                  d      d |j                  d      |j                  d      d       | _        y )Nr(  r)  r   r*  r+  r0  r,  r1  r2  r4  r5  r6  r7  )r+  r0  r,  r-  r.  r/  r1  r(  r2  r4  r5  r3  r6  r7  r8  )r<   r/   rJ   r>  r?  r@  r=   )r-   r/   r<   r=   r(  rC  rD  s          r   r2   zIFramePlaylist.__init__  s     '++L9
!%%c*F"6!9~s6!9~>O"O",(,,[90445HI$((1  )--l;&%))(3*..}=)--l;)--l;0445HI!##
r   c                    g }| j                   j                  r(|j                  d| j                   j                  z         | j                   j                  r(|j                  d| j                   j                  z         | j                   j                  r(|j                  d| j                   j                  z         | j                   j
                  r\t        | j                   j
                  d         dz   t        | j                   j
                  d         z   }|j                  d|z          | j                   j                  r1|j                  dt        | j                   j                        z          | j                   j                  r(|j                  d	| j                   j                  z         | j                   j                  r(|j                  d
| j                   j                  z         | j                  r'|j                  dt        | j                        z          | j                   j                  r1|j                  dt        | j                   j                        z          | j                   j                  r1|j                  dt        | j                   j                        z          ddj                  |      z   S )NPROGRAM-ID=%dBANDWIDTH=%dAVERAGE-BANDWIDTH=%dr   r)  r*  RESOLUTION=CODECS=VIDEO-RANGE=%sHDCP-LEVEL=%sr   PATHWAY-ID=STABLE-VARIANT-ID=z#EXT-X-I-FRAME-STREAM-INF:r   )r=   r1  rT   r+  r0  r(  r   r2  r"  r4  r5  r<   r6  r7  r   )r-   iframe_stream_infress      r   r   zIFramePlaylist.__str__!  sE   ""--$$$"9"9"D"DD "",,$$^d6M6M6W6W%WX""44$$&)@)@)R)RR ""--D++66q9:d--88;<= 
 $$]S%89""))$$Y8O8O8V8V1W%WX""..$$ 4#:#:#F#FF ""--$$$"9"9"D"DD 88$$VfTXX.>%>?""--$$t'>'>'I'I JJ ""44$$$vd.E.E.W.W'XX ,chh7H.IIIr   NrJ  r   r   r   rZ   rZ     s    
>(Jr   rZ   c                   T    e Zd ZdZdZdZdZdZdZdZ	dZ
dZdZdZdZdZdZdZd Zd Zy)r@  Nc                    |j                  d      | _        |j                  d      | _        |j                  d      | _        |j                  d      | _        |j                  d      | _        |j                  d      | _        |j                  d      | _        |j                  d      | _        |j                  d	      | _	        |j                  d
      | _
        |j                  d      | _        |j                  d      | _        |j                  d      | _        |j                  d      | _        |j                  d      | _        y )Nr+  r/  r0  r1  r(  r2  r-  r,  r.  r3  r4  r5  r6  r7  r8  )rJ   r+  r/  r0  r1  r(  r2  r-  r,  r.  r3  r4  r5  r6  r7  r8  )r-   r  s     r   r2   zStreamInfo.__init__]  s    K0%zz*;<!',?!@ **\2 **\2jj*ZZ(
ZZ(
K0 **\2!::m4 **\2 **\2!',?!@ &

+= >r   c                    g }| j                   |j                  d| j                   z         | j                  |j                  d| j                  z         | j                  |j                  d| j                  z         | j                  |j                  d| j                  z         | j
                  Ht        | j
                  d         dz   t        | j
                  d         z   }|j                  d|z          | j                  S|j                  d	t        j                  | j                        j                  t        j                  d
            z         | j                  '|j                  dt        | j                        z          | j                  |j                  d| j                  z         | j                  |j                  d| j                  z         | j                  '|j                  dt        | j                        z          | j                   '|j                  dt        | j                         z          | j"                  '|j                  dt        | j"                        z          dj%                  |      S )NrN  zCLOSED-CAPTIONS=%srO  rP  r   r)  r*  rQ  zFRAME-RATE=%gz1.000rR  rS  rT  rU  rV  zREQ-VIDEO_LAYOUT=r   )r1  rT   r/  r+  r0  r(  r   r3  decimalDecimalquantizer2  r"  r4  r5  r6  r7  r8  r   )r-   rI  rX  s      r   r   zStreamInfo.__str__n  s   
??&o?@+2T5I5IIJ>>%nt~~=>!!-4t7M7MMN??&dooa()C/#dooa6H2IICmc12??&//$//2;;GOOG<TUV ;;"i&*==>'.1A1AAB??&o?@??&mfT__.EEF!!-2VD<R<R5SST  ,1F4;P;P4QQRxx
##r   )r   r   r   r+  r/  r0  r1  r(  r2  r-  r,  r.  r3  r4  r5  r6  r7  r8  r2   r   r   r   r   r@  r@  L  sZ    IOJJFEEIJKJJ?"$r   r@  c                   @    e Zd ZdZ	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZd Zd Zy)rW   a  
    A media object from a M3U8 playlist
    https://tools.ietf.org/html/draft-pantos-http-live-streaming-16#section-4.3.4.1

    `uri`
      a string with the media uri

    `type`
    `group_id`
    `language`
    `assoc-language`
    `name`
    `default`
    `autoselect`
    `forced`
    `instream_id`
    `characteristics`
    `channels`
    `stable_rendition_id`
      attributes in the EXT-MEDIA tag

    `base_uri`
      uri the media comes from in URI hierarchy. ex.: http://example.com/path/to
    Nc                     || _         || _        || _        || _        || _        || _        || _        || _        || _        || _	        || _
        |	| _        |
| _        || _        || _        y rq   )r/   r<   rG  r:  languagenamedefault
autoselectforcedassoc_languageinstream_idcharacteristicschannelsstable_rendition_idextras)r-   r<   rG  r:  ra  rb  rc  rd  re  rh  ri  rj  rf  rg  r/   rk  s                   r   r2   zMedia.__init__  sq    $ !	  	$,&. #6 r   c                    g }| j                   r'|j                  dt        | j                         z          | j                  r|j                  d| j                  z          | j                  r'|j                  dt        | j                        z          | j
                  r'|j                  dt        | j
                        z          | j                  r'|j                  dt        | j                        z          | j                  r'|j                  dt        | j                        z          | j                  r|j                  d| j                  z          | j                  r|j                  d| j                  z          | j                  r|j                  d	| j                  z          | j                  r'|j                  d
t        | j                        z          | j                  r'|j                  dt        | j                        z          | j                  r'|j                  dt        | j                        z          | j                  r'|j                  dt        | j                        z          ddj                  |      z   S )Nr   TYPE=z	GROUP-ID=	LANGUAGE=zASSOC-LANGUAGE=zNAME=zDEFAULT=zAUTOSELECT=zFORCED=zINSTREAM-ID=zCHARACTERISTICS=z	CHANNELS=zSTABLE-RENDITION-ID=z#EXT-X-MEDIA:r   )r<   rT   r"  rG  r:  ra  rf  rb  rc  rd  re  rg  rh  ri  rj  r   )r-   	media_outs     r   rs   zMedia.dumps  s   	88VfTXX&66799Wtyy01==[6$--+@@A==[6$--+@@A.8K8K1LLM99Wvdii'889<<Z$,,67??]T__<=;;Y45^fT5E5E.FFG/&9M9M2NNO==[6$--+@@A##3fT=U=U6VVW)!444r   c                 "    | j                         S rq   rr   rt   s    r   r   zMedia.__str__  rv   r   )NNNNNNNNNNNNNNr  r   r   r   rW   rW     sD    6   D5@r   rW   c                       e Zd Zd Zy)TagListc                 ^    | D cg c]  }t        |       }}dj                  |      S c c}w r   r  )r-   r  r   s      r   r   zTagList.__str__  s-    &*+s#c(++yy   ,r  Nr  r   r   r   rr  rr    r  r   rr  c                       e Zd Zed        Zy)rV   c                 @    | D cg c]  }|j                    c}S c c}w rq   r   r   s     r   r<   zMediaList.uri  s    '+,e		,,,r   N)r   r   r   r   r<   r   r   r   rV   rV     s    - -r   rV   c                       e Zd Zy)rX   Nr   r   r   r   rX   rX     r   r   rX   c                       e Zd Zy)rb   Nr   r   r   r   rb   rb     r   r   rb   c                       e Zd ZddZd Zy)r\   Nc                 2    t        |      | _        || _        y rq   )floattime_offsetprecise)r-   r{  r|  s      r   r2   zStart.__init__  s     -r   c                     dt        | j                        z   g}| j                  r5| j                  dv r'|j                  dt        | j                        z          t        dz   dj                  |      z   S )NzTIME-OFFSET=)YESNOzPRECISE=r   r   )r   r{  r|  rT   r   r   r  s     r   r   zStart.__str__  s_     3t'7'7#889<<DLLM9MM*s4<<'889S 388F#333r   rq   )r   r   r   r2   r   r   r   r   r\   r\     s    4r   r\   c                        e Zd ZddZd Zd Zy)ra   Nc                 <    || _         || _        || _        || _        y rq   )r/   r<   last_msn	last_part)r-   r/   r<   r  r  s        r   r2   zRenditionReport.__init__  s      "r   c                 0   g }|j                  dt        | j                        z          |j                  dt        | j                        z          | j
                  '|j                  dt        | j
                        z          ddj                  |      z   S )Nr   z	LAST-MSN=z
LAST-PART=z#EXT-X-RENDITION-REPORT:r   )rT   r"  r<   r   r  r  r   r   s     r   rs   zRenditionReport.dumps  ss    fvdhh//0kC$667>>%MM,T^^)<<=)CHHV,<<<r   c                 "    | j                         S rq   rr   rt   s    r   r   zRenditionReport.__str__   rv   r   rq   r   r   r   r2   rs   r   r   r   r   ra   ra     s    #=r   ra   c                       e Zd Zd Zy)r`   c                 ^    | D cg c]  }t        |       }}dj                  |      S c c}w r   r  )r-   r   r   s      r   r   zRenditionReportList.__str__%  s-    ,01&#f+11yy   2r  Nr  r   r   r   r`   r`   $  r  r   r`   c                   0    e Zd Z	 	 	 	 	 ddZd Zd Zd Zy)r]   Nc                 J    || _         || _        || _        || _        || _        y rq   )can_skip_untilcan_block_reload	hold_backpart_hold_backcan_skip_dateranges)r-   r  r  r  r  r  s         r   r2   zServerControl.__init__+  s+     - 0",#6 r   c                     t        | |      S rq   getattrr-   items     r   __getitem__zServerControl.__getitem__9      tT""r   c           	         g }| j                   r|j                  d| j                   z         dD ]3  }| |   s	|j                  t        |      dt        | |                5 | j                  rQ|j                  dt        | j                        z         | j
                  r|j                  d| j
                  z         ddj                  |      z   S )NzCAN-BLOCK-RELOAD=%s)r  r  r   zCAN-SKIP-UNTIL=%szCAN-SKIP-DATERANGES=%sz#EXT-X-SERVER-CONTROL:r   )r  rT   denormalize_attributer   r  r  r   )r-   ctrlri   s      r   rs   zServerControl.dumps<  s      KK-0E0EEF3 	DDz,T24DT$Z4PR	 KK+.>t?R?R.SST''4t7O7OOP'#((4.88r   c                 "    | j                         S rq   rr   rt   s    r   r   zServerControl.__str__O  rv   r   )NNNNNr   r   r   r2   r  rs   r   r   r   r   r]   r]   *  s'      7#9&r   r]   c                        e Zd ZddZd Zd Zy)r_   Nc                      || _         || _        y rq   )skipped_segmentsrecently_removed_dateranges)r-   r  r  s      r   r2   zSkip.__init__T  s     0+F(r   c                     g }|j                  d| j                  z         | j                  '|j                  dt        | j                        z         ddj	                  |      z   S )NzSKIPPED-SEGMENTS=%szRECENTLY-REMOVED-DATERANGES=%sz#EXT-X-SKIP:r   )rT   r  r  r"  r   )r-   rC   s     r   rs   z
Skip.dumpsX  sb    )D,A,AAB++7KK099:;
 ..r   c                 "    | j                         S rq   rr   rt   s    r   r   zSkip.__str__c  rv   r   rq   r  r   r   r   r_   r_   S  s    G	/r   r_   c                        e Zd ZddZd Zd Zy)r^   Nc                     || _         y rq   )part_target)r-   r  s     r   r2   zPartInformation.__init__h  s
    &r   c                 2    dt        | j                        z  S )Nz#EXT-X-PART-INF:PART-TARGET=%s)r   r  rt   s    r   rs   zPartInformation.dumpsk  s    /2B4CSCS2TTTr   c                 "    | j                         S rq   rr   rt   s    r   r   zPartInformation.__str__n  rv   r   rq   r  r   r   r   r^   r^   g  s    'Ur   r^   c                   (    e Zd Z	 ddZd Zd Zd Zy)re   Nc                 J    || _         || _        || _        || _        || _        y rq   )	hint_typer/   r<   byterange_startbyterange_length)r-   rG  r/   r<   r  r  s         r   r2   zPreloadHint.__init__s  s)      . 0r   c                     t        | |      S rq   r  r  s     r   r  zPreloadHint.__getitem__|  r  r   c                    g }|j                  d| j                  z          |j                  dt        | j                        z          dD ]*  }| |   	|j                  t	        |       d| |           , ddj                  |      z   S )Nrm  r   )r  r  r   z#EXT-X-PRELOAD-HINT:r   )rT   r  r"  r<   r  r   )r-   hintri   s      r   rs   zPreloadHint.dumps  s    Gdnn,-FVDHH--.; 	KDDz%4T:;1T$ZLIJ	K &66r   c                 "    | j                         S rq   rr   rt   s    r   r   zPreloadHint.__str__  rv   r   )NNr  r   r   r   re   re   r  s    JN1#	7r   re   c                        e Zd ZddZd Zd Zy)rc   Nc                 <    || _         || _        || _        || _        y rq   )rF   valuer<   ra  )r-   rF   r  r<   ra  s        r   r2   zSessionData.__init__  s    
 r   c                    dt        | j                        z   g}| j                  r(|j                  dt        | j                        z          n3| j                  r'|j                  dt        | j                        z          | j
                  r'|j                  dt        | j
                        z          ddj                  |      z   S )NzDATA-ID=zVALUE=r   rn  z#EXT-X-SESSION-DATA:r   )r"  rF   r  rT   r<   ra  r   )r-   session_data_outs     r   rs   zSessionData.dumps  s    &)==>::##Hvdjj/A$ABXX##FVDHH-=$=>==##K&2G$GH%1A(BBBr   c                 "    | j                         S rq   rr   rt   s    r   r   zSessionData.__str__  rv   r   )NNNr  r   r   r   rc   rc     s    !
Cr   rc   c                       e Zd Zy)r   Nr   r   r   r   r   r     r   r   r   c                       e Zd Zd Zd Zd Zy)r   c                    |d   | _         |j                  d      | _        |j                  d      | _        |j                  d      | _        |j                  d      | _        |j                  d      | _        |j                  d      | _        |j                  d      | _        |j                  d	      | _	        |j                  d
      | _
        |D cg c]'  }|j                  d      s||j                  |      f) c}| _        y c c}w )Nid
start_dateclassend_dater   planned_duration
scte35_cmd
scte35_out	scte35_inend_on_nextx_)r  rJ   r  class_r  r   r  r  r  r  r  
startswithx_client_attrs)r-   r  ri   s      r   r2   zDateRange.__init__  s    , **\2jj)

:.

:. &

+= > **\2 **\2K0!::m417
)-4??4;PT6::d#$
 
s   D
,D
c                 B   g }|j                  dt        | j                        z          | j                  r'|j                  dt        | j                        z          | j                  r'|j                  dt        | j                        z          | j
                  r'|j                  dt        | j
                        z          | j                  r'|j                  dt        | j                        z          | j                  r'|j                  dt        | j                        z          | j                  r|j                  d| j                  z          | j                  r|j                  d| j                  z          | j                  r|j                  d	| j                  z          | j                  r|j                  d
| j                  z          t        | j                        D ]$  \  }}|j                  t        |       d|        & ddj!                  |      z   S )NzID=zSTART-DATE=zCLASS=z	END-DATE=	DURATION=zPLANNED-DURATION=zSCTE35-CMD=zSCTE35-OUT=z
SCTE35-IN=zEND-ON-NEXT=r   z#EXT-X-DATERANGE:r   )rT   r"  r  r  r  r  r   r   r  r  r  r  r  sortedr  r  r   )r-   r   ri   r  s       r   rs   zDateRange.dumps  s   	01 ??]VDOO-DDE;;Xt{{(;;<==[6$--+@@A==[+;DMM+JJK  #&6t7L7L&MM ??]T__<=??]T__<=>>\DNN:;^d.>.>>? "$"5"56 	GKD% 5d ;<AeWEF	G #SXXi%888r   c                 "    | j                         S rq   rr   rt   s    r   r   zDateRange.__str__  rv   r   Nr  r   r   r   r   r     s    
!9Fr   r   c                        e Zd ZddZd Zd Zy)rf   Nc                 .    || _         || _        || _        y rq   )r/   r<   r6  )r-   r/   
server_urir6  s       r   r2   zContentSteering.__init__  s     $r   c                     g }|j                  dt        | j                        z          | j                  '|j                  dt        | j                        z          ddj	                  |      z   S )NzSERVER-URI=rU  z#EXT-X-CONTENT-STEERING:r   )rT   r"  r<   r6  r   )r-   steerings     r   rs   zContentSteering.dumps  sY    txx(889??&OOMF4??,CCD)CHHX,>>>r   c                 "    | j                         S rq   rr   rt   s    r   r   zContentSteering.__str__  rv   r   rq   r  r   r   r   rf   rf     s    %
?r   rf   c                       e Zd ZdZd Zd Zy)r[   a~  
    ImagePlaylist object representing a link to a
    variant M3U8 image playlist with a specific bitrate.

    Attributes:

    `image_stream_info` is a named tuple containing the attributes:
     `bandwidth`, `resolution` which is a tuple (w, h) of integers and `codecs`,

    More info: https://github.com/image-media-playlist/spec/blob/master/image_media_playlist_v0_4.pdf
    c                    || _         || _        |j                  d      }|.|j                  d      }t	        |d         t	        |d         f}nd }t        |j                  d      |j                  d      |j                  d      d d d |j                  d      ||j                  d	      d d d |j                  d
      |j                  d            | _        y )Nr(  r)  r   r*  r+  r0  r,  r1  r2  r6  r7  )r+  r0  r,  r-  r.  r/  r1  r(  r2  r4  r5  r3  r6  r7  )r<   r/   rJ   r>  r?  r@  r?   )r-   r/   r<   r?   r(  rC  rD  s          r   r2   zImagePlaylist.__init__   s     &**<8
!%%c*F"6!9~s6!9~>O"O!+'++K8/334GH#''0  (,,\:&$((2(,,\:/334GH!"
r   c                    g }| j                   j                  r(|j                  d| j                   j                  z         | j                   j                  r(|j                  d| j                   j                  z         | j                   j                  r(|j                  d| j                   j                  z         | j                   j
                  r\t        | j                   j
                  d         dz   t        | j                   j
                  d         z   }|j                  d|z          | j                   j                  r1|j                  dt        | j                   j                        z          | j                  r'|j                  d	t        | j                        z          | j                   j                  r1|j                  d
t        | j                   j                        z          | j                   j                  r1|j                  dt        | j                   j                        z          ddj                  |      z   S )NrN  rO  rP  r   r)  r*  rQ  rR  r   rU  rV  z#EXT-X-IMAGE-STREAM-INF:r   )r?   r1  rT   r+  r0  r(  r   r2  r"  r<   r6  r7  r   )r-   image_stream_infrX  s      r   r   zImagePlaylist.__str__  s   !!,,##Od6L6L6W6W$WX!!++##NT5K5K5U5U$UV!!33##&)?)?)Q)QQ !!,,D**55a89d,,77:;< 
 ##MC$78!!((##It7M7M7T7T0U$UV88##FVDHH-=$=>!!,,##t'='='H'H II !!33##$vd.D.D.V.V'WW *CHH5E,FFFr   NrJ  r   r   r   r[   r[     s    

<Gr   r[   c                   "    e Zd ZdZd Zd Zd Zy)Tilesz
    Image tiles from a M3U8 playlist

    `resolution`
      resolution attribute from EXT-X-TILES tag

    `layout`
      layout attribute from EXT-X-TILES tag

    `duration`
      duration attribute from EXT-X-TILES tag
    c                 .    || _         || _        || _        y rq   )r(  layoutr   )r-   r(  r  r   s       r   r2   zTiles.__init__M  s    $ r   c                     g }|j                  d| j                  z          |j                  d| j                  z          |j                  d| j                  z          ddj	                  |      z   S )NrQ  zLAYOUT=r  z#EXT-X-TILES:r   )rT   r(  r  r   r   )r-   tiless     r   rs   zTiles.dumpsR  sY    ]T__45Y,-[4==01%00r   c                 "    | j                         S rq   rr   rt   s    r   r   zTiles.__str__Z  rv   r   Nr  r   r   r   r  r  ?  s    !
1r   r  c                     | sy |D ]h  }|s| j                  dd       |j                  k(  s&| j                  dd      |j                  k(  sF| j                  dd       |j                  k(  sf|c S  t	        d      )Nr<   r  NONEr  zNo key found for key data)rJ   r<   r  r  KeyError)keydatakeylistr7   s      r   rO   rO   ^  st      E4(CGG3KK&1SZZ?KKd+svv5
 .
//r   c                 B    | j                  dd      j                         S )N_-)replacer   )	attributes    r   r  r  m  s    S#&,,..r   c                     d| z  S )Nz"%s"r   )strings    r   r"  r"  q  s    F?r   c                 @   t        j                         5 }d|_        t        j                  t	        |             }t	        ||j                         k(  r$|j                  t        j                  d            n|j                               cd d d        S # 1 sw Y   y xY w)N   r*  )r\  localcontextprecr]  r   to_integral_valuer^  	normalize)numberctxds      r   r   r   u  sw    				 
3OOCK(A'')) JJwq)*

 
 
s   A5BB)3r\  r   m3u8.mixinsr   r   m3u8.parserr   r   m3u8.protocolr   r   r	   r
   r   r   	Exceptionr   r   rN   listrM   r   r   rK   rL   rd   rY   rZ   r@  rW   rr  rV   rX   rb   r\   ra   r`   r]   r_   r^   re   rc   r   r   rf   r[   r  rO   r  r"  r   r   r   r   <module>r     s    	 ; / 	Y 	j1 j1Z~5m ~5BC$, C(\ ] \ ~!3 !B&- B&J(&M (&V ?M} ?MDUJ] UJp@$ @$F]M ]@!d !-- -	70 		g 	
4 
4m (!$ 4 !& &R ( - 8 .	G 	4 4nm &IGM IGXM >0/
r   