Merge pull request #1147 from petlyh/youtube-albums

[YouTube] Add Albums channel tab
This commit is contained in:
Stypox 2023-12-30 21:58:19 +01:00 committed by GitHub
commit 3402cdb666
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 1703 additions and 1 deletions

View File

@ -445,6 +445,9 @@ public class YoutubeChannelExtractor extends ChannelExtractor {
case "streams": case "streams":
addNonVideosTab.accept(ChannelTabs.LIVESTREAMS); addNonVideosTab.accept(ChannelTabs.LIVESTREAMS);
break; break;
case "releases":
addNonVideosTab.accept(ChannelTabs.ALBUMS);
break;
case "playlists": case "playlists":
addNonVideosTab.accept(ChannelTabs.PLAYLISTS); addNonVideosTab.accept(ChannelTabs.PLAYLISTS);
break; break;

View File

@ -78,6 +78,8 @@ public class YoutubeChannelTabExtractor extends ChannelTabExtractor {
return "EgZzaG9ydHPyBgUKA5oBAA%3D%3D"; return "EgZzaG9ydHPyBgUKA5oBAA%3D%3D";
case ChannelTabs.LIVESTREAMS: case ChannelTabs.LIVESTREAMS:
return "EgdzdHJlYW1z8gYECgJ6AA%3D%3D"; return "EgdzdHJlYW1z8gYECgJ6AA%3D%3D";
case ChannelTabs.ALBUMS:
return "EghyZWxlYXNlc_IGBQoDsgEA";
case ChannelTabs.PLAYLISTS: case ChannelTabs.PLAYLISTS:
return "EglwbGF5bGlzdHPyBgQKAkIA"; return "EglwbGF5bGlzdHPyBgQKAkIA";
default: default:
@ -304,7 +306,7 @@ public class YoutubeChannelTabExtractor extends ChannelTabExtractor {
richItem.getObject("reelItemRenderer")); richItem.getObject("reelItemRenderer"));
} else if (richItem.has("playlistRenderer")) { } else if (richItem.has("playlistRenderer")) {
getCommitPlaylistConsumer(collector, channelIds, getCommitPlaylistConsumer(collector, channelIds,
item.getObject("playlistRenderer")); richItem.getObject("playlistRenderer"));
} }
} else if (item.has("gridVideoRenderer")) { } else if (item.has("gridVideoRenderer")) {
getCommitVideoConsumer(collector, timeAgoParser, channelIds, getCommitVideoConsumer(collector, timeAgoParser, channelIds,

View File

@ -29,6 +29,8 @@ public final class YoutubeChannelTabLinkHandlerFactory extends ListLinkHandlerFa
return "/shorts"; return "/shorts";
case ChannelTabs.LIVESTREAMS: case ChannelTabs.LIVESTREAMS:
return "/streams"; return "/streams";
case ChannelTabs.ALBUMS:
return "/releases";
case ChannelTabs.PLAYLISTS: case ChannelTabs.PLAYLISTS:
return "/playlists"; return "/playlists";
default: default:
@ -65,6 +67,7 @@ public final class YoutubeChannelTabLinkHandlerFactory extends ListLinkHandlerFa
ChannelTabs.VIDEOS, ChannelTabs.VIDEOS,
ChannelTabs.SHORTS, ChannelTabs.SHORTS,
ChannelTabs.LIVESTREAMS, ChannelTabs.LIVESTREAMS,
ChannelTabs.ALBUMS,
ChannelTabs.PLAYLISTS ChannelTabs.PLAYLISTS
}; };
} }

View File

