
    iS                        d dl Z d dlZd dlZd dlZd dlmZ d dlmZ d dlm	Z	 d dl
mZmZmZ d dlmZ d dlmZmZ d dlmZ d d	lmZmZmZ d d
lmZ d dlmZmZ ddlmZm Z  ddl!m"Z"  e       Z#ejH                  jK                  dd      Z&ejH                  jO                  dd      Z(ejH                  jK                  dd      Z)ejH                  jK                  ddd      Z* G d d      Z+y)    N)Dict)Console)get_headers)
join_videojoin_audiosjoin_subtitles)
create_nfo)download_trackercontext_tracker)MediaPlayers)config_manager
os_managerinternet_manager)MediaDownloader)get_wvd_pathget_prd_path   )	MPDParser	DRMSystem)
DRMManagerM3U8_DOWNLOADcleanup_tmp_folderM3U8_CONVERSION	extensionskip_downloadgenerate_nfoF)defaultc                       e Zd Zddedeeef   dedeeef   dededed	ed
edeeef   f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)DASH_DownloaderNlicense_urllicense_headersmpd_urlmpd_headersmpd_sub_listoutput_pathdrm_preferencedecrypt_preferencekeycookiesc           	      T   |rt        |      j                         nd| _        |rt        |      j                         nd| _        |xs
 t	               | _        || _        |xs g | _        |j                         | _	        |	| _
        |
xs i | _        |j                         | _        t        t               t               t         j"                  j%                  dd      t         j"                  j%                  dd            | _        t(        j*                  | _        t(        j,                  | _        d| _        t1        j2                  |      | _        | j4                  j7                  dt8               s| xj4                  dt8         z  c_        t:        j<                  j?                  t:        j<                  jA                  | j4                              d   | _!        t:        j<                  jE                  t:        j<                  jG                  | j4                        | jB                  dz         | _$        t:        j<                  jK                  | j4                        | _&        d| _'        g | _(        i | _)        d| _*        dx| _+        x| _,        | _-        d| _.        d| _/        d| _0        y)a  
        Initialize DASH Downloader.
        
        Parameters:
            license_url: URL to obtain DRM license
            mpd_url: URL of the MPD manifest
            mpd_sub_list: List of subtitle dicts (unused with MediaDownloader)
            output_path: Full path including filename and extension (e.g., /path/to/video.mp4)
            drm_preference: Preferred DRM system ('widevine', 'playready', 'auto')
        N
remote_cdmwidevine	playready.r   
_dash_temp)1strstripr"   r    r   r#   r!   r$   lowerr&   r(   r)   r'   r   r   r   r   r+   getdrm_managerr   download_id	site_nameraw_mpd_pathr   get_sanitize_pathr%   endswithEXTENSION_OUTPUTospathsplitextbasenamefilename_basejoindirname
output_direxistsfile_already_existsdrm_infodecryption_keyskid_to_labelmedia_downloader	meta_jsonmeta_selectedraw_mpderrorlast_merge_resultmedia_players)selfr    r!   r"   r#   r$   r%   r&   r'   r(   r)   s              \/home/nidran/Documenti/script/streaming-community/StreamingCommunity/core/downloader/dash.py__init__zDASH_Downloader.__init__'   s4    07s7|))+D7B3{+113&7+-.(.B,224}""4":":"<%lnlnnF_F_FcFcdpr|F}  @N  @Y  @Y  @]  @]  ^j  lw  @x  y +66(22  &77D((1-=,>)?@!$4#5 66WW--bgg.>.>t?O?O.PQRST'',,rwwt7G7G'H$J\J\_kJkl#%77>>$2B2B#C  ! $=AAA+dl
!%!    c                 L   	 t        | j                  | j                        }|j                  | j                         | j                  |||||       |j                  | j                  ||||      | _        y# t        $ r"}t        j                  d|        Y d}~yd}~ww xY w)z Fetch and setup DRM information.)headersTz[yellow]Warning parsing MPD: NF)r   r"   r#   parse_from_filerK   _map_kids_to_labelsget_drm_infor&   rE   	Exceptionconsoleprint)rO   selected_idsselected_kidsselected_langsselected_periodsparseres          rP   _setup_drm_infozDASH_Downloader._setup_drm_infoU   s    	t||T5E5EFF""4<<0 $$V\=.Zjk #//##\= 0DM  	MM9!=>	s   A5A8 8	B#BB#c                    i | _         |j                  ||||      }i }|D ].  }|d   dv r|j                  |d   g       j                  |       0 t	        |||g      }	|j                         D ]{  \  }
}t        |D ch c]  }|d   	 c}      dk(  xr |	 }|D ]M  }|d   s	|d   j                         j                  dd      }| j                  ||
|      }|| j                   |<   O } yc c}w )zMap KIDs to descriptive labels.content_type)imagetextdefault_kid   - N)
rG   get_adaptation_sets_info
setdefaultappendanyitemslenr2   replace_generate_label)rO   r_   r[   r\   r]   r^   setsgroupss
has_filterc_typern   iis_uniitemnorm_kidlabels                    rP   rV   z#DASH_Downloader._map_kids_to_labelsi   s   ..|]N\lm  	?A $55a/4;;A>	?
 ,~FG
