@@ -175,19 +175,40 @@ def download_subtitles(self) -> bool:
175175 for sub in self .selected_subs :
176176 try :
177177 language = sub .get ('language' )
178- fmt = sub .get ('format' )
179-
180- # Download subtitle
178+ fmt = sub .get ('format' , 'vtt' )
179+
181180 console .log (f"[cyan]Downloading subtitle[white]: [red]{ language } ({ fmt } )" )
182- response = client .get (sub .get ('url' ))
183- response .raise_for_status ()
184181
185- # Save subtitle file and make request
182+ # Get segment URLs (can be single or multiple)
183+ segment_urls = sub .get ('segment_urls' )
184+ single_url = sub .get ('url' )
185+
186+ # Build list of URLs to download
187+ urls_to_download = []
188+ if segment_urls :
189+ urls_to_download = segment_urls
190+ elif single_url :
191+ urls_to_download = [single_url ]
192+ else :
193+ console .print (f"[yellow]Warning: No URL found for subtitle { language } " )
194+ continue
195+
196+ # Download all segments
197+ all_content = []
198+ for seg_url in urls_to_download :
199+ response = client .get (seg_url )
200+ response .raise_for_status ()
201+ all_content .append (response .content )
202+
203+ # Concatenate all segments
204+ final_content = b'' .join (all_content )
205+
206+ # Save to file
186207 sub_filename = f"{ language } .{ fmt } "
187208 sub_path = os .path .join (self .subs_dir , sub_filename )
188209
189210 with open (sub_path , 'wb' ) as f :
190- f .write (response . content )
211+ f .write (final_content )
191212
192213 except Exception as e :
193214 console .print (f"[red]Error downloading subtitle { language } : { e } " )
@@ -212,12 +233,20 @@ def download_and_decrypt(self, custom_headers=None, query_params=None, key=None)
212233 self .error = None
213234 self .stopped = False
214235
236+ # Check if any representation is protected
237+ has_protected_content = any (rep .get ('protected' , False ) for rep in self .parser .representations )
238+
239+ # If no protection found, download without decryption
240+ if not has_protected_content :
241+ console .log ("[cyan]Content is not protected, downloading without decryption" )
242+ return self .download_segments (clear = True )
243+
215244 # Determine which DRM to use
216245 drm_type = self ._determine_drm_type ()
217246
218247 if not drm_type :
219- self . download_segments ( clear = True )
220- return True
248+ console . print ( "[red]Content is protected but no DRM system found" )
249+ return False
221250
222251 # Fetch keys based on DRM type
223252 keys = self ._fetch_drm_keys (drm_type , custom_headers , query_params , key )
@@ -251,15 +280,6 @@ def download_and_decrypt(self, custom_headers=None, query_params=None, key=None)
251280 # Download and decrypt video
252281 video_rep = self .get_representation_by_type ("video" )
253282 if video_rep :
254- video_key_info = key_mapping .get ("video" )
255- if not video_key_info and single_key :
256- console .print ("[yellow]Warning: no mapped key found for video; using the single available key." )
257- video_key_info = {"kid" : single_key ["kid" ], "key" : single_key ["key" ], "representation_id" : None , "default_kid" : None }
258- if not video_key_info :
259- self .error = "No key found for video representation"
260- return False
261-
262- console .log (f"[cyan]Using video key: [red]{ video_key_info ['kid' ]} [cyan]for representation [yellow]{ video_key_info .get ('representation_id' , 'N/A' )} " )
263283 video_downloader = MPD_Segments (tmp_folder = self .encrypted_dir , representation = video_rep , pssh = self ._get_pssh_for_drm (drm_type ), custom_headers = custom_headers )
264284 encrypted_path = video_downloader .get_concat_path (self .encrypted_dir )
265285
@@ -289,13 +309,28 @@ def download_and_decrypt(self, custom_headers=None, query_params=None, key=None)
289309 self .current_downloader = None
290310 self .current_download_type = None
291311
292- # Decrypt video using the mapped key
312+ # Decrypt video ONLY if it's protected
293313 decrypted_path = os .path .join (self .decrypted_dir , f"video.{ EXTENSION_OUTPUT } " )
294- result_path = decrypt_with_mp4decrypt ("Video" , encrypted_path , video_key_info ['kid' ], video_key_info ['key' ], output_path = decrypted_path )
314+
315+ if video_rep .get ('protected' , False ):
316+ video_key_info = key_mapping .get ("video" )
317+ if not video_key_info and single_key :
318+ console .print ("[yellow]Warning: no mapped key found for video; using the single available key." )
319+ video_key_info = {"kid" : single_key ["kid" ], "key" : single_key ["key" ], "representation_id" : None , "default_kid" : None }
320+
321+ if not video_key_info :
322+ self .error = "No key found for video representation"
323+ return False
295324
296- if not result_path :
297- self .error = f"Video decryption failed with key { video_key_info ['kid' ]} "
298- return False
325+ console .log (f"[cyan]Using video key: [red]{ video_key_info ['kid' ]} [cyan]for representation [yellow]{ video_key_info .get ('representation_id' , 'N/A' )} " )
326+ result_path = decrypt_with_mp4decrypt ("Video" , encrypted_path , video_key_info ['kid' ], video_key_info ['key' ], output_path = decrypted_path )
327+
328+ if not result_path :
329+ self .error = f"Video decryption failed with key { video_key_info ['kid' ]} "
330+ return False
331+ else :
332+ console .log ("[cyan]Video is not protected, copying without decryption" )
333+ shutil .copy2 (encrypted_path , decrypted_path )
299334
300335 else :
301336 self .error = "No video found"
0 commit comments