Skip to content

Commit b59b9d8

Browse files
committed
[sites:youtube] Allow pagination for playlists
1 parent e6adb4b commit b59b9d8

File tree

1 file changed

+39
-8
lines changed

1 file changed

+39
-8
lines changed

chat_downloader/sites/youtube.py

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1285,17 +1285,48 @@ def get_user_videos(self, channel_id=None, user_id=None, custom_username=None, v
12851285

12861286
def get_playlist_items(self, playlist_url, params=None):
12871287

1288-
yt_initial_data, ytcfg, player_response_info = self._get_initial_info(
1288+
yt_initial_data, ytcfg, _ = self._get_initial_info(
12891289
playlist_url, params)
12901290

1291-
items = self._get_rendered_content(
1292-
yt_initial_data)['playlistVideoListRenderer']['contents']
1291+
page_contents = self._get_rendered_content(yt_initial_data)
12931292

1294-
for item in items:
1295-
playlist_video = item.get('playlistVideoRenderer')
1293+
# TODO remove code duplication
1294+
api_key = ytcfg.get('INNERTUBE_API_KEY')
1295+
continuation_url = self._YOUTUBE_BROWSE_API_TEMPLATE.format(api_key)
12961296

1297-
if playlist_video:
1298-
yield self._parse_video(playlist_video)
1297+
continuation_params = {
1298+
'context': ytcfg.get('INNERTUBE_CONTEXT') or {}
1299+
}
1300+
continuation = None
1301+
first_time = True
1302+
while True:
1303+
if first_time:
1304+
items = multi_get(
1305+
page_contents, 'playlistVideoListRenderer', 'contents')
1306+
first_time = False
1307+
else:
1308+
continuation_params['continuation'] = continuation
1309+
yt_info = self._get_continuation_info(
1310+
continuation_url, params, json=continuation_params)
1311+
items = multi_get(yt_info, 'onResponseReceivedActions',
1312+
0, 'appendContinuationItemsAction', 'continuationItems')
1313+
1314+
if not items:
1315+
break
1316+
1317+
continuation = None
1318+
for item in items:
1319+
vid = item.get('playlistVideoRenderer')
1320+
continuation_item = item.get('continuationItemRenderer')
1321+
1322+
if vid:
1323+
yield self._parse_video(vid)
1324+
elif continuation_item:
1325+
continuation = multi_get(
1326+
continuation_item, 'continuationEndpoint', 'continuationCommand', 'token')
1327+
1328+
if not continuation:
1329+
break
12991330

13001331
_CONSENT_ID_REGEX = r'PENDING\+(\d+)'
13011332
# https://github.com/ytdl-org/youtube-dl/blob/a8035827177d6b59aca03bd717acb6a9bdd75ada/youtube_dl/extractor/youtube.py#L251
@@ -1634,7 +1665,7 @@ def _get_chat_messages(self, initial_info, ytcfg, params):
16341665

16351666
# Top chat replay - Some messages, such as potential spam, may not be visible
16361667
# Live chat replay - All messages are visible
1637-
chat_type = params.get('chat_type').title() # Live or Top
1668+
chat_type = params.get('chat_type', 'live').title() # Live or Top
16381669
continuation_index = 0 if chat_type == 'Top' else 1
16391670
continuation_info = list(initial_continuation_info.items())[
16401671
continuation_index]

0 commit comments

Comments
 (0)