#\\^ 		4MFEE:q!M*:;q@S^F 4M*.446>>sBG,,T66B.3!!(+4		4:s   >C.
c                     |rd| S |g}|j                  d      r|j                  |d    d       |j                  d      r |d   dk7  r|j                  d|d    d       dj                  |      S )	zGenerate label for a stream.zall heightplanguageN/A() )r3   rl   r@   )rO   ry   rc   
is_uniformpartss        rP   rq   zDASH_Downloader._generate_label   s~    ,((88HLLDN+1-.88JD$4$=LL1T*-.a01xxrR   c                    t        | j                  j                  dg             dkD  r| j                  R| j                  dk(  sCt        | j                  j                  dg             dkD  r| j                  | j                  dk(  r{t        | j                  j                  dg             dkD  rS| j                  r| j                  dk(  r8| j                  r| j                  dk(  rt
        j                  d       d| _        y| j                  d   }	 |t        j                  k(  rb| j                  j                  | j                  j                  d	g       | j                  | j                  | j                  | j                        }n|t        j                  k(  rb| j                  j                  | j                  j                  d
g       | j                  | j                  | j                  | j                        }n#t
        j                  d|        d| | _        y|r|| _        yd| _        y# t"        $ r,}t
        j                  d|        d| | _        Y d}~yd}~ww xY w)z(Fetch decryption keys based on DRM type.available_drm_typesr   Nri   zJ[yellow]DRM detected but missing both license_url and key. Cannot proceed.z5Missing license_url and key for DRM-protected contentFselected_drm_typewidevine_psshplayready_psshz[red]Unsupported DRM type: zUnsupported DRM type: TzFailed to fetch decryption keysz[red]Error fetching keys: zKey fetch error: )ro   rE   r3   r    r(   rY   rZ   rL   r   WIDEVINEr4   get_wv_keysr!   rG   	PLAYREADYget_pr_keysrF   rX   )rO   drm_typekeysr`   s       rP   _fetch_decryption_keysz&DASH_Downloader._fetch_decryption_keys   s   t}}  !6;<q@dFVFVF^bfbrbrvxbx  ~A  BF  BO  BO  BS  BS  Ti  km  Bn  ~o  rs  ~s  y}  yA  yA  yI  MQ  MU  MU  Y[  M[DMM%%&;R@AAEtO_O_cgcscswycy  EI  EM  EM  QU  QY  QY  ]_  Q_jkT
==!45	9---''33DMM4E4EoWY4Z\`\l\lnr  oC  oC  EI  EM  EM  OS  O`  O`  aY000''33DMM4E4EFVXZ4[]a]m]mos  pD  pD  FJ  FN  FN  PT  Pa  Pa  b ;H:FG5hZ@
'+$ ?
 	MM6qc:;,QC0DJ	s%   DH1 	H1 )H1 1	I&:"I!!I&c                    g g g g f\  }}}}d}t         j                  j                  | j                        r	 t	        | j                  dd      5 }t        j                  |      }ddd       D ]  }t        |j                  d      xs |j                  d      dk(        }	|	rd	}| j                  ||       |j                  d
      x}
r|j                  |
j                                |j                  d      x}r|j                  t        |             | j                  ||        	 t#        | j$                  dd      }|s|rt         j                  j                  | j&                        r	 t	        | j&                  dd      5 }t        j                  |      }ddd       | j)                        }|D ]  }| j                  ||       |j                  d
      x}
r|j                  |
j                                |j                  d      x}r|j                  t        |             | j                  ||        	 t+        t,        j/                  |            t+        t,        j/                  |            t+        t,        j/                  |            t+        t,        j/                  |            fS # 1 sw Y   VxY w# t        $ r0}t        j!                  d| j                   d|        Y d}~d}~ww xY w# 1 sw Y   exY w# t        $ r/}t        j!                  d| j&                   d|        Y d}~d}~ww xY w)z7Extract selected track information from metadata files.Frz	utf-8-sig)encodingN
Resolution	MediaTypeVIDEOTLanguagePeriodIdz[yellow]Warning reading z: force_best_video)r;   r<   rC   rJ   openjsonloadboolr3   _extract_idsrl   r2   r0   _extract_kids_from_encryptinforX   rY   rZ   getattrrH   rI   _find_best_videolistdictfromkeys)rO   r[   r\   r]   r^   has_video_in_selectedfdatary   is_videolangpidr`   
force_best
best_videos                  rP   _extract_selected_track_infoz,DASH_Downloader._extract_selected_track_info   s   HJBPRTVEm^5E % 77>>$,,-T$,,cKH (A99Q<D( ! MD#DHH\$:$^dhh{>SW^>^_H04- %%dL9  $xx
33t3&--djjl; #hhz22s2(//C9 77mL#M, T224FN
$t~~8VP$..#D (99Q<D( "2248
& MD%%dL9  $xx
33t3&--djjl; #hhz22s2(//C9 77mLM" T]]<014m8T3UW[\`\i\ijx\yWz  }A  BF  BO  BO  P`  Ba  }b  c  	ce( (*  T 89K9K8LBqcRSST( ("  P 88H1#NOOPsa   K J:&CK 2L 
L B#L :K?K 	L %K;;L LL 	M%MMc                     |D cg c]:  }|j                  d      s|j                  d      dk(  r|j                  d      r|< }}|rt        |d       gS g S c c}w )z)Find best video track based on bandwidth.r   r   r   	Bandwidthc                 &    | j                  dd      S )Nr   r   r3   )xs    rP   <lambda>z2DASH_Downloader._find_best_video.<locals>.<lambda>   s    !%%Q*? rR   )r(   )r3   max)rO   r   ry   videoss       rP   r   z DASH_Downloader._find_best_video   sk     "
&$((;*?7*J% 
 

 FLF ?@ASQSS
s   ?Ac                    g }|j                  dd      }|rt        |      }|j                  |       |j                  |       d|v r6|j                  d      d   }|j                  |       |j                  |       d|v r7|j                  d      d   }|j                  |       |j                  |       yy|j                  d      x}r.t        |      }|j                  |       |j                  |       yy)z=Extract IDs from item, prioritizing specific ID over GroupId.Idri   :rh   GroupIdN)r3   r0   rl   split)	rO   ry   r[   	extractedtidtid_spartgidgid_ss	            rP   r   zDASH_Downloader._extract_ids   s    	hhtR HE&U#e|{{3'+##D)  &e|{{3'+##D)  & 
 HHY''S'HE&U# (rR   c                    |j                  di       }|j                  dg       D ]  }|j                  d      x}rR|j                  di       j                  d      x}r/|j                  |j                         j                  dd             |j                  dg       D ]U  }|j                  di       j                  d      x}s'|j                  |j                         j                  dd             W  y	)