@ -112,6 +112,28 @@ class YoutubeChannelTabExtractorTest {
@Override public boolean expectedHasMoreItems() { return true; } @Override public boolean expectedHasMoreItems() { return true; }
} }
static class Albums extends DefaultListExtractorTest<ChannelTabExtractor> {
private static YoutubeChannelTabExtractor extractor;
@BeforeAll
static void setUp() throws IOException, ExtractionException {
YoutubeTestsUtils.ensureStateless();
NewPipe.init(DownloaderFactory.getDownloader(RESOURCE_PATH + "albums"));
extractor = (YoutubeChannelTabExtractor) YouTube.getChannelTabExtractorFromId(
"@Radiohead", ChannelTabs.ALBUMS);
extractor.fetchPage();
}
@Override public ChannelTabExtractor extractor() throws Exception { return extractor; }
@Override public StreamingService expectedService() throws Exception { return YouTube; }
@Override public String expectedName() throws Exception { return ChannelTabs.ALBUMS; }
@Override public String expectedId() throws Exception { return "UCq19-LqvG35A-30oyAiPiqA"; }
@Override public String expectedUrlContains() throws Exception { return "https://www.youtube.com/channel/UCq19-LqvG35A-30oyAiPiqA/releases"; }
@Override public String expectedOriginalUrlContains() throws Exception { return "https://www.youtube.com/@Radiohead/releases"; }
@Override public InfoItem.InfoType expectedInfoItemType() { return InfoItem.InfoType.PLAYLIST; }
@Override public boolean expectedHasMoreItems() { return true; }
}
// TESTS FOR TABS OF AGE RESTRICTED CHANNELS // TESTS FOR TABS OF AGE RESTRICTED CHANNELS
// Fetching the tabs individually would use the standard tabs without fallback to // Fetching the tabs individually would use the standard tabs without fallback to

View File

@ -0,0 +1,85 @@
{
"request": {
"httpMethod": "GET",
"url": "https://www.youtube.com/sw.js",
"headers": {
"Referer": [
"https://www.youtube.com"
],
"Origin": [
"https://www.youtube.com"
],
"Accept-Language": [
"en-GB, en;q\u003d0.9"
]
},
"localization": {
"languageCode": "en",
"countryCode": "GB"
}
},
"response": {
"responseCode": 200,
"responseMessage": "",
"responseHeaders": {
"access-control-allow-credentials": [
"true"
],
"access-control-allow-origin": [
"https://www.youtube.com"
],
"alt-svc": [
"h3\u003d\":443\"; ma\u003d2592000,h3-29\u003d\":443\"; ma\u003d2592000"
],
"cache-control": [
"private, max-age\u003d0"
],
"content-type": [
"text/javascript; charset\u003dutf-8"
],
"cross-origin-opener-policy": [
"same-origin; report-to\u003d\"youtube_main\""
],
"date": [
"Sat, 30 Dec 2023 13:43:25 GMT"
],
"expires": [
"Sat, 30 Dec 2023 13:43:25 GMT"
],
"origin-trial": [
"AvC9UlR6RDk2crliDsFl66RWLnTbHrDbp+DiY6AYz/PNQ4G4tdUTjrHYr2sghbkhGQAVxb7jaPTHpEVBz0uzQwkAAAB4eyJvcmlnaW4iOiJodHRwczovL3lvdXR1YmUuY29tOjQ0MyIsImZlYXR1cmUiOiJXZWJWaWV3WFJlcXVlc3RlZFdpdGhEZXByZWNhdGlvbiIsImV4cGlyeSI6MTcxOTUzMjc5OSwiaXNTdWJkb21haW4iOnRydWV9"
],
"p3p": [
"CP\u003d\"This is not a P3P policy! See http://support.google.com/accounts/answer/151657?hl\u003den-GB for more info.\""
],
"permissions-policy": [
"ch-ua-arch\u003d*, ch-ua-bitness\u003d*, ch-ua-full-version\u003d*, ch-ua-full-version-list\u003d*, ch-ua-model\u003d*, ch-ua-wow64\u003d*, ch-ua-form-factor\u003d*, ch-ua-platform\u003d*, ch-ua-platform-version\u003d*"
],
"report-to": [
"{\"group\":\"youtube_main\",\"max_age\":2592000,\"endpoints\":[{\"url\":\"https://csp.withgoogle.com/csp/report-to/youtube_main\"}]}"
],
"server": [
"ESF"
],
"set-cookie": [
"YSC\u003dpk4qlD0k7qs; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dSun, 04-Apr-2021 13:43:25 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
"CONSENT\u003dPENDING+551; expires\u003dMon, 29-Dec-2025 13:43:25 GMT; path\u003d/; domain\u003d.youtube.com; Secure"
],
"strict-transport-security": [
"max-age\u003d31536000"
],
"x-content-type-options": [
"nosniff"
],
"x-frame-options": [
"SAMEORIGIN"
],
"x-xss-protection": [
"0"
]
},
"responseBody": "\n self.addEventListener(\u0027install\u0027, event \u003d\u003e {\n event.waitUntil(self.skipWaiting());\n });\n self.addEventListener(\u0027activate\u0027, event \u003d\u003e {\n event.waitUntil(\n self.clients.claim().then(() \u003d\u003e self.registration.unregister()));\n });\n ",
"latestUrl": "https://www.youtube.com/sw.js"
}
}

