youtubei 1.4.5 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -35,6 +35,22 @@ class MusicClient {
35
35
  }
36
36
  });
37
37
  }
38
+ /**
39
+ * Searches for all video, song, album, playlist, or artist
40
+ *
41
+ * @param query The search query
42
+ */
43
+ searchAll(query) {
44
+ return __awaiter(this, void 0, void 0, function* () {
45
+ const response = yield this.http.post(`${constants_1.I_END_POINT}/search`, {
46
+ data: { query },
47
+ });
48
+ return {
49
+ top: MusicSearchResult_1.MusicAllSearchResultParser.parseTopResult(response.data, this),
50
+ shelves: MusicSearchResult_1.MusicAllSearchResultParser.parseSearchResult(response.data, this),
51
+ };
52
+ });
53
+ }
38
54
  /**
39
55
  * Get lyrics of a song
40
56
  *
@@ -10,6 +10,77 @@ const MusicPlaylistCompact_1 = require("../MusicPlaylistCompact");
10
10
  const MusicSongCompact_1 = require("../MusicSongCompact");
11
11
  const MusicVideoCompact_1 = require("../MusicVideoCompact");
12
12
  class MusicAllSearchResultParser {
13
+ static parseTopResult(data, client) {
14
+ var _a;
15
+ const sectionListContents = data.contents.tabbedSearchResultsRenderer.tabs[0].tabRenderer.content
16
+ .sectionListRenderer.contents;
17
+ const top = (_a = sectionListContents.find((f) => f.musicCardShelfRenderer)) === null || _a === void 0 ? void 0 : _a.musicCardShelfRenderer;
18
+ if (!top)
19
+ return;
20
+ const { browseEndpoint, watchEndpoint } = top.title.runs[0].navigationEndpoint;
21
+ const id = (watchEndpoint === null || watchEndpoint === void 0 ? void 0 : watchEndpoint.videoId) || (browseEndpoint === null || browseEndpoint === void 0 ? void 0 : browseEndpoint.browseId);
22
+ const type = (watchEndpoint === null || watchEndpoint === void 0 ? void 0 : watchEndpoint.watchEndpointMusicSupportedConfigs.watchEndpointMusicConfig.musicVideoType) || (browseEndpoint === null || browseEndpoint === void 0 ? void 0 : browseEndpoint.browseEndpointContextSupportedConfigs.browseEndpointContextMusicConfig.pageType);
23
+ const title = top.title.runs[0].text;
24
+ const thumbnail = top.thumbnail.musicThumbnailRenderer.thumbnail.thumbnails;
25
+ let topResult;
26
+ if (type === "MUSIC_VIDEO_TYPE_ATV") {
27
+ topResult = new MusicSongCompact_1.MusicSongCompact({
28
+ client,
29
+ id,
30
+ title,
31
+ duration: common_1.getDuration(top.subtitle.runs.at(-1).text),
32
+ artists: MusicAllSearchResultParser.parseArtists(top.subtitle.runs, client),
33
+ album: MusicAllSearchResultParser.parseAlbum(top.subtitle.runs, client),
34
+ thumbnails: new common_1.Thumbnails().load(thumbnail),
35
+ });
36
+ }
37
+ else if (type === "MUSIC_VIDEO_TYPE_UGC" || type === "MUSIC_VIDEO_TYPE_OMV") {
38
+ topResult = new MusicVideoCompact_1.MusicVideoCompact({
39
+ client,
40
+ id,
41
+ title,
42
+ duration: common_1.getDuration(top.subtitle.runs.at(-1).text),
43
+ artists: MusicAllSearchResultParser.parseArtists(top.subtitle.runs, client),
44
+ thumbnails: new common_1.Thumbnails().load(thumbnail),
45
+ });
46
+ }
47
+ else if (type === "MUSIC_PAGE_TYPE_ALBUM") {
48
+ topResult = new MusicAlbumCompact_1.MusicAlbumCompact({
49
+ client,
50
+ id,
51
+ title,
52
+ artists: MusicAllSearchResultParser.parseArtists(top.subtitle.runs, client),
53
+ thumbnails: new common_1.Thumbnails().load(thumbnail),
54
+ });
55
+ }
56
+ else if (type === "MUSIC_PAGE_TYPE_ARTIST") {
57
+ topResult = new MusicArtistCompact_1.MusicArtistCompact({
58
+ client,
59
+ id,
60
+ name: title,
61
+ thumbnails: new common_1.Thumbnails().load(thumbnail),
62
+ });
63
+ }
64
+ else if (type === "MUSIC_PAGE_TYPE_PLAYLIST") {
65
+ topResult = new MusicPlaylistCompact_1.MusicPlaylistCompact({
66
+ client,
67
+ id,
68
+ title,
69
+ channel: MusicAllSearchResultParser.parseChannel(top.subtitle.runs, client),
70
+ thumbnails: new common_1.Thumbnails().load(thumbnail),
71
+ });
72
+ }
73
+ let more;
74
+ if (top.contents) {
75
+ more = top.contents
76
+ .filter((c) => c.musicResponsiveListItemRenderer)
77
+ .map((c) => MusicAllSearchResultParser.parseSearchItem(c, client));
78
+ }
79
+ return {
80
+ item: topResult,
81
+ more,
82
+ };
83
+ }
13
84
  static parseSearchResult(data, client) {
14
85
  const sectionListContents = data.contents.tabbedSearchResultsRenderer.tabs[0].tabRenderer.content
15
86
  .sectionListRenderer.contents;
@@ -18,7 +89,9 @@ class MusicAllSearchResultParser {
18
89
  .map((m) => m.musicShelfRenderer);
19
90
  return shelves.map((m) => ({
20
91
  title: m.title.runs.map((r) => r.text).join(),
21
- items: m.contents.map((c) => MusicAllSearchResultParser.parseSearchItem(c, client)),
92
+ items: m.contents
93
+ .map((c) => MusicAllSearchResultParser.parseSearchItem(c, client))
94
+ .filter((i) => i),
22
95
  }));
23
96
  }
24
97
  static parseSearchItem(content, client) {
@@ -28,21 +101,26 @@ class MusicAllSearchResultParser {
28
101
  if (playEndpoint === null || playEndpoint === void 0 ? void 0 : playEndpoint.watchEndpoint) {
29
102
  const pageType = playEndpoint.watchEndpoint.watchEndpointMusicSupportedConfigs
30
103
  .watchEndpointMusicConfig.musicVideoType;
31
- if (pageType === "MUSIC_VIDEO_TYPE_PODCAST_EPISODE")
32
- return;
33
104
  return MusicAllSearchResultParser.parseVideoItem(item, pageType, client);
34
105
  }
35
106
  else if (playEndpoint === null || playEndpoint === void 0 ? void 0 : playEndpoint.watchPlaylistEndpoint.params) {
36
107
  return MusicAllSearchResultParser.parsePlaylistItem(item, client);
37
108
  }
38
109
  else if (playEndpoint === null || playEndpoint === void 0 ? void 0 : playEndpoint.watchPlaylistEndpoint) {
39
- return MusicAllSearchResultParser.parseAlbumItem(item, client);
110
+ // TODO add podcast support, id starts with PL
111
+ if (playEndpoint.watchPlaylistEndpoint.playlistId.startsWith("OL")) {
112
+ return MusicAllSearchResultParser.parseAlbumItem(item, client);
113
+ }
40
114
  }
41
115
  else {
42
116
  return MusicAllSearchResultParser.parseArtistItem(item, client);
43
117
  }
44
118
  }
45
119
  static parseVideoItem(item, pageType, client) {
120
+ // TODO support other types
121
+ if (!["MUSIC_VIDEO_TYPE_ATV", "MUSIC_VIDEO_TYPE_UGC", "MUSIC_VIDEO_TYPE_OMV"].includes(pageType)) {
122
+ return;
123
+ }
46
124
  const [topColumn, bottomColumn] = item.flexColumns.map((c) => c.musicResponsiveListItemFlexColumnRenderer.text.runs);
47
125
  const id = topColumn[0].navigationEndpoint.watchEndpoint.videoId;
48
126
  const title = topColumn[0].text;
@@ -50,28 +128,17 @@ class MusicAllSearchResultParser {
50
128
  const thumbnails = new common_1.Thumbnails().load(item.thumbnail.musicThumbnailRenderer.thumbnail.thumbnails);
51
129
  const artists = MusicAllSearchResultParser.parseArtists(bottomColumn, client);
52
130
  if (pageType === "MUSIC_VIDEO_TYPE_ATV") {
53
- const rawAlbum = bottomColumn.find((r) => {
54
- var _a;
55
- return ((_a = r.navigationEndpoint) === null || _a === void 0 ? void 0 : _a.browseEndpoint.browseEndpointContextSupportedConfigs.browseEndpointContextMusicConfig.pageType) === "MUSIC_PAGE_TYPE_ALBUM";
56
- });
57
- const album = rawAlbum
58
- ? new MusicAlbumCompact_1.MusicAlbumCompact({
59
- client,
60
- id: rawAlbum.navigationEndpoint.browseEndpoint.browseId,
61
- title: rawAlbum.text,
62
- })
63
- : undefined;
64
131
  return new MusicSongCompact_1.MusicSongCompact({
65
132
  client,
66
133
  id,
67
- album,
134
+ album: MusicAllSearchResultParser.parseAlbum(bottomColumn, client),
68
135
  title,
69
136
  artists,
70
137
  thumbnails,
71
138
  duration,
72
139
  });
73
140
  }
74
- else if (pageType === "MUSIC_VIDEO_TYPE_UGC") {
141
+ else if (pageType === "MUSIC_VIDEO_TYPE_UGC" || pageType === "MUSIC_VIDEO_TYPE_OMV") {
75
142
  return new MusicVideoCompact_1.MusicVideoCompact({ client, id, title, artists, thumbnails, duration });
76
143
  }
77
144
  }
@@ -102,34 +169,53 @@ class MusicAllSearchResultParser {
102
169
  const thumbnails = new common_1.Thumbnails().load(item.thumbnail.musicThumbnailRenderer.thumbnail.thumbnails);
103
170
  return new MusicArtistCompact_1.MusicArtistCompact({ client, id, name, thumbnails });
104
171
  }
105
- static parseArtists(items, client) {
106
- return this.parseArtistOrChannel(items).map((r) => {
172
+ static parseAlbum(items, client) {
173
+ var _a;
174
+ const albumRaw = items.find((r) => {
107
175
  var _a;
108
- return new MusicBaseArtist_1.MusicBaseArtist({
109
- client,
110
- name: r.text,
111
- id: (_a = r.navigationEndpoint) === null || _a === void 0 ? void 0 : _a.browseEndpoint.browseId,
112
- });
176
+ const pageType = (_a = r.navigationEndpoint) === null || _a === void 0 ? void 0 : _a.browseEndpoint.browseEndpointContextSupportedConfigs.browseEndpointContextMusicConfig.pageType;
177
+ return pageType === "MUSIC_PAGE_TYPE_ALBUM";
178
+ });
179
+ if (!albumRaw)
180
+ return;
181
+ const album = new MusicAlbumCompact_1.MusicAlbumCompact({
182
+ client,
183
+ title: albumRaw.text,
184
+ id: (_a = albumRaw.navigationEndpoint) === null || _a === void 0 ? void 0 : _a.browseEndpoint.browseId,
113
185
  });
186
+ return album;
114
187
  }
115
- static parseChannel(items, client) {
116
- const [channel] = this.parseArtistOrChannel(items).map((r) => {
188
+ static parseArtists(items, client) {
189
+ return items
190
+ .filter((r) => {
191
+ var _a;
192
+ const pageType = (_a = r.navigationEndpoint) === null || _a === void 0 ? void 0 : _a.browseEndpoint.browseEndpointContextSupportedConfigs.browseEndpointContextMusicConfig.pageType;
193
+ return pageType === "MUSIC_PAGE_TYPE_ARTIST";
194
+ })
195
+ .map((r) => {
117
196
  var _a;
118
- return new MusicBaseChannel_1.MusicBaseChannel({
197
+ return new MusicBaseArtist_1.MusicBaseArtist({
119
198
  client,
120
199
  name: r.text,
121
200
  id: (_a = r.navigationEndpoint) === null || _a === void 0 ? void 0 : _a.browseEndpoint.browseId,
122
201
  });
123
202
  });
124
- return channel;
125
203
  }
126
- static parseArtistOrChannel(items) {
127
- const contents = items.filter((r) => {
204
+ static parseChannel(items, client) {
205
+ var _a;
206
+ const channelRaw = items.find((r) => {
128
207
  var _a;
129
208
  const pageType = (_a = r.navigationEndpoint) === null || _a === void 0 ? void 0 : _a.browseEndpoint.browseEndpointContextSupportedConfigs.browseEndpointContextMusicConfig.pageType;
130
- return (pageType === "MUSIC_PAGE_TYPE_ARTIST" || pageType === "MUSIC_PAGE_TYPE_USER_CHANNEL");
209
+ return pageType === "MUSIC_PAGE_TYPE_USER_CHANNEL";
210
+ });
211
+ if (!channelRaw)
212
+ return;
213
+ const channel = new MusicBaseChannel_1.MusicBaseChannel({
214
+ client,
215
+ name: channelRaw.text,
216
+ id: (_a = channelRaw.navigationEndpoint) === null || _a === void 0 ? void 0 : _a.browseEndpoint.browseId,
131
217
  });
132
- return !contents.length && items[0] ? [items[0]] : contents;
218
+ return channel;
133
219
  }
134
220
  }
135
221
  exports.MusicAllSearchResultParser = MusicAllSearchResultParser;
@@ -79,6 +79,29 @@ var MusicClient = /** @class */ (function () {
79
79
  });