z<Extract KIDs from EncryptInfo in MediaInit or MediaSegments.Playlist
MediaParts	MediaInitEncryptInfoKIDrh   ri   MediaSegmentsN)r3   rl   r2   rp   )rO   ry   r\   playlistr   initkid_valsegs           rP   r   z.DASH_Downloader._extract_kids_from_encryptinfo
  s    88J+LLr2 
	KD xx,,t,"hh}b9==eDD7D!(()@)@b)IJ xx4 K!ggmR8<<UCC7C!(()@)@b)IJK
	KrR   c           
      
   | j                   r#t        j                  d       | j                  dfS t	        j
                  | j                         	 t        | j                        | _        | j                  j                          t        | j                  | j                  | j                  | j                  | j                  | j                   | j"                  | j$                        | _        | j(                  r| j(                  | j&                  _        | j"                  r t-        j.                  | j"                  d       | j&                  j1                          | j&                  j3                         \  | _        | _        }| _        | j;                         } | j<                  | sDt?        j@                  d       | j"                  r"t-        jB                  | j"                  dd       y| jD                  rz| jD                  d	   rk| jG                         s[t?        j@                  d
| j@                          | j"                  r,t-        jB                  | j"                  d| j@                         ytH        r#t        j                  d       | j                  dfS | j"                  r t-        j.                  | j"                  d       | j&                  jK                  | jL                  r| jL                  nd       | j&                  jO                         }|jQ                  d      dk(  r/| j"                  r"t-        jB                  | j"                  dd       y| jS                  |      rDt?        j@                  d       | j"                  r"t-        jB                  | j"                  dd       y| j"                  r t-        j.                  | j"                  d       | jU                  |      }|rtV        jX                  j[                  |      s| j"                  rBt-        j\                  | j"                        r#t-        jB                  | j"                  dd       yt?        j@                  d       | j"                  r"t-        jB                  | j"                  dd       y| j_                  |       | ja                          tb        rte        | j                         | j"                  rIt-        jB                  | j"                  dtV        jX                  jg                  | j                               th        r!tk        jl                  | j                  d       | j                  dfS # t        $ r Y w xY w)z1Main execution flow for downloading DASH content.z[yellow]File already exists.F)urlrB   filenamerT   r)   r'   r5   r6   z
Parsing...zFailed to fetch DRM infozDRM parsing failed)successrL   )NTr   z!Failed to fetch decryption keys: z/[yellow]Skipping download as per configuration.downloadingNrL   	cancelledzNo media downloadedz	Muxing...zMerge operation failedzMerge failedT)r   r<   )ignore_errors)7rD   rY   rZ   r%   r   create_pathrB   r   rN   createrX   r   r"   r?   r#   r)   r'   r5   r6   rH   r$   external_subtitlesr
   update_statusparser_streamget_metadatarI   rJ   rK   r   ra   loggingrL   complete_downloadrE   r   SKIP_DOWNLOADset_keyrF   start_downloadr3   _no_media_downloaded_merge_filesr;   r<   rC   
