@@ -306,7 +306,7 @@ def _extract_ytcfg(self, video_id, webpage):
306
306
return self ._parse_json (
307
307
self ._search_regex (
308
308
r'ytcfg\.set\s*\(\s*({.+?})\s*\)\s*;' , webpage , 'ytcfg' ,
309
- default = '{}' ), video_id , fatal = False )
309
+ default = '{}' ), video_id , fatal = False ) or {}
310
310
311
311
def _extract_video (self , renderer ):
312
312
video_id = renderer ['videoId' ]
@@ -2475,7 +2475,7 @@ def _extract_continuation(cls, renderer):
2475
2475
ctp = continuation_ep .get ('clickTrackingParams' )
2476
2476
return YoutubeTabIE ._build_continuation_query (continuation , ctp )
2477
2477
2478
- def _entries (self , tab , identity_token ):
2478
+ def _entries (self , tab , item_id , webpage ):
2479
2479
tab_content = try_get (tab , lambda x : x ['content' ], dict )
2480
2480
if not tab_content :
2481
2481
return
@@ -2535,26 +2535,37 @@ def _entries(self, tab, identity_token):
2535
2535
yield entry
2536
2536
continuation = self ._extract_continuation (rich_grid_renderer )
2537
2537
2538
+ ytcfg = self ._extract_ytcfg (item_id , webpage )
2539
+ client_version = try_get (
2540
+ ytcfg , lambda x : x ['INNERTUBE_CLIENT_VERSION' ], compat_str ) or '2.20210407.08.00'
2541
+
2538
2542
headers = {
2539
2543
'x-youtube-client-name' : '1' ,
2540
- 'x-youtube-client-version' : '2.20201112.04.01' ,
2544
+ 'x-youtube-client-version' : client_version ,
2541
2545
'content-type' : 'application/json' ,
2542
2546
}
2547
+
2548
+ context = try_get (ytcfg , lambda x : x ['INNERTUBE_CONTEXT' ], dict ) or {
2549
+ 'client' : {
2550
+ 'clientName' : 'WEB' ,
2551
+ 'clientVersion' : client_version ,
2552
+ }
2553
+ }
2554
+ visitor_data = try_get (context , lambda x : x ['client' ]['visitorData' ], compat_str )
2555
+
2556
+ identity_token = self ._extract_identity_token (ytcfg , webpage )
2543
2557
if identity_token :
2544
2558
headers ['x-youtube-identity-token' ] = identity_token
2545
2559
2546
2560
data = {
2547
- 'context' : {
2548
- 'client' : {
2549
- 'clientName' : 'WEB' ,
2550
- 'clientVersion' : '2.20201021.03.00' ,
2551
- }
2552
- },
2561
+ 'context' : context ,
2553
2562
}
2554
2563
2555
2564
for page_num in itertools .count (1 ):
2556
2565
if not continuation :
2557
2566
break
2567
+ if visitor_data :
2568
+ headers ['x-goog-visitor-id' ] = visitor_data
2558
2569
data ['continuation' ] = continuation ['continuation' ]
2559
2570
data ['clickTracking' ] = {
2560
2571
'clickTrackingParams' : continuation ['itct' ]
@@ -2579,6 +2590,9 @@ def _entries(self, tab, identity_token):
2579
2590
if not response :
2580
2591
break
2581
2592
2593
+ visitor_data = try_get (
2594
+ response , lambda x : x ['responseContext' ]['visitorData' ], compat_str ) or visitor_data
2595
+
2582
2596
continuation_contents = try_get (
2583
2597
response , lambda x : x ['continuationContents' ], dict )
2584
2598
if continuation_contents :
@@ -2687,7 +2701,7 @@ def _extract_alert(data):
2687
2701
alerts .append (text )
2688
2702
return '\n ' .join (alerts )
2689
2703
2690
- def _extract_from_tabs (self , item_id , webpage , data , tabs , identity_token ):
2704
+ def _extract_from_tabs (self , item_id , webpage , data , tabs ):
2691
2705
selected_tab = self ._extract_selected_tab (tabs )
2692
2706
renderer = try_get (
2693
2707
data , lambda x : x ['metadata' ]['channelMetadataRenderer' ], dict )
@@ -2712,7 +2726,7 @@ def _extract_from_tabs(self, item_id, webpage, data, tabs, identity_token):
2712
2726
if renderer :
2713
2727
title = try_get (renderer , lambda x : x ['hashtag' ]['simpleText' ])
2714
2728
playlist = self .playlist_result (
2715
- self ._entries (selected_tab , identity_token ),
2729
+ self ._entries (selected_tab , item_id , webpage ),
2716
2730
playlist_id = playlist_id , playlist_title = title ,
2717
2731
playlist_description = description )
2718
2732
playlist .update (self ._extract_uploader (data ))
@@ -2736,8 +2750,7 @@ def _extract_from_playlist(self, item_id, url, data, playlist):
2736
2750
self ._playlist_entries (playlist ), playlist_id = playlist_id ,
2737
2751
playlist_title = title )
2738
2752
2739
- def _extract_identity_token (self , webpage , item_id ):
2740
- ytcfg = self ._extract_ytcfg (item_id , webpage )
2753
+ def _extract_identity_token (self , ytcfg , webpage ):
2741
2754
if ytcfg :
2742
2755
token = try_get (ytcfg , lambda x : x ['ID_TOKEN' ], compat_str )
2743
2756
if token :
@@ -2760,12 +2773,11 @@ def _real_extract(self, url):
2760
2773
return self .url_result (video_id , ie = YoutubeIE .ie_key (), video_id = video_id )
2761
2774
self .to_screen ('Downloading playlist %s - add --no-playlist to just download video %s' % (playlist_id , video_id ))
2762
2775
webpage = self ._download_webpage (url , item_id )
2763
- identity_token = self ._extract_identity_token (webpage , item_id )
2764
2776
data = self ._extract_yt_initial_data (item_id , webpage )
2765
2777
tabs = try_get (
2766
2778
data , lambda x : x ['contents' ]['twoColumnBrowseResultsRenderer' ]['tabs' ], list )
2767
2779
if tabs :
2768
- return self ._extract_from_tabs (item_id , webpage , data , tabs , identity_token )
2780
+ return self ._extract_from_tabs (item_id , webpage , data , tabs )
2769
2781
playlist = try_get (
2770
2782
data , lambda x : x ['contents' ]['twoColumnWatchNextResults' ]['playlist' ]['playlist' ], dict )
2771
2783
if playlist :
0 commit comments