80
80
  });
81
81
  };
82
+ /**
83
+ * Searches for all video, song, album, playlist, or artist
84
+ *
85
+ * @param query The search query
86
+ */
87
+ MusicClient.prototype.searchAll = function (query) {
88
+ return __awaiter(this, void 0, void 0, function () {
89
+ var response;
90
+ return __generator(this, function (_a) {
91
+ switch (_a.label) {
92
+ case 0: return [4 /*yield*/, this.http.post(I_END_POINT + "/search", {
93
+ data: { query: query },
94
+ })];
95
+ case 1:
96
+ response = _a.sent();
97
+ return [2 /*return*/, {
98
+ top: MusicAllSearchResultParser.parseTopResult(response.data, this),
99
+ shelves: MusicAllSearchResultParser.parseSearchResult(response.data, this),
100
+ }];
101
+ }
102
+ });
103
+ });
104
+ };
82
105
  /**
83
106
  * Get lyrics of a song
84
107
  *
@@ -25,6 +25,77 @@ import { MusicVideoCompact } from "../MusicVideoCompact";
25
25
  var MusicAllSearchResultParser = /** @class */ (function () {
26
26
  function MusicAllSearchResultParser() {
27
27
  }
28
+ MusicAllSearchResultParser.parseTopResult = function (data, client) {
29
+ var _a;
30
+ var sectionListContents = data.contents.tabbedSearchResultsRenderer.tabs[0].tabRenderer.content
31
+ .sectionListRenderer.contents;
32
+ var top = (_a = sectionListContents.find(function (f) { return f.musicCardShelfRenderer; })) === null || _a === void 0 ? void 0 : _a.musicCardShelfRenderer;
33
+ if (!top)
34
+ return;
35
+ var _b = top.title.runs[0].navigationEndpoint, browseEndpoint = _b.browseEndpoint, watchEndpoint = _b.watchEndpoint;
36
+ var id = (watchEndpoint === null || watchEndpoint === void 0 ? void 0 : watchEndpoint.videoId) || (browseEndpoint === null || browseEndpoint === void 0 ? void 0 : browseEndpoint.browseId);
37
+ var type = (watchEndpoint === null || watchEndpoint === void 0 ? void 0 : watchEndpoint.watchEndpointMusicSupportedConfigs.watchEndpointMusicConfig.musicVideoType) || (browseEndpoint === null || browseEndpoint === void 0 ? void 0 : browseEndpoint.browseEndpointContextSupportedConfigs.browseEndpointContextMusicConfig.pageType);
38
+ var title = top.title.runs[0].text;
39
+ var thumbnail = top.thumbnail.musicThumbnailRenderer.thumbnail.thumbnails;
40
+ var topResult;
41
+ if (type === "MUSIC_VIDEO_TYPE_ATV") {
42
+ topResult = new MusicSongCompact({
43
+ client: client,
44
+ id: id,
45
+ title: title,
46
+ duration: getDuration(top.subtitle.runs.at(-1).text),
47
+ artists: MusicAllSearchResultParser.parseArtists(top.subtitle.runs, client),
48
+ album: MusicAllSearchResultParser.parseAlbum(top.subtitle.runs, client),
49
+ thumbnails: new Thumbnails().load(thumbnail),
50
+ });
51
+ }
52
+ else if (type === "MUSIC_VIDEO_TYPE_UGC" || type === "MUSIC_VIDEO_TYPE_OMV") {
53
+ topResult = new MusicVideoCompact({
54
+ client: client,
55
+ id: id,
56
+ title: title,
57
+ duration: getDuration(top.subtitle.runs.at(-1).text),
58
+ artists: MusicAllSearchResultParser.parseArtists(top.subtitle.runs, client),
59
+ thumbnails: new Thumbnails().load(thumbnail),
60
+ });
61
+ }
62
+ else if (type === "MUSIC_PAGE_TYPE_ALBUM") {
63
+ topResult = new MusicAlbumCompact({
64
+ client: client,
65
+ id: id,
66
+ title: title,
67
+ artists: MusicAllSearchResultParser.parseArtists(top.subtitle.runs, client),
68
+ thumbnails: new Thumbnails().load(thumbnail),
69
+ });
70
+ }
71
+ else if (type === "MUSIC_PAGE_TYPE_ARTIST") {
72
+ topResult = new MusicArtistCompact({
73
+ client: client,
74
+ id: id,
75
+ name: title,
76
+ thumbnails: new Thumbnails().load(thumbnail),
77
+ });
78
+ }
79
+ else if (type === "MUSIC_PAGE_TYPE_PLAYLIST") {
80
+ topResult = new MusicPlaylistCompact({
81
+ client: client,
82
+ id: id,
83
+ title: title,
84
+ channel: MusicAllSearchResultParser.parseChannel(top.subtitle.runs, client),
85
+ thumbnails: new Thumbnails().load(thumbnail),
86
+ });
87
+ }
88
+ var more;
89
+ if (top.contents) {
90
+ more = top.contents
91
+ .filter(function (c) { return c.musicResponsiveListItemRenderer; })
92
+ .map(function (c) { return MusicAllSearchResultParser.parseSearchItem(c, client); });
93
+ }
94
+ return {
95
+ item: topResult,
96
+ more: more,
97
+ };
98
+ };
28
99
  MusicAllSearchResultParser.parseSearchResult = function (data, client) {
29
100
  var sectionListContents = data.contents.tabbedSearchResultsRenderer.tabs[0].tabRenderer.content
30
101
  .sectionListRenderer.contents;
@@ -33,9 +104,9 @@ var MusicAllSearchResultParser = /** @class */ (function () {
33
104
  .map(function (m) { return m.musicShelfRenderer; });
34
105
  return shelves.map(function (m) { return ({
35
106
  title: m.title.runs.map(function (r) { return r.text; }).join(),
36
- items: m.contents.map(function (c) {
37
- return MusicAllSearchResultParser.parseSearchItem(c, client);
38
- }),
107
+ items: m.contents
108
+ .map(function (c) { return MusicAllSearchResultParser.parseSearchItem(c, client); })
109
+ .filter(function (i) { return i; }),
39
110
  }); });
40
111
  };
41
112
  MusicAllSearchResultParser.parseSearchItem = function (content, client) {
@@ -45,21 +116,26 @@ var MusicAllSearchResultParser = /** @class */ (function () {
45
116
  if (playEndpoint === null || playEndpoint === void 0 ? void 0 : playEndpoint.watchEndpoint) {
46
117
  var pageType = playEndpoint.watchEndpoint.watchEndpointMusicSupportedConfigs
47
118
  .watchEndpointMusicConfig.musicVideoType;
48
- if (pageType === "MUSIC_VIDEO_TYPE_PODCAST_EPISODE")
49
- return;
50
119
  return MusicAllSearchResultParser.parseVideoItem(item, pageType, client);
51
120
  }
52
121
  else if (playEndpoint === null || playEndpoint === void 0 ? void 0 : playEndpoint.watchPlaylistEndpoint.params) {
53
122
  return MusicAllSearchResultParser.parsePlaylistItem(item, client);
54
123
  }
55
124
  else if (playEndpoint === null || playEndpoint === void 0 ? void 0 : playEndpoint.watchPlaylistEndpoint) {
56
- return MusicAllSearchResultParser.parseAlbumItem(item, client);
125
+ // TODO add podcast support, id starts with PL
126
+ if (playEndpoint.watchPlaylistEndpoint.playlistId.startsWith("OL")) {
127
+ return MusicAllSearchResultParser.parseAlbumItem(item, client);
128
+ }
57
129
  }
58
130
  else {
59
131
  return MusicAllSearchResultParser.parseArtistItem(item, client);
60
132
  }
61
133
  };
62
134
  MusicAllSearchResultParser.parseVideoItem = function (item, pageType, client) {
135
+ // TODO support other types
136
+ if (!["MUSIC_VIDEO_TYPE_ATV", "MUSIC_VIDEO_TYPE_UGC", "MUSIC_VIDEO_TYPE_OMV"].includes(pageType)) {
137
+ return;
138
+ }
63
139
  var _a = __read(item.flexColumns.map(function (c) { return c.musicResponsiveListItemFlexColumnRenderer.text.runs; }), 2), topColumn = _a[0], bottomColumn = _a[1];
64
140
  var id = topColumn[0].navigationEndpoint.watchEndpoint.videoId;
65
141
  var title = topColumn[0].text;
@@ -67,28 +143,17 @@ var MusicAllSearchResultParser = /** @class */ (function () {
67
143
  var thumbnails = new Thumbnails().load(item.thumbnail.musicThumbnailRenderer.thumbnail.thumbnails);
68
144
  var artists = MusicAllSearchResultParser.parseArtists(bottomColumn, client);
69
145
  if (pageType === "MUSIC_VIDEO_TYPE_ATV") {
70
- var rawAlbum = bottomColumn.find(function (r) {
71
- var _a;
72
- return ((_a = r.navigationEndpoint) === null || _a === void 0 ? void 0 : _a.browseEndpoint.browseEndpointContextSupportedConfigs.browseEndpointContextMusicConfig.pageType) === "MUSIC_PAGE_TYPE_ALBUM";
73
- });
74
- var album = rawAlbum
75
- ? new MusicAlbumCompact({
76
- client: client,
77
- id: rawAlbum.navigationEndpoint.browseEndpoint.browseId,
78
- title: rawAlbum.text,
79
- })
80
- : undefined;
81
146
  return new MusicSongCompact({
82
147
  client: client,
83
148
  id: id,
84
- album: album,
149
+ album: MusicAllSearchResultParser.parseAlbum(bottomColumn, client),
85
150
  title: title,
86
151
  artists: artists,
87
152
  thumbnails: thumbnails,
88
153
  duration: duration,
89
154
  });
90
155
  }
91
- else if (pageType === "MUSIC_VIDEO_TYPE_UGC") {
156
+ else if (pageType === "MUSIC_VIDEO_TYPE_UGC" || pageType === "MUSIC_VIDEO_TYPE_OMV") {
92
157
  return new MusicVideoCompact({ client: client, id: id, title: title, artists: artists, thumbnails: thumbnails, duration: duration });
93
158
  }
94
159
  };
@@ -119,8 +184,30 @@ var MusicAllSearchResultParser = /** @class */ (function () {
119
184
  var thumbnails = new Thumbnails().load(item.thumbnail.musicThumbnailRenderer.thumbnail.thumbnails);
120
185
  return new MusicArtistCompact({ client: client, id: id, name: name, thumbnails: thumbnails });
121
186
  };
187
+ MusicAllSearchResultParser.parseAlbum = function (items, client) {
188
+ var _a;
189
+ var albumRaw = items.find(function (r) {
190
+ var _a;
191
+ var pageType = (_a = r.navigationEndpoint) === null || _a === void 0 ? void 0 : _a.browseEndpoint.browseEndpointContextSupportedConfigs.browseEndpointContextMusicConfig.pageType;
192
+ return pageType === "MUSIC_PAGE_TYPE_ALBUM";
193
+ });
194
+ if (!albumRaw)
195
+ return;
196
+ var album = new MusicAlbumCompact({
197
+ client: client,
198
+ title: albumRaw.text,
199
+ id: (_a = albumRaw.navigationEndpoint) === null || _a === void 0 ? void 0 : _a.browseEndpoint.browseId,
200
+ });
201
+ return album;
202
+ };
122
203
  MusicAllSearchResultParser.parseArtists = function (items, client) {
123
- return this.parseArtistOrChannel(items).map(function (r) {
204
+ return items
205
+ .filter(function (r) {
206
+ var _a;
207
+ var pageType = (_a = r.navigationEndpoint) === null || _a === void 0 ? void 0 : _a.browseEndpoint.browseEndpointContextSupportedConfigs.browseEndpointContextMusicConfig.pageType;
208
+ return pageType === "MUSIC_PAGE_TYPE_ARTIST";
209
+ })
210
+ .map(function (r) {
124
211
  var _a;
125
212
  return new MusicBaseArtist({
126
213
  client: client,
@@ -130,23 +217,20 @@ var MusicAllSearchResultParser = /** @class */ (function () {
130
217
  });
131
218
  };
132
219
  MusicAllSearchResultParser.parseChannel = function (items, client) {
133
- var _a = __read(this.parseArtistOrChannel(items).map(function (r) {
134
- var _a;
135
- return new MusicBaseChannel({
136
- client: client,
137
- name: r.text,
138
- id: (_a = r.navigationEndpoint) === null || _a === void 0 ? void 0 : _a.browseEndpoint.browseId,
139
- });
140
- }), 1), channel = _a[0];
141
- return channel;
142
- };
143
- MusicAllSearchResultParser.parseArtistOrChannel = function (items) {
144
- var contents = items.filter(function (r) {
220
+ var _a;
221
+ var channelRaw = items.find(function (r) {
145
222
  var _a;
146
223
  var pageType = (_a = r.navigationEndpoint) === null || _a === void 0 ? void 0 : _a.browseEndpoint.browseEndpointContextSupportedConfigs.browseEndpointContextMusicConfig.pageType;
147
- return (pageType === "MUSIC_PAGE_TYPE_ARTIST" || pageType === "MUSIC_PAGE_TYPE_USER_CHANNEL");
224
+ return pageType === "MUSIC_PAGE_TYPE_USER_CHANNEL";
225
+ });
226
+ if (!channelRaw)
227
+ return;
228
+ var channel = new MusicBaseChannel({
229
+ client: client,
230
+ name: channelRaw.text,
231
+ id: (_a = channelRaw.navigationEndpoint) === null || _a === void 0 ? void 0 : _a.browseEndpoint.browseId,
148
232
  });
149
- return !contents.length && items[0] ? [items[0]] : contents;
233
+ return channel;
150
234
  };
151
235
  return MusicAllSearchResultParser;
152
236
  }());
@@ -6,6 +6,10 @@ import { MusicLyrics } from "../MusicLyrics";
6
6
  import { MusicPlaylistCompact } from "../MusicPlaylistCompact";
7
7
  import { MusicSearchResult, MusicSearchType } from "../MusicSearchResult";
8
8
  import { MusicVideoCompact } from "../MusicVideoCompact";
9
+ export declare type MusicTopShelf = {
10
+ item?: MusicVideoCompact | MusicAlbumCompact | MusicPlaylistCompact | MusicArtistCompact;
11
+ more?: (MusicVideoCompact | MusicAlbumCompact | MusicPlaylistCompact | MusicArtistCompact)[];
12
+ };
9
13
  export declare type MusicClientOptions = {
10
14
  initialCookie: string;
11
15
  /** Optional options for http client */
@@ -22,11 +26,20 @@ export declare class MusicClient {
22
26
  * Searches for video, song, album, playlist, or artist
23
27
  *
24
28
  * @param query The search query
25
- * @param options Search options
29
+ * @param type Search type
26
30
  *
27
31
  */
28
32
  search(query: string): Promise<Shelf<MusicVideoCompact[] | MusicAlbumCompact[] | MusicPlaylistCompact[] | MusicArtistCompact[]>[]>;
29
33
  search<T extends MusicSearchType>(query: string, type: T): Promise<MusicSearchResult<T>>;
34
+ /**
35
+ * Searches for all video, song, album, playlist, or artist
36
+ *
37
+ * @param query The search query
38
+ */
39
+ searchAll(query: string): Promise<{
40
+ top?: MusicTopShelf;
41
+ shelves: Shelf<MusicVideoCompact[] | MusicAlbumCompact[] | MusicPlaylistCompact[] | MusicArtistCompact[]>[];
42
+ }>;
30
43
  /**
31
44
  * Get lyrics of a song
32
45
  *
@@ -1,17 +1,18 @@
1
1
  import { Shelf, YoutubeRawData } from "../../common";
2
2
  import { MusicAlbumCompact } from "../MusicAlbumCompact";
3
- import { MusicClient } from "../MusicClient";
3
+ import { MusicClient, MusicTopShelf } from "../MusicClient";
4
4
  import { MusicPlaylistCompact } from "../MusicPlaylistCompact";
5
5
  import { MusicSongCompact } from "../MusicSongCompact";
6
6
  import { MusicVideoCompact } from "../MusicVideoCompact";
7
7
  export declare class MusicAllSearchResultParser {
8
+ static parseTopResult(data: YoutubeRawData, client: MusicClient): MusicTopShelf | undefined;
8
9
  static parseSearchResult(data: YoutubeRawData, client: MusicClient): Shelf<MusicVideoCompact[] | MusicAlbumCompact[] | MusicPlaylistCompact[]>[];
9
10
  private static parseSearchItem;
10
11
  static parseVideoItem(item: YoutubeRawData, pageType: string, client: MusicClient): MusicSongCompact | MusicVideoCompact | undefined;
11
12
  private static parsePlaylistItem;
12
13
  private static parseAlbumItem;
13
14
  private static parseArtistItem;
15
+ private static parseAlbum;
14
16
  private static parseArtists;
15
17
  private static parseChannel;
16
- private static parseArtistOrChannel;
17
18
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "youtubei",
3
- "version": "1.4.5",
3
+ "version": "1.5.1",
4
4
  "description": "Simple package to get information from youtube such as videos, playlists, channels, video information & comments, related videos, up next video, and more!",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",