is_stopped_move_to_final_location_print_summaryCREATE_NFO_FILESr	   abspathCLEANUP_TMPshutilrmtree)rO   _selected_infostatus
final_files        rP   startzDASH_Downloader.start  s+   ##MM89##U** 	t/	!-doo!>D%%'
 !0''$$LL#66((nn	!
 7;7H7HD!!4**4+;+;\J++- ?C>S>S>`>`>b;*At| 99; $t##]3MM45 2243C3CUZno ==T]]+@A..0 A$**NO##$66t7G7GQV^b^h^hi!MMKL##U** **4+;+;]K%%d>R>Rd&:&:X\]&&557 ::g+- 2243C3CUZef $$V,MM/0 2243C3CUZop **4+;+;[I&&v.

!;$4$?$?@P@P$Q 2243C3CUZef!MM23 2243C3CUZhi 	$$Z0 	t''(..t/?/?TVT[T[TcTcdhdtdtTuvMM$//>&&A  		s   4U   	U-,U-c                     |j                  d      du xr@ |j                  d      g k(  xr* |j                  d      g k(  xr |j                  d      g k(  S )z!Check if no media was downloaded.videoNaudios	subtitlesr   r   )rO   r   s     rP   r   z$DASH_Downloader._no_media_downloaded  sr    

7#t+  X

80D0J  XvzzZeOfjlOl  Xqwq{q{  }Q  rR  VX  rX  	YrR   c                    t         j                  j                  |      t         j                  j                  | j                        k7  rj	 t         j                  j	                  | j                        rt        j
                  | j                         t        j                  || j                         yy# t        $ r)}t        j                  d|        || _        Y d}~yd}~ww xY w)zMove file to final output path.z&[yellow]Warning: Could not move file: N)
r;   r<   r   r%   rC   removerenamerX   rY   rZ   )rO   r   r`   s      rP   r   z'DASH_Downloader._move_to_final_location  s    77??:&"''//$:J:J*KK.77>>$"2"23IId../		*d&6&67	 L
  . FqcJK#-  .s   A(B5 5	C'>C""C'c                 N   |r%|j                  d      r|d   j                  d      st        j                  d       d| _        y|d   d   }t        j
                  j                  |      s t        j                  d|        d| _        y|d   s^|d	   sYt        j                  d
       t        || j                        \  }}|| _	        t        j
                  j                  |      r|S dS |}|d   r| j                  ||d         }|d	   r| j                  ||d	         }|S )z$Merge downloaded files using FFmpeg.r   r<   z+[red]Error: Video track information missingzVideo track missingNz[red]Video file not found: zVideo file missingr   r   z5[cyan]
No additional tracks to merge, muxing video...)
video_pathout_path)r3   rY   rZ   rL   r;   r<   rC   r   r%   rM   _merge_audio_tracks_merge_subtitle_tracks)rO   r   r   merged_fileresult_jsoncurrent_files         rP   r   zDASH_Downloader._merge_files  s   VZZ0w8K8KF8SMMGH.DJG_V,
ww~~j)MM7
|DE-DJ h{(;MMRS'1%))($K &1D""$''.."=;G4G! (33L&BRSL +66|VKEXYLrR   c                 b   t         j                  dt        |       d       t        j                  j                  | j                  | j                   dt               }t        |||      \  }}}|| _
        t        j                  j                  |      r|S t         j                  d       |S )z&Merge audio tracks with current video.[cyan]
Merging [red]z [cyan]audio track(s)...z_with_audio.)r   audio_tracksr   z6[yellow]Audio merge failed, continuing with video only)rY   rZ   ro   r;   r<   r@   rB   r?   r:   r   rM   rC   )rO   r   r   audio_outputr   r   r   s          rP   r   z#DASH_Downloader._merge_audio_tracks  s    -c,.?-@@XYZww||DOO8J8J7K<XhWi5jk&1#%!'
#Q
 "-77>>+&MMRSrR   c                 `   t         j                  dt        |       d       t        j                  j                  | j                  | j                   dt               }t        |||      \  }}|| _
        t        j                  j                  |      r|S t         j                  d       |S )z)Merge subtitle tracks with current video.r   z [cyan]subtitle track(s)...z_final.)r   subtitles_listr   z;[yellow]Subtitle merge failed, continuing without subtitles)rY   rZ   ro   r;   r<   r@   rB   r?   r:   r   rM   rC   )rO   r   subtitle_tracks
