From 811d4bf6321c3e4c8dad82ed3b8d60ae1ce8eaaf Mon Sep 17 00:00:00 2001 From: girst Date: Sun, 6 Feb 2022 18:45:36 +0100 Subject: [PATCH] make music mix playlists work needs some cleanup --- app/browse/__init__.py | 2 +- app/browse/protobuf.py | 29 ++++++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/app/browse/__init__.py b/app/browse/__init__.py index 81df013..885adb9 100644 --- a/app/browse/__init__.py +++ b/app/browse/__init__.py @@ -79,7 +79,7 @@ def channel(channel_id, subpage="videos"): return error, 400 # todo: ugly title, descr, thumb, rows, continuation = prepare_channel(result, channel_id) - if not rows: # overran end of list, or is special channel (e.g. music topic) + if not rows: # overran end of list, or is special channel (e.g. music topic (sidebar 'best of youtube', UC-9-kyTW8ZkZNDHQJ6FgpwQ) flash("ajax returned nothing; displaying fallback results (15 newest)", "error") return fallback_route(channel_id, subpage) diff --git a/app/browse/protobuf.py b/app/browse/protobuf.py index 02d66fc..703aaf1 100644 --- a/app/browse/protobuf.py +++ b/app/browse/protobuf.py @@ -134,18 +134,45 @@ def make_channel_params(subject, typ="videos", page=1, sort=None, query=None, v3 @message @dataclass class PlaylistData: - offset: int64 = field(1) + offset: Optional[int64] = field(1) # normal playlists + after: Optional[str] = field(2) # mix playlist (RDCL*, RDCM*): video id of last loaded item (how to get first page!?) @message @dataclass class PlaylistSubparams: data: str = field(15) def make_playlist_params(playlist_id, offset): + # TODO: special type of playlists: (see https://github.com/nlitsme/youtube_tool) + # - PL*: normal playlists + # - special channel playlists (suffix=channel_id without UC): + # - UU*: newest uploads (works) + # - PU*: popular uploads (works) + # Note: youtubekids (e.g. PLMYEtVRpaqY00V9W81Cwmzp6N6vZqfUKD4) fallback-only (youtube webui 404's) + # - FL*: favourited uploads (works; 404's if private) + # - LL*: liked uploads (untested) + # - RDCMUC*: mix for channel (fallback only; e.g. RDCMUCYO_jab_esuFRV4b17AJtAw, undisplayable on youtube (only works on watch)) + # - CL, EL, MQ, TT: unknown + # - OLAK5uy_ music album playlist (works, e.g. OLAK5uy_m4xAFdmMC5rX3Ji3g93pQe3hqLZw_9LhM) + # - RD*: mix playlist (works with after=; e.g. RDCLAK5uy_kLWIr9gv1XLlPbaDS965-Db4TrBoUTxQ8, RDCLAK5uy_mx8mvGaCkyI12AedAu8yIbBpEYmg6Ayow, RDCLAK5uy_n340faD9pPGRVEVwozYTzIpfXuqmQwcgA, RDCLAK5uy_kQmVjdr90p2onIIAnijgU8u9iUUAOXM2I) + # https://www.youtube.com/watch?v=FTQbiNvZqaY&list=RDCLAK5uy_khNGopKCT_t38MZ1W7z4kERrqprkXovxo&start_radio=1 + # - EC, UL, TL: unknown + # - own user playlists (obviously not working): + # - RDMM: my mix + # - WL: watch later + # - LL: own liked videos + # - LM: own liked youtube-music videos + after = None + if playlist_id.startswith("RD"): + # NOTE: this only fixes RDCLAK5uy_, not RDCMUC + after = '___________' # any video id that doesn't exist within the playlist requests the beginning + offset = None + return b64e(Continuation( params=Params( subject="VL" + playlist_id, params=b64e(PlaylistSubparams( data="PT:" + b64e(PlaylistData( offset=offset, + after=after, ).dumps(), padding=False) ).dumps()), ), -- 2.39.3