1919class NicoDownloader ():
2020 HEADERS = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36' }
2121
22- def __init__ (self , url_or_video_id , cookies ):
22+ def __init__ (self , url_or_video_id , cookies , proxy = None ):
2323 if m := re .search (r'/watch/([^?&]+)' , url_or_video_id ):
2424 self .video_id = m [1 ]
2525 else :
@@ -64,13 +64,27 @@ def validate_cookie(cookies):
6464 self .session .cookies .update (cookies )
6565 self .session .headers .update (self .HEADERS )
6666
67- self .proxy_host , self .proxy_port = None , None
68- proxies = getproxies ()
69- if http_proxy := proxies .get ('http' ):
70- parsed = urlparse (http_proxy )
71- self .proxy_host , self .proxy_port = parsed .hostname , parsed .port
72- print (f'INFO: Using proxy { self .proxy_host } :{ self .proxy_port } for websocket connection.' )
67+ # proxy settings
68+ if proxy .lower () == 'none' or proxy is None :
69+ proxy = None
70+ elif proxy == 'auto' :
71+ proxies = getproxies ()
72+ if proxy := proxies .get ('http' ):
73+ print (f'INFO: automatically use system proxy { proxy } .' )
7374
75+ # I don't think system proxy would be missing scheme, but just in case
76+ if proxy and '://' not in proxy :
77+ proxy = f'http://{ proxy } '
78+
79+ self .session .proxies = {'http' : proxy , 'https' : proxy }
80+ self .proxy = proxy
81+
82+ def create_ws (self , url ):
83+ host , port , type_ = None , None , None
84+ if self .proxy :
85+ parsed = urlparse (self .proxy )
86+ host , port , type_ = parsed .hostname , parsed .port , parsed .scheme
87+ return websocket .create_connection (url , header = self .HEADERS , http_proxy_host = host , http_proxy_port = port , proxy_type = type_ )
7488
7589 def fetch_page (self , url ):
7690 soup = get (url , session = self .session )
@@ -82,7 +96,7 @@ def download_comments(self, room_info, when):
8296 url = room_info ["data" ]["messageServer" ]["uri" ]
8397 thread_id = room_info ["data" ]["threadId" ]
8498
85- ws = websocket . create_connection (url , header = self . HEADERS , http_proxy_host = self . proxy_host , http_proxy_port = self . proxy_port )
99+ ws = self . create_ws (url )
86100 print (f'Start download comments from thread { thread_id } ' )
87101 sending = True
88102 while sending :
@@ -205,7 +219,7 @@ def download_timeshift(self, info_only=False, comments='yes', verbose=False, dum
205219 print (f'WS url is { ws_url } ' )
206220 print ('Creating websocket connection...' )
207221 # websocket.enableTrace(True)
208- ws = websocket . create_connection (ws_url , header = self . HEADERS , http_proxy_host = self . proxy_host , http_proxy_port = self . proxy_port )
222+ ws = self . create_ws (ws_url )
209223 verbose and print ("Sent startWatching" )
210224 ws .send ('{"type":"startWatching","data":{"stream":{"quality":"' + max_quality + '","protocol":"hls","latency":"low","chasePlay":false},"room":{"protocol":"webSocket","commentable":true},"reconnect":false}}' )
211225 room_info = None
@@ -255,7 +269,9 @@ def download_timeshift(self, info_only=False, comments='yes', verbose=False, dum
255269 # do not use arrays. the way python quotes & is not compatible with cmd/bat which minyami uses.
256270 # See: https://stackoverflow.com/questions/74700723/
257271 # Make sure to also use shell=True for *nix systems
258- cmd = f'minyami -d "{ playlist_url } " --key { audience_token } ,{ max_quality } -o "{ self .filename } .ts" --proxy "http://{ self .proxy_host } :{ self .proxy_port } "'
272+ cmd = f'minyami -d "{ playlist_url } " --key { audience_token } ,{ max_quality } -o "{ self .filename } .ts"'
273+ if self .proxy :
274+ cmd += f' --proxy "{ self .proxy } "'
259275 if verbose :
260276 cmd += ' --verbose'
261277 print ('CMD is:' )
@@ -293,9 +309,10 @@ def _split_lines(self, text, width):
293309 parser .add_argument ('--thumb' , action = 'store_true' , help = 'Download thumbnail only. Only works for video type (not live type).' )
294310 parser .add_argument ('--cookies' , '-c' , default = 'chrome' , help = 'R|Cookie source. [Default: chrome]\n Provide either:\n - A browser name to fetch from;\n - The value of "user_session";\n - A Netscape-style cookie file.' )
295311 parser .add_argument ('--comments' , '-d' , default = 'yes' , choices = ['yes' , 'no' , 'only' ], help = 'Control if comments (danmaku) are downloaded. [Default: yes]' )
312+ parser .add_argument ('--proxy' , help = 'Specify a proxy, "none", or "auto" (automatically detects system proxy settings). [Default: auto]' )
296313 args = parser .parse_args ()
297314
298- nico_downloader = NicoDownloader (args .url , args .cookies )
315+ nico_downloader = NicoDownloader (args .url , args .cookies , args . proxy )
299316
300317 if args .thumb :
301318 nico_downloader .download_thumbnail ()
0 commit comments