sub_outputr   r   s         rP   r   z&DASH_Downloader._merge_subtitle_tracks  s    -c/.B-CC^_`WW\\$//d6H6H5IQaPb3cd
#1#*$
 [
 "-77>>+&MMWXrR   c                 `   t         j                  j                  | j                        syt	        j
                  t         j                  j                  | j                              }d}| j                  r6t        | j                  t              r| j                  j                  dd      }t        j                  d       t        j                  dt         j                  j                  | j                                t        j                  d|        t        j                  d|        y)zPrint download summary.Nr   timez
[green]Output:z  [cyan]Path: [red]z  [cyan]Size: [red]z  [cyan]Duration: [red])r;   r<   rC   r%   r   format_file_sizegetsizerM   
isinstancer   r3   rY   rZ   r   )rO   	file_sizedurations      rP   r   zDASH_Downloader._print_summary  s    ww~~d../$55bggoodFVFV6WX	!!j1G1G&N--11&%@H()+BGGOOD<L<L,M+NOP+I;78/z:;rR   )	NNNNNr,   bento4NN)__name__
__module____qualname__r0   r   r   rQ   ra   rV   rq   r   r   r   r   r   r   r   r   r   r   r   r    rR   rP   r   r   &   s    ,"C ,"$sCx. ,"Z] ,"swx{  ~A  yA  tB ,"  Y] ,"  sv ,"  OR ,"  ux ,"  JM ,"  _c  dg  il  dl  _m ,"\(42@:cxT$,Km'^Y	."H $ $<rR   r   ),r;   r   r   r   typingr   rich.consoler   $StreamingCommunity.utils.http_clientr   "StreamingCommunity.core.processorsr   r   r   -StreamingCommunity.core.processors.helper.nfor	   'StreamingCommunity.source.utils.trackerr
   r   -StreamingCommunity.source.utils.media_playersr   StreamingCommunity.utilsr   r   r    StreamingCommunity.source.N_m3u8r   StreamingCommunity.setupr   r   r_   r   r   drmr   rY   configget_boolr   r3   r:   r   r   r   r  rR   rP   <module>r     s    
     ! = V V D U F Q Q = ? )  )##,,_>RS!((,,->L %%..P!((112C^]b1c G< G<rR   