youtubei 1.6.7 → 1.8.0
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.
- package/dist/cjs/common/shared/HTTP/HTTP.js +1 -3
- package/dist/cjs/common/utils/helper.js +5 -1
- package/dist/cjs/music/MusicClient/MusicClient.js +13 -18
- package/dist/cjs/music/MusicSearchResult/MusicSearchResult.js +6 -4
- package/dist/cjs/music/MusicSearchResult/MusicSearchResultParser.js +205 -14
- package/dist/cjs/music/MusicSearchResult/index.js +0 -1
- package/dist/cjs/youtube/BaseChannel/BaseChannel.js +2 -0
- package/dist/cjs/youtube/BaseChannel/BaseChannelParser.js +3 -2
- package/dist/cjs/youtube/BaseChannel/ChannelPlaylists.js +12 -2
- package/dist/cjs/youtube/BaseChannel/ChannelPosts.js +59 -0
- package/dist/cjs/youtube/BaseVideo/BaseVideoParser.js +14 -2
- package/dist/cjs/youtube/Channel/ChannelParser.js +10 -6
- package/dist/cjs/youtube/PlaylistCompact/PlaylistCompact.js +9 -0
- package/dist/cjs/youtube/PlaylistCompact/PlaylistCompactParser.js +23 -0
- package/dist/cjs/youtube/Post/Post.js +23 -0
- package/dist/cjs/youtube/Post/PostParser.js +23 -0
- package/dist/cjs/youtube/Post/index.js +14 -0
- package/dist/cjs/youtube/SearchResult/SearchResultParser.js +10 -0
- package/dist/cjs/youtube/VideoCompact/VideoCompact.js +9 -0
- package/dist/cjs/youtube/VideoCompact/VideoCompactParser.js +27 -0
- package/dist/esm/common/shared/HTTP/HTTP.js +1 -3
- package/dist/esm/common/utils/helper.js +5 -1
- package/dist/esm/music/MusicClient/MusicClient.js +16 -20
- package/dist/esm/music/MusicSearchResult/MusicSearchResult.js +5 -4
- package/dist/esm/music/MusicSearchResult/MusicSearchResultParser.js +221 -14
- package/dist/esm/music/MusicSearchResult/index.js +0 -1
- package/dist/esm/youtube/BaseChannel/BaseChannel.js +2 -0
- package/dist/esm/youtube/BaseChannel/BaseChannelParser.js +3 -2
- package/dist/esm/youtube/BaseChannel/ChannelPlaylists.js +11 -3
- package/dist/esm/youtube/BaseChannel/ChannelPosts.js +111 -0
- package/dist/esm/youtube/BaseVideo/BaseVideoParser.js +14 -2
- package/dist/esm/youtube/Channel/ChannelParser.js +12 -8
- package/dist/esm/youtube/PlaylistCompact/PlaylistCompact.js +9 -0
- package/dist/esm/youtube/PlaylistCompact/PlaylistCompactParser.js +23 -0
- package/dist/esm/youtube/Post/Post.js +36 -0
- package/dist/esm/youtube/Post/PostParser.js +23 -0
- package/dist/esm/youtube/Post/index.js +2 -0
- package/dist/esm/youtube/SearchResult/SearchResultParser.js +10 -0
- package/dist/esm/youtube/VideoCompact/VideoCompact.js +9 -0
- package/dist/esm/youtube/VideoCompact/VideoCompactParser.js +27 -0
- package/dist/typings/music/MusicClient/MusicClient.d.ts +3 -7
- package/dist/typings/music/MusicSearchResult/MusicSearchResult.d.ts +7 -4
- package/dist/typings/music/MusicSearchResult/MusicSearchResultParser.d.ts +15 -3
- package/dist/typings/music/MusicSearchResult/index.d.ts +0 -1
- package/dist/typings/youtube/BaseChannel/BaseChannel.d.ts +4 -1
- package/dist/typings/youtube/BaseChannel/BaseChannelParser.d.ts +1 -0
- package/dist/typings/youtube/BaseChannel/ChannelPosts.d.ts +30 -0
- package/dist/typings/youtube/PlaylistCompact/PlaylistCompact.d.ts +6 -0
- package/dist/typings/youtube/PlaylistCompact/PlaylistCompactParser.d.ts +1 -0
- package/dist/typings/youtube/Post/Post.d.ts +32 -0
- package/dist/typings/youtube/Post/PostParser.d.ts +5 -0
- package/dist/typings/youtube/Post/index.d.ts +2 -0
- package/dist/typings/youtube/VideoCompact/VideoCompact.d.ts +6 -0
- package/dist/typings/youtube/VideoCompact/VideoCompactParser.d.ts +1 -0
- package/package.json +1 -1
- package/dist/cjs/music/MusicSearchResult/MusicAllSearchResultParser.js +0 -218
- package/dist/esm/music/MusicSearchResult/MusicAllSearchResultParser.js +0 -234
- package/dist/typings/music/MusicSearchResult/MusicAllSearchResultParser.d.ts +0 -19
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PostParser = void 0;
|
|
4
|
+
const BaseChannel_1 = require("../BaseChannel");
|
|
5
|
+
class PostParser {
|
|
6
|
+
static loadPost(target, data) {
|
|
7
|
+
var _a, _b, _c, _d;
|
|
8
|
+
const { postId, authorText, authorThumbnail, authorEndpoint, contentText, publishedTimeText, voteCount, } = data;
|
|
9
|
+
// Basic information
|
|
10
|
+
target.id = postId;
|
|
11
|
+
target.content = (_a = contentText === null || contentText === void 0 ? void 0 : contentText.runs) === null || _a === void 0 ? void 0 : _a.map((r) => r.text).join("");
|
|
12
|
+
target.channel = new BaseChannel_1.BaseChannel({
|
|
13
|
+
id: (_b = authorEndpoint === null || authorEndpoint === void 0 ? void 0 : authorEndpoint.browseEndpoint) === null || _b === void 0 ? void 0 : _b.browseId,
|
|
14
|
+
name: (_c = authorText.runs) === null || _c === void 0 ? void 0 : _c[0].text,
|
|
15
|
+
thumbnails: authorThumbnail.thumbnails,
|
|
16
|
+
client: target.client,
|
|
17
|
+
});
|
|
18
|
+
target.timestamp = (_d = publishedTimeText.runs[0]) === null || _d === void 0 ? void 0 : _d.text;
|
|
19
|
+
target.voteCount = voteCount.simpleText;
|
|
20
|
+
return target;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
exports.PostParser = PostParser;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
10
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
__exportStar(require("./Post"), exports);
|
|
14
|
+
__exportStar(require("./PostParser"), exports);
|
|
@@ -33,6 +33,16 @@ class SearchResultParser {
|
|
|
33
33
|
contents.push(new VideoCompact_1.VideoCompact({ client }).load(c.videoRenderer));
|
|
34
34
|
else if ("channelRenderer" in c)
|
|
35
35
|
contents.push(new BaseChannel_1.BaseChannel({ client }).load(c.channelRenderer));
|
|
36
|
+
else if ("lockupViewModel" in c) {
|
|
37
|
+
// new data structure for search result
|
|
38
|
+
const type = c.lockupViewModel.contentType;
|
|
39
|
+
if (type === "LOCKUP_CONTENT_TYPE_VIDEO") {
|
|
40
|
+
contents.push(new VideoCompact_1.VideoCompact({ client }).loadLockup(c.lockupViewModel));
|
|
41
|
+
}
|
|
42
|
+
else if (type === "LOCKUP_CONTENT_TYPE_PLAYLIST") {
|
|
43
|
+
contents.push(new PlaylistCompact_1.PlaylistCompact({ client }).loadLockup(c.lockupViewModel));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
36
46
|
}
|
|
37
47
|
return contents;
|
|
38
48
|
}
|
|
@@ -32,6 +32,15 @@ class VideoCompact extends Base_1.Base {
|
|
|
32
32
|
VideoCompactParser_1.VideoCompactParser.loadVideoCompact(this, data);
|
|
33
33
|
return this;
|
|
34
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* Load this instance with raw lockup data from Youtube
|
|
37
|
+
*
|
|
38
|
+
* @hidden
|
|
39
|
+
*/
|
|
40
|
+
loadLockup(data) {
|
|
41
|
+
VideoCompactParser_1.VideoCompactParser.loadLockupVideoCompact(this, data);
|
|
42
|
+
return this;
|
|
43
|
+
}
|
|
35
44
|
/**
|
|
36
45
|
* Get {@link Video} object based on current video id
|
|
37
46
|
*
|
|
@@ -38,5 +38,32 @@ class VideoCompactParser {
|
|
|
38
38
|
target.viewCount = common_1.stripToInt((viewCountText === null || viewCountText === void 0 ? void 0 : viewCountText.simpleText) || (viewCountText === null || viewCountText === void 0 ? void 0 : viewCountText.runs[0].text));
|
|
39
39
|
return target;
|
|
40
40
|
}
|
|
41
|
+
static loadLockupVideoCompact(target, data) {
|
|
42
|
+
var _a, _b;
|
|
43
|
+
const lockupMetadataViewModel = data.metadata.lockupMetadataViewModel;
|
|
44
|
+
const decoratedAvatarViewModel = lockupMetadataViewModel.image.decoratedAvatarViewModel;
|
|
45
|
+
const thumbnailBadge = data.contentImage.thumbnailViewModel.overlays[0].thumbnailOverlayBadgeViewModel
|
|
46
|
+
.thumbnailBadges[0].thumbnailBadgeViewModel;
|
|
47
|
+
const metadataRows = lockupMetadataViewModel.metadata.contentMetadataViewModel.metadataRows;
|
|
48
|
+
const channel = new BaseChannel_1.BaseChannel({
|
|
49
|
+
client: target.client,
|
|
50
|
+
name: metadataRows[0].metadataParts[0].text.content,
|
|
51
|
+
id: decoratedAvatarViewModel.rendererContext.commandContext.onTap.innertubeCommand
|
|
52
|
+
.browseEndpoint.browseId,
|
|
53
|
+
thumbnails: new common_1.Thumbnails().load(decoratedAvatarViewModel.avatar.avatarViewModel.image.sources),
|
|
54
|
+
});
|
|
55
|
+
const isLive = ((_a = thumbnailBadge.icon) === null || _a === void 0 ? void 0 : _a.sources[0].clientResource.imageName) === "LIVE";
|
|
56
|
+
target.channel = channel;
|
|
57
|
+
target.id = data.contentId;
|
|
58
|
+
target.title = lockupMetadataViewModel.title.content;
|
|
59
|
+
target.isLive = ((_b = thumbnailBadge.icon) === null || _b === void 0 ? void 0 : _b.sources[0].clientResource.imageName) === "LIVE";
|
|
60
|
+
target.duration = !isLive ? common_1.getDuration(thumbnailBadge.text) : null;
|
|
61
|
+
target.thumbnails = new common_1.Thumbnails().load(data.contentImage.thumbnailViewModel.image.sources);
|
|
62
|
+
target.viewCount = common_1.stripToInt(metadataRows[1].metadataParts[0].text.content);
|
|
63
|
+
target.uploadDate = !isLive
|
|
64
|
+
? metadataRows[1].metadataParts[metadataRows[1].metadataParts.length - 1].text.content
|
|
65
|
+
: undefined;
|
|
66
|
+
return target;
|
|
67
|
+
}
|
|
41
68
|
}
|
|
42
69
|
exports.VideoCompactParser = VideoCompactParser;
|
|
@@ -114,9 +114,7 @@ var HTTP = /** @class */ (function () {
|
|
|
114
114
|
switch (_b.label) {
|
|
115
115
|
case 0: return [4 /*yield*/, this.request(path, __assign(__assign({}, options), { method: "POST", params: __assign({ key: this.apiKey, prettyPrint: "false" }, options === null || options === void 0 ? void 0 : options.params), data: __assign({ context: {
|
|
116
116
|
client: __assign({ clientName: this.clientName, clientVersion: this.clientVersion, visitorData: (_a = this.pot) === null || _a === void 0 ? void 0 : _a.visitorData }, this.defaultClientOptions),
|
|
117
|
-
}, serviceIntegrityDimensions: this.pot
|
|
118
|
-
? { poToken: this.pot.token, }
|
|
119
|
-
: undefined }, options === null || options === void 0 ? void 0 : options.data) }))];
|
|
117
|
+
}, serviceIntegrityDimensions: this.pot ? { poToken: this.pot.token } : undefined }, options === null || options === void 0 ? void 0 : options.data) }))];
|
|
120
118
|
case 1: return [2 /*return*/, _b.sent()];
|
|
121
119
|
}
|
|
122
120
|
});
|
|
@@ -33,6 +33,7 @@ export var stripToInt = function (string) {
|
|
|
33
33
|
};
|
|
34
34
|
export var getContinuationFromItems = function (items, accessors) {
|
|
35
35
|
var e_1, _a;
|
|
36
|
+
var _b, _c, _d;
|
|
36
37
|
if (accessors === void 0) { accessors = ["continuationEndpoint"]; }
|
|
37
38
|
var continuation = items[items.length - 1];
|
|
38
39
|
var renderer = continuation === null || continuation === void 0 ? void 0 : continuation.continuationItemRenderer;
|
|
@@ -52,7 +53,10 @@ export var getContinuationFromItems = function (items, accessors) {
|
|
|
52
53
|
}
|
|
53
54
|
finally { if (e_1) throw e_1.error; }
|
|
54
55
|
}
|
|
55
|
-
|
|
56
|
+
if ((_c = (_b = current === null || current === void 0 ? void 0 : current.commandExecutorCommand) === null || _b === void 0 ? void 0 : _b.commands) === null || _c === void 0 ? void 0 : _c.length) {
|
|
57
|
+
current = current.commandExecutorCommand.commands.find(function (cmd) { return "continuationCommand" in cmd; });
|
|
58
|
+
}
|
|
59
|
+
return (_d = current === null || current === void 0 ? void 0 : current.continuationCommand) === null || _d === void 0 ? void 0 : _d.token;
|
|
56
60
|
};
|
|
57
61
|
export var mapFilter = function (items, key) {
|
|
58
62
|
return items
|
|
@@ -47,7 +47,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
47
47
|
};
|
|
48
48
|
import { HTTP } from "../../common";
|
|
49
49
|
import { MusicLyrics } from "../MusicLyrics";
|
|
50
|
-
import {
|
|
50
|
+
import { MusicSearchResult } from "../MusicSearchResult";
|
|
51
51
|
import { BASE_URL, INNERTUBE_API_KEY, INNERTUBE_CLIENT_NAME, INNERTUBE_CLIENT_VERSION, I_END_POINT, } from "../constants";
|
|
52
52
|
/** Youtube Music Client */
|
|
53
53
|
var MusicClient = /** @class */ (function () {
|
|
@@ -56,23 +56,22 @@ var MusicClient = /** @class */ (function () {
|
|
|
56
56
|
var fullOptions = __assign(__assign({ initialCookie: "", oauth: { enabled: false }, fetchOptions: {} }, options), { youtubeClientOptions: __assign({ hl: "en", gl: "US" }, options.youtubeClientOptions), apiKey: options.apiKey || INNERTUBE_API_KEY, baseUrl: options.baseUrl || BASE_URL, clientName: options.clientName || INNERTUBE_CLIENT_NAME, clientVersion: options.clientVersion || INNERTUBE_CLIENT_VERSION });
|
|
57
57
|
this.http = new HTTP(fullOptions);
|
|
58
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Searches for video, song, album, playlist, or artist
|
|
61
|
+
*
|
|
62
|
+
* @param query The search query
|
|
63
|
+
* @param type Search type
|
|
64
|
+
*
|
|
65
|
+
*/
|
|
59
66
|
MusicClient.prototype.search = function (query, type) {
|
|
60
67
|
return __awaiter(this, void 0, void 0, function () {
|
|
61
|
-
var
|
|
68
|
+
var result;
|
|
62
69
|
return __generator(this, function (_a) {
|
|
63
70
|
switch (_a.label) {
|
|
64
71
|
case 0:
|
|
65
|
-
if (!!type) return [3 /*break*/, 2];
|
|
66
|
-
return [4 /*yield*/, this.http.post(I_END_POINT + "/search", {
|
|
67
|
-
data: { query: query },
|
|
68
|
-
})];
|
|
69
|
-
case 1:
|
|
70
|
-
response = _a.sent();
|
|
71
|
-
return [2 /*return*/, MusicAllSearchResultParser.parseSearchResult(response.data, this)];
|
|
72
|
-
case 2:
|
|
73
72
|
result = new MusicSearchResult({ client: this });
|
|
74
73
|
return [4 /*yield*/, result.search(query, type)];
|
|
75
|
-
case
|
|
74
|
+
case 1:
|
|
76
75
|
_a.sent();
|
|
77
76
|
return [2 /*return*/, result];
|
|
78
77
|
}
|
|
@@ -86,18 +85,15 @@ var MusicClient = /** @class */ (function () {
|
|
|
86
85
|
*/
|
|
87
86
|
MusicClient.prototype.searchAll = function (query) {
|
|
88
87
|
return __awaiter(this, void 0, void 0, function () {
|
|
89
|
-
var
|
|
88
|
+
var result;
|
|
90
89
|
return __generator(this, function (_a) {
|
|
91
90
|
switch (_a.label) {
|
|
92
|
-
case 0:
|
|
93
|
-
|
|
94
|
-
|
|
91
|
+
case 0:
|
|
92
|
+
result = new MusicSearchResult({ client: this });
|
|
93
|
+
return [4 /*yield*/, result.search(query)];
|
|
95
94
|
case 1:
|
|
96
|
-
|
|
97
|
-
return [2 /*return*/,
|
|
98
|
-
top: MusicAllSearchResultParser.parseTopResult(response.data, this),
|
|
99
|
-
shelves: MusicAllSearchResultParser.parseSearchResult(response.data, this),
|
|
100
|
-
}];
|
|
95
|
+
_a.sent();
|
|
96
|
+
return [2 /*return*/, result];
|
|
101
97
|
}
|
|
102
98
|
});
|
|
103
99
|
});
|
|
@@ -125,16 +125,17 @@ var MusicSearchResult = /** @class */ (function (_super) {
|
|
|
125
125
|
case 0:
|
|
126
126
|
this.items = [];
|
|
127
127
|
this.type = type;
|
|
128
|
-
|
|
128
|
+
if (type)
|
|
129
|
+
bufferParams = MusicSearchProto.encode(optionsToProto(type)).finish();
|
|
129
130
|
return [4 /*yield*/, this.client.http.post(I_END_POINT + "/search", {
|
|
130
131
|
data: {
|
|
131
132
|
query: query,
|
|
132
|
-
params: Buffer.from(bufferParams).toString("base64"),
|
|
133
|
+
params: bufferParams ? Buffer.from(bufferParams).toString("base64") : undefined,
|
|
133
134
|
},
|
|
134
135
|
})];
|
|
135
136
|
case 1:
|
|
136
137
|
response = _c.sent();
|
|
137
|
-
_a = MusicSearchResultParser.parseInitialSearchResult(response.data,
|
|
138
|
+
_a = MusicSearchResultParser.parseInitialSearchResult(response.data, this.client), data = _a.data, continuation = _a.continuation;
|
|
138
139
|
(_b = this.items).push.apply(_b, __spread(data));
|
|
139
140
|
this.continuation = continuation;
|
|
140
141
|
return [2 /*return*/, this];
|
|
@@ -159,7 +160,7 @@ var MusicSearchResult = /** @class */ (function (_super) {
|
|
|
159
160
|
})];
|
|
160
161
|
case 1:
|
|
161
162
|
response = _b.sent();
|
|
162
|
-
_a = MusicSearchResultParser.parseContinuationSearchResult(response.data, this.
|
|
163
|
+
_a = MusicSearchResultParser.parseContinuationSearchResult(response.data, this.client), data = _a.data, continuation = _a.continuation;
|
|
163
164
|
return [2 /*return*/, {
|
|
164
165
|
items: data,
|
|
165
166
|
continuation: continuation,
|
|
@@ -9,43 +9,130 @@ var __values = (this && this.__values) || function(o) {
|
|
|
9
9
|
};
|
|
10
10
|
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
11
11
|
};
|
|
12
|
-
|
|
12
|
+
var __read = (this && this.__read) || function (o, n) {
|
|
13
|
+
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
14
|
+
if (!m) return o;
|
|
15
|
+
var i = m.call(o), r, ar = [], e;
|
|
16
|
+
try {
|
|
17
|
+
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
18
|
+
}
|
|
19
|
+
catch (error) { e = { error: error }; }
|
|
20
|
+
finally {
|
|
21
|
+
try {
|
|
22
|
+
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
23
|
+
}
|
|
24
|
+
finally { if (e) throw e.error; }
|
|
25
|
+
}
|
|
26
|
+
return ar;
|
|
27
|
+
};
|
|
28
|
+
import { getDuration, stripToInt, Thumbnails } from "../../common";
|
|
29
|
+
import { MusicAlbumCompact } from "../MusicAlbumCompact";
|
|
30
|
+
import { MusicArtistCompact } from "../MusicArtistCompact";
|
|
31
|
+
import { MusicBaseArtist } from "../MusicBaseArtist";
|
|
32
|
+
import { MusicBaseChannel } from "../MusicBaseChannel";
|
|
33
|
+
import { MusicPlaylistCompact } from "../MusicPlaylistCompact";
|
|
34
|
+
import { MusicSongCompact } from "../MusicSongCompact";
|
|
35
|
+
import { MusicVideoCompact } from "../MusicVideoCompact";
|
|
13
36
|
var MusicSearchResultParser = /** @class */ (function () {
|
|
14
37
|
function MusicSearchResultParser() {
|
|
15
38
|
}
|
|
16
|
-
MusicSearchResultParser.parseInitialSearchResult = function (data,
|
|
39
|
+
MusicSearchResultParser.parseInitialSearchResult = function (data, client) {
|
|
17
40
|
var _a, _b;
|
|
18
|
-
var
|
|
19
|
-
|
|
41
|
+
var sectionContents = data.contents.tabbedSearchResultsRenderer.tabs[0].tabRenderer.content
|
|
42
|
+
.sectionListRenderer.contents;
|
|
43
|
+
var topContent = sectionContents.find(function (c) { return "musicCardShelfRenderer" in c; });
|
|
44
|
+
var resultContents = sectionContents.find(function (c) { return "musicShelfRenderer" in c; });
|
|
45
|
+
var topResult = this.parseTopResult(topContent, client);
|
|
46
|
+
if (!resultContents) {
|
|
20
47
|
// no results
|
|
21
48
|
return {
|
|
22
|
-
data: [],
|
|
49
|
+
data: topResult ? [topResult] : [],
|
|
23
50
|
continuation: undefined,
|
|
24
51
|
};
|
|
25
52
|
}
|
|
26
|
-
var _c =
|
|
53
|
+
var _c = resultContents.musicShelfRenderer, contents = _c.contents, continuations = _c.continuations;
|
|
54
|
+
var result = MusicSearchResultParser.parseSearchResult(contents, client);
|
|
55
|
+
if (topResult)
|
|
56
|
+
result.unshift(topResult);
|
|
27
57
|
return {
|
|
28
|
-
data:
|
|
58
|
+
data: result,
|
|
29
59
|
continuation: (_b = (_a = continuations === null || continuations === void 0 ? void 0 : continuations[0]) === null || _a === void 0 ? void 0 : _a.nextContinuationData) === null || _b === void 0 ? void 0 : _b.continuation,
|
|
30
60
|
};
|
|
31
61
|
};
|
|
32
|
-
MusicSearchResultParser.parseContinuationSearchResult = function (data,
|
|
62
|
+
MusicSearchResultParser.parseContinuationSearchResult = function (data, client) {
|
|
33
63
|
var shelf = data.continuationContents.musicShelfContinuation;
|
|
34
64
|
return {
|
|
35
|
-
data: MusicSearchResultParser.parseSearchResult(shelf.contents,
|
|
65
|
+
data: MusicSearchResultParser.parseSearchResult(shelf.contents, client),
|
|
36
66
|
continuation: shelf.continuations[0].nextContinuationData.continuation,
|
|
37
67
|
};
|
|
38
68
|
};
|
|
39
|
-
MusicSearchResultParser.
|
|
69
|
+
MusicSearchResultParser.parseTopResult = function (data, client) {
|
|
70
|
+
var top = data === null || data === void 0 ? void 0 : data.musicCardShelfRenderer;
|
|
71
|
+
if (!top)
|
|
72
|
+
return;
|
|
73
|
+
var _a = top.title.runs[0].navigationEndpoint, browseEndpoint = _a.browseEndpoint, watchEndpoint = _a.watchEndpoint;
|
|
74
|
+
var id = (watchEndpoint === null || watchEndpoint === void 0 ? void 0 : watchEndpoint.videoId) || (browseEndpoint === null || browseEndpoint === void 0 ? void 0 : browseEndpoint.browseId);
|
|
75
|
+
var type = (watchEndpoint === null || watchEndpoint === void 0 ? void 0 : watchEndpoint.watchEndpointMusicSupportedConfigs.watchEndpointMusicConfig.musicVideoType) || (browseEndpoint === null || browseEndpoint === void 0 ? void 0 : browseEndpoint.browseEndpointContextSupportedConfigs.browseEndpointContextMusicConfig.pageType);
|
|
76
|
+
var title = top.title.runs[0].text;
|
|
77
|
+
var thumbnail = top.thumbnail.musicThumbnailRenderer.thumbnail.thumbnails;
|
|
78
|
+
var topResult;
|
|
79
|
+
if (type === "MUSIC_VIDEO_TYPE_ATV") {
|
|
80
|
+
topResult = new MusicSongCompact({
|
|
81
|
+
client: client,
|
|
82
|
+
id: id,
|
|
83
|
+
title: title,
|
|
84
|
+
duration: getDuration(top.subtitle.runs.at(-1).text),
|
|
85
|
+
artists: this.parseArtists(top.subtitle.runs, client),
|
|
86
|
+
album: this.parseAlbum(top.subtitle.runs, client),
|
|
87
|
+
thumbnails: new Thumbnails().load(thumbnail),
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
else if (type === "MUSIC_VIDEO_TYPE_UGC" || type === "MUSIC_VIDEO_TYPE_OMV") {
|
|
91
|
+
topResult = new MusicVideoCompact({
|
|
92
|
+
client: client,
|
|
93
|
+
id: id,
|
|
94
|
+
title: title,
|
|
95
|
+
duration: getDuration(top.subtitle.runs.at(-1).text),
|
|
96
|
+
artists: this.parseArtists(top.subtitle.runs, client),
|
|
97
|
+
thumbnails: new Thumbnails().load(thumbnail),
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
else if (type === "MUSIC_PAGE_TYPE_ALBUM") {
|
|
101
|
+
topResult = new MusicAlbumCompact({
|
|
102
|
+
client: client,
|
|
103
|
+
id: id,
|
|
104
|
+
title: title,
|
|
105
|
+
artists: this.parseArtists(top.subtitle.runs, client),
|
|
106
|
+
thumbnails: new Thumbnails().load(thumbnail),
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
else if (type === "MUSIC_PAGE_TYPE_ARTIST") {
|
|
110
|
+
topResult = new MusicArtistCompact({
|
|
111
|
+
client: client,
|
|
112
|
+
id: id,
|
|
113
|
+
name: title,
|
|
114
|
+
thumbnails: new Thumbnails().load(thumbnail),
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
else if (type === "MUSIC_PAGE_TYPE_PLAYLIST") {
|
|
118
|
+
topResult = new MusicPlaylistCompact({
|
|
119
|
+
client: client,
|
|
120
|
+
id: id,
|
|
121
|
+
title: title,
|
|
122
|
+
channel: this.parseChannel(top.subtitle.runs, client),
|
|
123
|
+
thumbnails: new Thumbnails().load(thumbnail),
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
return topResult;
|
|
127
|
+
};
|
|
128
|
+
MusicSearchResultParser.parseSearchResult = function (shelfContents, client) {
|
|
40
129
|
var e_1, _a;
|
|
41
|
-
var rawContents = shelfContents
|
|
42
|
-
.filter(function (c) { return "musicResponsiveListItemRenderer" in c; })
|
|
43
|
-
.map(function (c) { return c.musicResponsiveListItemRenderer; });
|
|
130
|
+
var rawContents = shelfContents.filter(function (c) { return "musicResponsiveListItemRenderer" in c; });
|
|
44
131
|
var contents = [];
|
|
45
132
|
try {
|
|
46
133
|
for (var rawContents_1 = __values(rawContents), rawContents_1_1 = rawContents_1.next(); !rawContents_1_1.done; rawContents_1_1 = rawContents_1.next()) {
|
|
47
134
|
var c = rawContents_1_1.value;
|
|
48
|
-
var parsed =
|
|
135
|
+
var parsed = this.parseSearchItem(c, client);
|
|
49
136
|
if (parsed)
|
|
50
137
|
contents.push(parsed);
|
|
51
138
|
}
|
|
@@ -59,6 +146,126 @@ var MusicSearchResultParser = /** @class */ (function () {
|
|
|
59
146
|
}
|
|
60
147
|
return contents;
|
|
61
148
|
};
|
|
149
|
+
MusicSearchResultParser.parseSearchItem = function (content, client) {
|
|
150
|
+
var _a;
|
|
151
|
+
var item = content.musicResponsiveListItemRenderer;
|
|
152
|
+
var playEndpoint = (_a = item.overlay) === null || _a === void 0 ? void 0 : _a.musicItemThumbnailOverlayRenderer.content.musicPlayButtonRenderer.playNavigationEndpoint;
|
|
153
|
+
if (playEndpoint === null || playEndpoint === void 0 ? void 0 : playEndpoint.watchEndpoint) {
|
|
154
|
+
var pageType = playEndpoint.watchEndpoint.watchEndpointMusicSupportedConfigs
|
|
155
|
+
.watchEndpointMusicConfig.musicVideoType;
|
|
156
|
+
return this.parseVideoItem(item, pageType, client);
|
|
157
|
+
}
|
|
158
|
+
else if (playEndpoint === null || playEndpoint === void 0 ? void 0 : playEndpoint.watchPlaylistEndpoint.params) {
|
|
159
|
+
return this.parsePlaylistItem(item, client);
|
|
160
|
+
}
|
|
161
|
+
else if (playEndpoint === null || playEndpoint === void 0 ? void 0 : playEndpoint.watchPlaylistEndpoint) {
|
|
162
|
+
// TODO add podcast support, id starts with PL
|
|
163
|
+
if (playEndpoint.watchPlaylistEndpoint.playlistId.startsWith("OL")) {
|
|
164
|
+
return this.parseAlbumItem(item, client);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
return this.parseArtistItem(item, client);
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
MusicSearchResultParser.parseVideoItem = function (item, pageType, client) {
|
|
172
|
+
// TODO support other types
|
|
173
|
+
if (!["MUSIC_VIDEO_TYPE_ATV", "MUSIC_VIDEO_TYPE_UGC", "MUSIC_VIDEO_TYPE_OMV"].includes(pageType)) {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
var _a = __read(item.flexColumns.map(function (c) { return c.musicResponsiveListItemFlexColumnRenderer.text.runs; }), 2), topColumn = _a[0], bottomColumn = _a[1];
|
|
177
|
+
var id = topColumn[0].navigationEndpoint.watchEndpoint.videoId;
|
|
178
|
+
var title = topColumn[0].text;
|
|
179
|
+
var duration = getDuration(bottomColumn.at(-1).text) || undefined;
|
|
180
|
+
var thumbnails = new Thumbnails().load(item.thumbnail.musicThumbnailRenderer.thumbnail.thumbnails);
|
|
181
|
+
var artists = this.parseArtists(bottomColumn, client);
|
|
182
|
+
if (pageType === "MUSIC_VIDEO_TYPE_ATV") {
|
|
183
|
+
return new MusicSongCompact({
|
|
184
|
+
client: client,
|
|
185
|
+
id: id,
|
|
186
|
+
album: this.parseAlbum(bottomColumn, client),
|
|
187
|
+
title: title,
|
|
188
|
+
artists: artists,
|
|
189
|
+
thumbnails: thumbnails,
|
|
190
|
+
duration: duration,
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
else if (pageType === "MUSIC_VIDEO_TYPE_UGC" || pageType === "MUSIC_VIDEO_TYPE_OMV") {
|
|
194
|
+
return new MusicVideoCompact({ client: client, id: id, title: title, artists: artists, thumbnails: thumbnails, duration: duration });
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
MusicSearchResultParser.parsePlaylistItem = function (item, client) {
|
|
198
|
+
var _a = __read(item.flexColumns.map(function (c) { return c.musicResponsiveListItemFlexColumnRenderer.text.runs; }), 2), topColumn = _a[0], bottomColumn = _a[1];
|
|
199
|
+
var id = item.overlay.musicItemThumbnailOverlayRenderer.content.musicPlayButtonRenderer
|
|
200
|
+
.playNavigationEndpoint.watchPlaylistEndpoint.playlistId;
|
|
201
|
+
var title = topColumn[0].text;
|
|
202
|
+
var songCount = stripToInt(bottomColumn.at(-1).text) || undefined;
|
|
203
|
+
var thumbnails = new Thumbnails().load(item.thumbnail.musicThumbnailRenderer.thumbnail.thumbnails);
|
|
204
|
+
var channel = this.parseChannel(bottomColumn, client);
|
|
205
|
+
return new MusicPlaylistCompact({ client: client, id: id, title: title, thumbnails: thumbnails, songCount: songCount, channel: channel });
|
|
206
|
+
};
|
|
207
|
+
MusicSearchResultParser.parseAlbumItem = function (item, client) {
|
|
208
|
+
var _a = __read(item.flexColumns.map(function (c) { return c.musicResponsiveListItemFlexColumnRenderer.text.runs; }), 2), topColumn = _a[0], bottomColumn = _a[1];
|
|
209
|
+
var id = item.overlay.musicItemThumbnailOverlayRenderer.content.musicPlayButtonRenderer
|
|
210
|
+
.playNavigationEndpoint.watchPlaylistEndpoint.playlistId;
|
|
211
|
+
var title = topColumn[0].text;
|
|
212
|
+
var year = stripToInt(bottomColumn.at(-1).text) || undefined;
|
|
213
|
+
var thumbnails = new Thumbnails().load(item.thumbnail.musicThumbnailRenderer.thumbnail.thumbnails);
|
|
214
|
+
var artists = this.parseArtists(bottomColumn, client);
|
|
215
|
+
return new MusicAlbumCompact({ client: client, id: id, title: title, thumbnails: thumbnails, artists: artists, year: year });
|
|
216
|
+
};
|
|
217
|
+
MusicSearchResultParser.parseArtistItem = function (item, client) {
|
|
218
|
+
var _a = __read(item.flexColumns.map(function (c) { return c.musicResponsiveListItemFlexColumnRenderer.text.runs; }), 1), topColumn = _a[0];
|
|
219
|
+
var id = item.navigationEndpoint.browseEndpoint.browseId;
|
|
220
|
+
var name = topColumn[0].text;
|
|
221
|
+
var thumbnails = new Thumbnails().load(item.thumbnail.musicThumbnailRenderer.thumbnail.thumbnails);
|
|
222
|
+
return new MusicArtistCompact({ client: client, id: id, name: name, thumbnails: thumbnails });
|
|
223
|
+
};
|
|
224
|
+
MusicSearchResultParser.parseAlbum = function (items, client) {
|
|
225
|
+
var _a;
|
|
226
|
+
var albumRaw = items.find(function (r) {
|
|
227
|
+
var _a;
|
|
228
|
+
var pageType = (_a = r.navigationEndpoint) === null || _a === void 0 ? void 0 : _a.browseEndpoint.browseEndpointContextSupportedConfigs.browseEndpointContextMusicConfig.pageType;
|
|
229
|
+
return pageType === "MUSIC_PAGE_TYPE_ALBUM";
|
|
230
|
+
});
|
|
231
|
+
if (!albumRaw)
|
|
232
|
+
return;
|
|
233
|
+
var album = new MusicAlbumCompact({
|
|
234
|
+
client: client,
|
|
235
|
+
title: albumRaw.text,
|
|
236
|
+
id: (_a = albumRaw.navigationEndpoint) === null || _a === void 0 ? void 0 : _a.browseEndpoint.browseId,
|
|
237
|
+
});
|
|
238
|
+
return album;
|
|
239
|
+
};
|
|
240
|
+
MusicSearchResultParser.parseArtists = function (items, client) {
|
|
241
|
+
return this.parseArtistsOrChannel(items).map(function (r) {
|
|
242
|
+
var _a;
|
|
243
|
+
return new MusicBaseArtist({
|
|
244
|
+
client: client,
|
|
245
|
+
name: r.text,
|
|
246
|
+
id: (_a = r.navigationEndpoint) === null || _a === void 0 ? void 0 : _a.browseEndpoint.browseId,
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
};
|
|
250
|
+
MusicSearchResultParser.parseChannel = function (items, client) {
|
|
251
|
+
var _a;
|
|
252
|
+
var _b = __read(this.parseArtistsOrChannel(items), 1), channelRaw = _b[0];
|
|
253
|
+
if (!channelRaw)
|
|
254
|
+
return;
|
|
255
|
+
var channel = new MusicBaseChannel({
|
|
256
|
+
client: client,
|
|
257
|
+
name: channelRaw.text,
|
|
258
|
+
id: (_a = channelRaw.navigationEndpoint) === null || _a === void 0 ? void 0 : _a.browseEndpoint.browseId,
|
|
259
|
+
});
|
|
260
|
+
return channel;
|
|
261
|
+
};
|
|
262
|
+
MusicSearchResultParser.parseArtistsOrChannel = function (items) {
|
|
263
|
+
return items.filter(function (i) {
|
|
264
|
+
var _a;
|
|
265
|
+
var pageType = (_a = i.navigationEndpoint) === null || _a === void 0 ? void 0 : _a.browseEndpoint.browseEndpointContextSupportedConfigs.browseEndpointContextMusicConfig.pageType;
|
|
266
|
+
return (pageType === "MUSIC_PAGE_TYPE_ARTIST" || pageType == "MUSIC_PAGE_TYPE_USER_CHANNEL");
|
|
267
|
+
});
|
|
268
|
+
};
|
|
62
269
|
return MusicSearchResultParser;
|
|
63
270
|
}());
|
|
64
271
|
export { MusicSearchResultParser };
|
|
@@ -15,6 +15,7 @@ import { Base } from "../Base";
|
|
|
15
15
|
import { BaseChannelParser } from "./BaseChannelParser";
|
|
16
16
|
import { ChannelLive } from "./ChannelLive";
|
|
17
17
|
import { ChannelPlaylists } from "./ChannelPlaylists";
|
|
18
|
+
import { ChannelPosts } from "./ChannelPosts";
|
|
18
19
|
import { ChannelShorts } from "./ChannelShorts";
|
|
19
20
|
import { ChannelVideos } from "./ChannelVideos";
|
|
20
21
|
/** Represents a Youtube Channel */
|
|
@@ -28,6 +29,7 @@ var BaseChannel = /** @class */ (function (_super) {
|
|
|
28
29
|
_this.shorts = new ChannelShorts({ channel: _this, client: _this.client });
|
|
29
30
|
_this.live = new ChannelLive({ channel: _this, client: _this.client });
|
|
30
31
|
_this.playlists = new ChannelPlaylists({ channel: _this, client: _this.client });
|
|
32
|
+
_this.posts = new ChannelPosts({ channel: _this, client: _this.client });
|
|
31
33
|
return _this;
|
|
32
34
|
}
|
|
33
35
|
Object.defineProperty(BaseChannel.prototype, "url", {
|
|
@@ -12,13 +12,13 @@ var BaseChannelParser = /** @class */ (function () {
|
|
|
12
12
|
};
|
|
13
13
|
/** Parse tab data from request, tab name is ignored if it's a continuation data */
|
|
14
14
|
BaseChannelParser.parseTabData = function (name, data) {
|
|
15
|
-
var _a, _b, _c, _d, _e;
|
|
15
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
16
16
|
var tab = (_a = data.contents) === null || _a === void 0 ? void 0 : _a.twoColumnBrowseResultsRenderer.tabs.find(function (t) {
|
|
17
17
|
var _a;
|
|
18
18
|
return (((_a = t.tabRenderer) === null || _a === void 0 ? void 0 : _a.endpoint.browseEndpoint.params) ===
|
|
19
19
|
BaseChannelParser.TAB_TYPE_PARAMS[name]);
|
|
20
20
|
});
|
|
21
|
-
return (((_d = (_c = (_b = tab === null || tab === void 0 ? void 0 : tab.tabRenderer.content.sectionListRenderer) === null || _b === void 0 ? void 0 : _b.contents) === null || _c === void 0 ? void 0 : _c[0].itemSectionRenderer.contents[0].gridRenderer) === null || _d === void 0 ? void 0 : _d.items) || (tab === null || tab === void 0 ? void 0 : tab.tabRenderer.content.richGridRenderer.contents.map(function (c) { var _a; return ((_a = c.richItemRenderer) === null || _a === void 0 ? void 0 : _a.content) || c; })) || ((
|
|
21
|
+
return (((_d = (_c = (_b = tab === null || tab === void 0 ? void 0 : tab.tabRenderer.content.sectionListRenderer) === null || _b === void 0 ? void 0 : _b.contents) === null || _c === void 0 ? void 0 : _c[0].itemSectionRenderer.contents[0].gridRenderer) === null || _d === void 0 ? void 0 : _d.items) || ((_h = (_g = (_f = (_e = tab === null || tab === void 0 ? void 0 : tab.tabRenderer.content) === null || _e === void 0 ? void 0 : _e.sectionListRenderer) === null || _f === void 0 ? void 0 : _f.contents) === null || _g === void 0 ? void 0 : _g[0].itemSectionRenderer) === null || _h === void 0 ? void 0 : _h.contents) || (tab === null || tab === void 0 ? void 0 : tab.tabRenderer.content.richGridRenderer.contents.map(function (c) { var _a; return ((_a = c.richItemRenderer) === null || _a === void 0 ? void 0 : _a.content) || c; })) || ((_j = data.onResponseReceivedActions) === null || _j === void 0 ? void 0 : _j[0].appendContinuationItemsAction.continuationItems.map(function (c) { var _a; return ((_a = c.richItemRenderer) === null || _a === void 0 ? void 0 : _a.content) || c; })) || ((_k = data.onResponseReceivedEndpoints) === null || _k === void 0 ? void 0 : _k[0].appendContinuationItemsAction.continuationItems) ||
|
|
22
22
|
[]);
|
|
23
23
|
};
|
|
24
24
|
BaseChannelParser.TAB_TYPE_PARAMS = {
|
|
@@ -26,6 +26,7 @@ var BaseChannelParser = /** @class */ (function () {
|
|
|
26
26
|
shorts: "EgZzaG9ydHPyBgUKA5oBAA%3D%3D",
|
|
27
27
|
live: "EgdzdHJlYW1z8gYECgJ6AA%3D%3D",
|
|
28
28
|
playlists: "EglwbGF5bGlzdHPyBgQKAkIA",
|
|
29
|
+
posts: "EgVwb3N0c_IGBAoCSgA%3D",
|
|
29
30
|
};
|
|
30
31
|
return BaseChannelParser;
|
|
31
32
|
}());
|
|
@@ -47,7 +47,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
47
47
|
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
48
48
|
}
|
|
49
49
|
};
|
|
50
|
-
import { getContinuationFromItems
|
|
50
|
+
import { getContinuationFromItems } from "../../common";
|
|
51
51
|
import { Continuable } from "../Continuable";
|
|
52
52
|
import { PlaylistCompact } from "../PlaylistCompact";
|
|
53
53
|
import { I_END_POINT } from "../constants";
|
|
@@ -93,11 +93,19 @@ var ChannelPlaylists = /** @class */ (function (_super) {
|
|
|
93
93
|
response = _b.sent();
|
|
94
94
|
items = BaseChannelParser.parseTabData("playlists", response.data);
|
|
95
95
|
continuation = getContinuationFromItems(items);
|
|
96
|
-
data =
|
|
96
|
+
data = items.filter(function (i) { return "gridPlaylistRenderer" in i || "lockupViewModel" in i; });
|
|
97
97
|
return [2 /*return*/, {
|
|
98
98
|
continuation: continuation,
|
|
99
99
|
items: data.map(function (i) {
|
|
100
|
-
|
|
100
|
+
var playlist = new PlaylistCompact({
|
|
101
|
+
client: _this.client,
|
|
102
|
+
channel: _this.channel,
|
|
103
|
+
});
|
|
104
|
+
if (i.gridPlaylistRenderer)
|
|
105
|
+
playlist.load(i.gridPlaylistRenderer);
|
|
106
|
+
else if (i.lockupViewModel)
|
|
107
|
+
playlist.loadLockup(i.lockupViewModel);
|
|
108
|
+
return playlist;
|
|
101
109
|
}),
|
|
102
110
|
}];
|
|
103
111
|
}
|