View File

@ -0,0 +1,396 @@
{
"request": {
"httpMethod": "POST",
"url": "https://www.youtube.com/youtubei/v1/navigation/resolve_url?key\u003dAIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8\u0026prettyPrint\u003dfalse",
"headers": {
"Referer": [
"https://www.youtube.com"
],
"Origin": [
"https://www.youtube.com"
],
"Cookie": [
"SOCS\u003dCAE\u003d"
],
"X-YouTube-Client-Version": [
"2.20231219.04.00"
],
"X-YouTube-Client-Name": [
"1"
],
"Content-Type": [
"application/json"
],
"Accept-Language": [
"en-GB, en;q\u003d0.9"
]
},
"dataToSend": [
123,
34,
99,
111,
110,
116,
101,
120,
116,
34,
58,
123,
34,
114,
101,
113,
117,
101,
115,
116,
34,
58,
123,
34,
105,
110,
116,
101,
114,
110,
97,
108,
69,
120,
112,
101,
114,
105,
109,
101,
110,
116,
70,
108,
97,
103,
115,
34,
58,
91,
93,
44,
34,
117,
115,
101,
83,
115,
108,
34,
58,
116,
114,
117,
101,
125,
44,
34,
99,
108,
105,
101,
110,
116,
34,
58,
123,
34,
117,
116,
99,
79,
102,
102,
115,
101,
116,
77,
105,
110,
117,
116,
101,
115,
34,
58,
48,
44,
34,
104,
108,
34,
58,
34,
101,
110,
45,
71,
66,
34,
44,
34,
103,
108,
34,
58,
34,
71,
66,
34,
44,
34,
99,
108,
105,
101,
110,
116,
78,
97,
109,
101,
34,
58,
34,
87,
69,
66,
34,
44,
34,
111,
114,
105,
103,
105,
110,
97,
108,
85,
114,
108,
34,
58,
34,
104,
116,
116,
112,
115,
58,
47,
47,
119,
119,
119,
46,
121,
111,
117,
116,
117,
98,
101,
46,
99,
111,
109,
34,
44,
34,
99,
108,
105,
101,
110,
116,
86,
101,
114,
115,
105,
111,
110,
34,
58,
34,
50,
46,
50,
48,
50,
51,
49,
50,
49,
57,
46,
48,
52,
46,
48,
48,
34,
44,
34,
112,
108,
97,
116,
102,
111,
114,
109,
34,
58,
34,
68,
69,
83,
75,
84,
79,
80,
34,
125,
44,
34,
117,
115,
101,
114,
34,
58,
123,
34,
108,
111,
99,
107,
101,
100,
83,
97,
102,
101,
116,
121,
77,
111,
100,
101,
34,
58,
102,
97,
108,
115,
101,
125,
125,
44,
34,
117,
114,
108,
34,
58,
34,
104,
116,
116,
112,
115,
58,
47,
47,
119,
119,
119,
46,
121,
111,
117,
116,
117,
98,
101,
46,
99,
111,
109,
47,
64,
82,
97,
100,
105,
111,
104,
101,
97,
100,
34,
125
],
"localization": {
"languageCode": "en",
"countryCode": "GB"
}
},
"response": {
"responseCode": 200,
"responseMessage": "",
"responseHeaders": {
"alt-svc": [
"h3\u003d\":443\"; ma\u003d2592000,h3-29\u003d\":443\"; ma\u003d2592000"
],
"cache-control": [
"private"
],
"content-type": [
"application/json; charset\u003dUTF-8"
],
"date": [
"Sat, 30 Dec 2023 13:43:25 GMT"
],
"expires": [
"Sat, 30 Dec 2023 13:43:25 GMT"
],
"p3p": [
"CP\u003d\"This is not a P3P policy! See g.co/p3phelp for more info.\""
],
"server": [
"scaffolding on HTTPServer2"
],
"set-cookie": [
"CONSENT\u003dPENDING+476; expires\u003dMon, 29-Dec-2025 13:43:25 GMT; path\u003d/; domain\u003d.youtube.com; Secure"
],
"vary": [
"Origin",
"X-Origin",
"Referer"
],
"x-content-type-options": [
"nosniff"
],
"x-frame-options": [
"SAMEORIGIN"
],
"x-xss-protection": [
"0"
]
},
"responseBody": "{\"responseContext\":{\"visitorData\":\"CgszSmVQc192a2J6TSj9vMCsBjIKCgJOTxIEEgAgMQ%3D%3D\",\"serviceTrackingParams\":[{\"service\":\"CSI\",\"params\":[{\"key\":\"c\",\"value\":\"WEB\"},{\"key\":\"cver\",\"value\":\"2.20231219.04.00\"},{\"key\":\"yt_li\",\"value\":\"0\"},{\"key\":\"ResolveUrl_rid\",\"value\":\"0x26bcd15632ab68f4\"}]},{\"service\":\"GFEEDBACK\",\"params\":[{\"key\":\"logged_in\",\"value\":\"0\"},{\"key\":\"e\",\"value\":\"23804281,23880831,23880837,23946420,23966208,23983296,23986019,23998056,24004644,24007246,24034168,24036948,24077241,24080738,24120820,24135310,24140247,24166867,24181174,24187377,24241378,24255543,24255545,24288664,24290971,24367579,24377598,24377909,24382552,24385728,24387949,24390675,24428788,24428941,24428945,24439361,24451319,24453989,24458839,24459435,24468724,24485421,24506515,24506784,24515423,24518452,24524098,24526646,24526770,24526783,24526790,24526797,24526806,24526811,24526827,24528552,24528557,24528575,24528584,24528644,24528649,24528657,24528666,24531244,24537200,24539025,24542367,24542452,24543669,24546059,24546075,24548627,24548629,24549786,24550458,24559328,24560416,24561210,24561384,24566687,24589493,24694842,24697069,24698453,24699899,51003636,51004018,51006181,51009781,51009900,51010235,51012165,51012291,51012659,51014091,51016856,51017346,51019626,51020570,51021953,51025415,51026715,51027870,51028271,51029412,51030101,51032409,51033399,51033577,51035289,51036511,51037044,51037342,51037353,51037540,51037819,51037893,51038399,51038805,51039200,51039493,51041280,51041331,51041497,51042259,51043775,51043942,51045885,51045889,51045969,51047539,51048240,51048279,51049006,51050361,51053689,51055135,51056262,51056268,51057451,51057501,51057534,51057746,51057809,51057822,51057846,51057857,51059269,51059543,51059573,51059972,51060895,51061001,51061018,51062131,51063131,51063138,51063151,51063160,51063551,51063643,51064593,51065651,51065706,51069269,51070203,51070732,51072748,51074183,51074391,51074609,51074662,51074717,51074739,51075839,51076209,51077150,51078193,51078481,51078868,51079299,51079353,51080182,51080510,51080715,51082236,51082367,51083014,51083232,51083651,51083748,51084269,51084277,51084288,51084695,51086857,51088826,51090887\"}]},{\"service\":\"GUIDED_HELP\",\"params\":[{\"key\":\"logged_in\",\"value\":\"0\"}]},{\"service\":\"ECATCHER\",\"params\":[{\"key\":\"client.version\",\"value\":\"2.20231219\"},{\"key\":\"client.name\",\"value\":\"WEB\"},{\"key\":\"client.fexp\",\"value\":\"51076209,24550458,24007246,51084695,51082236,51041331,24120820,51033399,51012659,51090887,24548629,51080510,51042259,24135310,51041497,24255543,51028271,51037893,51010235,24528644,24166867,51045969,24528666,24367579,51043775,23880837,24526811,24524098,51078481,24382552,51084277,51041280,51014091,24459435,51020570,24526797,24526646,51057534,51057857,51009781,24526790,24566687,24526783,51083651,51045889,24468724,51065651,51063551,24528552,24377598,51056268,23998056,51061001,24518452,24439361,51036511,51056262,51084269,24559328,51038805,24458839,24542367,51033577,51078193,24699899,51057822,23986019,24548627,51048240,51070203,51027870,24526827,51077150,51072748,51039200,24506515,51074662,24546075,51063151,24485421,24549786,51059972,51037044,24526806,51037540,51057809,51079299,51078868,24526770,24698453,51037353,24528575,51088826,24542452,24241378,51069269,51083232,51035289,51060895,51074609,51065706,24531244,51053689,51074717,24377909,24451319,24561210,51057846,24428788,24515423,24181174,51055135,24539025,24080738,51063160,51030101,51039493,51080715,51061018,24288664,51062131,51050361,51057746,24034168,51012165,51009900,51086857,51016856,51059269,51084288,51063131,24561384,51021953,51037819,24546059,51059543,51074739,24428945,24528584,51083748,24528649,51057451,51080182,51057501,23966208,51075839,24694842,51004018,51063138,24543669,51006181,24428941,51074183,24506784,51049006,51045885,51047539,51017346,51082367,24537200,51083014,24589493,51012291,51048279,23804281,51064593,23946420,24390675,24255545,23880831,51003636,24528657,51025415,51074391,24453989,23983296,24387949,51043942,51070732,24187377,51059573,51029412,24004644,51032409,24290971,24560416,51079353,51063643,24077241,51038399,24697069,24140247,24528557,51019626,51037342,24385728,51026715,24036948\"}]}],\"mainAppWebResponseContext\":{\"loggedOut\":true},\"webResponseContextExtensionData\":{\"hasDecorated\":true}},\"endpoint\":{\"clickTrackingParams\":\"IhMIvI34qaW3gwMVQaD0Bx2BFwuHMghleHRlcm5hbA\u003d\u003d\",\"commandMetadata\":{\"webCommandMetadata\":{\"url\":\"/youtubei/v1/navigation/resolve_url\",\"webPageType\":\"WEB_PAGE_TYPE_CHANNEL\",\"rootVe\":3611,\"apiUrl\":\"/youtubei/v1/browse\"},\"resolveUrlCommandMetadata\":{\"isVanityUrl\":true}},\"browseEndpoint\":{\"browseId\":\"UCq19-LqvG35A-30oyAiPiqA\",\"params\":\"EgC4AQCSAwDyBgQKAjIA\"}}}",
"latestUrl": "https://www.youtube.com/youtubei/v1/navigation/resolve_url?key\u003dAIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8\u0026prettyPrint\u003dfalse"
}
}