Add functional but preliminary channel tab support

Add channel tabs to the channel template and script
Update continuation token to request different tabs

Add support for 'reelItemRenderer' format required to extract shorts
This commit is contained in:
Jesus E
2023-06-17 16:05:40 -04:00
parent 74907a8183
commit f322035d4a
4 changed files with 75 additions and 21 deletions

View File

@@ -32,16 +32,23 @@ real_cookie = (('Cookie', 'VISITOR_INFO1_LIVE=8XihrAcN1l4'),)
generic_cookie = (('Cookie', 'VISITOR_INFO1_LIVE=ST1Ti53r4fU'),)
# added an extra nesting under the 2nd base64 compared to v4
# added tab support
def channel_ctoken_v5(channel_id, page, sort, tab, view=1):
new_sort = (2 if int(sort) == 1 else 1)
offset = str(30*(int(page) - 1))
if tab == 'videos':
tab = 15
elif tab == 'shorts':
tab = 10
elif tab == 'streams':
tab = 14
pointless_nest = proto.string(80226972,
proto.string(2, channel_id)
+ proto.string(3,
proto.percent_b64encode(
proto.string(110,
proto.string(3,
proto.string(15,
proto.string(tab,
proto.string(1,
proto.string(1,
proto.unpadded_b64encode(
@@ -167,7 +174,7 @@ def channel_ctoken_v2(channel_id, page, sort, tab, view=1):
tab = proto.string(2, tab)
sort = proto.uint(3, int(sort))
# page = proto.string(15, str(page) )
#page = proto.string(15, str(page))
shelf_view = proto.uint(4, 0)
view = proto.uint(6, int(view))
@@ -202,7 +209,7 @@ def get_channel_tab(channel_id, page="1", sort=3, tab='videos', view=1,
message = 'Got channel tab' if print_status else None
if not ctoken:
if tab == 'videos':
if tab in ('videos', 'shorts', 'streams'):
ctoken = channel_ctoken_v5(channel_id, page, sort, tab, view)
else:
ctoken = channel_ctoken_v3(channel_id, page, sort, tab, view)
@@ -349,11 +356,11 @@ def post_process_channel_info(info):
info['links'][i] = (text, util.prefix_url(url))
def get_channel_first_page(base_url=None, channel_id=None):
def get_channel_first_page(base_url=None, channel_id=None, tab='videos'):
if channel_id:
base_url = 'https://www.youtube.com/channel/' + channel_id
return util.fetch_url(base_url + '/videos?pbj=1&view=0', headers_desktop,
debug_name='gen_channel_videos')
return util.fetch_url(base_url + '/' + tab + '?pbj=1&view=0',
headers_desktop, debug_name='gen_channel_' + tab)
playlist_sort_codes = {'2': "da", '3': "dd", '4': "lad"}
@@ -374,24 +381,25 @@ def get_channel_page_general_url(base_url, tab, request, channel_id=None):
default_params = (page_number == 1 and sort == '3' and view == '1')
continuation = bool(ctoken) # whether or not we're using a continuation
if tab == 'videos' and channel_id and not default_params:
if (tab in ('videos', 'shorts', 'streams') and channel_id and
not default_params):
tasks = (
gevent.spawn(get_number_of_videos_channel, channel_id),
gevent.spawn(get_channel_tab, channel_id, page_number, sort,
'videos', view, ctoken)
tab, view, ctoken)
)
gevent.joinall(tasks)
util.check_gevent_exceptions(*tasks)
number_of_videos, polymer_json = tasks[0].value, tasks[1].value
continuation = True
elif tab == 'videos':
elif tab in ('videos', 'shorts', 'streams'):
if channel_id:
num_videos_call = (get_number_of_videos_channel, channel_id)
else:
num_videos_call = (get_number_of_videos_general, base_url)
tasks = (
gevent.spawn(*num_videos_call),
gevent.spawn(get_channel_first_page, base_url=base_url),
gevent.spawn(get_channel_first_page, base_url=base_url, tab=tab),
)
gevent.joinall(tasks)
util.check_gevent_exceptions(*tasks)
@@ -440,13 +448,13 @@ def get_channel_page_general_url(base_url, tab, request, channel_id=None):
item.update(additional_info)
if info['error'] is not None:
return flask.render_template('error.html', error_message=info['error'])
return flask.render_template('error.html', error_message = info['error'])
if tab == 'videos':
if tab in ('videos', 'shorts', 'streams'):
info['number_of_videos'] = number_of_videos
info['number_of_pages'] = math.ceil(number_of_videos/30)
info['header_playlist_names'] = local_playlist.get_playlist_names()
if tab in ('videos', 'playlists'):
if tab in ('videos', 'shorts', 'streams', 'playlists'):
info['current_sort'] = sort
elif tab == 'search':
info['search_box_value'] = query
@@ -457,9 +465,8 @@ def get_channel_page_general_url(base_url, tab, request, channel_id=None):
post_process_channel_info(info)
return flask.render_template(
'channel.html',
parameters_dictionary=request.args,
return flask.render_template('channel.html',
parameters_dictionary = request.args,
**info
)