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,111 @@
|
|
|
1
|
+
var __extends = (this && this.__extends) || (function () {
|
|
2
|
+
var extendStatics = function (d, b) {
|
|
3
|
+
extendStatics = Object.setPrototypeOf ||
|
|
4
|
+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
5
|
+
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
6
|
+
return extendStatics(d, b);
|
|
7
|
+
};
|
|
8
|
+
return function (d, b) {
|
|
9
|
+
extendStatics(d, b);
|
|
10
|
+
function __() { this.constructor = d; }
|
|
11
|
+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
12
|
+
};
|
|
13
|
+
})();
|
|
14
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
15
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
16
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
17
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
18
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
19
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
20
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
24
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
25
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
26
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
27
|
+
function step(op) {
|
|
28
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
29
|
+
while (_) try {
|
|
30
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
31
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
32
|
+
switch (op[0]) {
|
|
33
|
+
case 0: case 1: t = op; break;
|
|
34
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
35
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
36
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
37
|
+
default:
|
|
38
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
39
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
40
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
41
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
42
|
+
if (t[2]) _.ops.pop();
|
|
43
|
+
_.trys.pop(); continue;
|
|
44
|
+
}
|
|
45
|
+
op = body.call(thisArg, _);
|
|
46
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
47
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
import { getContinuationFromItems } from "../../common";
|
|
51
|
+
import { Continuable } from "../Continuable";
|
|
52
|
+
import { Post } from "../Post";
|
|
53
|
+
import { I_END_POINT } from "../constants";
|
|
54
|
+
import { BaseChannelParser } from "./BaseChannelParser";
|
|
55
|
+
/**
|
|
56
|
+
* {@link Continuable} of posts inside a {@link BaseChannel}
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```js
|
|
60
|
+
* const channel = await youtube.findOne(CHANNEL_NAME, {type: "channel"});
|
|
61
|
+
* await channel.posts.next();
|
|
62
|
+
* console.log(channel.posts.items) // first 30 posts
|
|
63
|
+
*
|
|
64
|
+
* let newPosts = await channel.posts.next();
|
|
65
|
+
* console.log(newPosts) // 30 loaded posts
|
|
66
|
+
* console.log(channel.posts.items) // first 60 posts
|
|
67
|
+
*
|
|
68
|
+
* await channel.posts.next(0); // load the rest of the posts in the channel
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
var ChannelPosts = /** @class */ (function (_super) {
|
|
72
|
+
__extends(ChannelPosts, _super);
|
|
73
|
+
/** @hidden */
|
|
74
|
+
function ChannelPosts(_a) {
|
|
75
|
+
var client = _a.client, channel = _a.channel;
|
|
76
|
+
var _this = _super.call(this, { client: client, strictContinuationCheck: true }) || this;
|
|
77
|
+
_this.channel = channel;
|
|
78
|
+
return _this;
|
|
79
|
+
}
|
|
80
|
+
ChannelPosts.prototype.fetch = function () {
|
|
81
|
+
var _a;
|
|
82
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
83
|
+
var params, response, items, continuation, data;
|
|
84
|
+
var _this = this;
|
|
85
|
+
return __generator(this, function (_b) {
|
|
86
|
+
switch (_b.label) {
|
|
87
|
+
case 0:
|
|
88
|
+
params = BaseChannelParser.TAB_TYPE_PARAMS.posts;
|
|
89
|
+
return [4 /*yield*/, this.client.http.post(I_END_POINT + "/browse", {
|
|
90
|
+
data: { browseId: (_a = this.channel) === null || _a === void 0 ? void 0 : _a.id, params: params, continuation: this.continuation },
|
|
91
|
+
})];
|
|
92
|
+
case 1:
|
|
93
|
+
response = _b.sent();
|
|
94
|
+
items = BaseChannelParser.parseTabData("posts", response.data);
|
|
95
|
+
continuation = getContinuationFromItems(items);
|
|
96
|
+
data = items
|
|
97
|
+
.map(function (i) { var _a, _b; return (_b = (_a = i.backstagePostThreadRenderer) === null || _a === void 0 ? void 0 : _a.post) === null || _b === void 0 ? void 0 : _b.backstagePostRenderer; })
|
|
98
|
+
.filter(function (i) { return i !== undefined; });
|
|
99
|
+
return [2 /*return*/, {
|
|
100
|
+
continuation: continuation,
|
|
101
|
+
items: data.map(function (i) {
|
|
102
|
+
return new Post({ client: _this.client, channel: _this.channel }).load(i);
|
|
103
|
+
}),
|
|
104
|
+
}];
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
};
|
|
109
|
+
return ChannelPosts;
|
|
110
|
+
}(Continuable));
|
|
111
|
+
export { ChannelPosts };
|
|
@@ -38,14 +38,16 @@ var BaseVideoParser = /** @class */ (function () {
|
|
|
38
38
|
});
|
|
39
39
|
// Like Count and Dislike Count
|
|
40
40
|
var topLevelButtons = videoInfo.videoActions.menuRenderer.topLevelButtons;
|
|
41
|
-
target.likeCount =
|
|
41
|
+
target.likeCount = topLevelButtons
|
|
42
|
+
? stripToInt(BaseVideoParser.parseButtonRenderer(topLevelButtons[0]))
|
|
43
|
+
: null;
|
|
42
44
|
// Tags and description
|
|
43
45
|
target.tags =
|
|
44
46
|
((_b = (_a = videoInfo.superTitleLink) === null || _a === void 0 ? void 0 : _a.runs) === null || _b === void 0 ? void 0 : _b.map(function (r) { return r.text.trim(); }).filter(function (t) { return t; })) || [];
|
|
45
47
|
target.description = videoInfo.videoDetails.shortDescription || "";
|
|
46
48
|
// related videos
|
|
47
49
|
var secondaryContents = (_c = data.response.contents.twoColumnWatchNextResults.secondaryResults) === null || _c === void 0 ? void 0 : _c.secondaryResults.results;
|
|
48
|
-
var itemSectionRenderer = (_d = secondaryContents.find(function (c) {
|
|
50
|
+
var itemSectionRenderer = (_d = secondaryContents === null || secondaryContents === void 0 ? void 0 : secondaryContents.find(function (c) {
|
|
49
51
|
return c.itemSectionRenderer;
|
|
50
52
|
})) === null || _d === void 0 ? void 0 : _d.itemSectionRenderer;
|
|
51
53
|
if (itemSectionRenderer)
|
|
@@ -83,6 +85,16 @@ var BaseVideoParser = /** @class */ (function () {
|
|
|
83
85
|
else if ("compactRadioRenderer" in data) {
|
|
84
86
|
return new PlaylistCompact({ client: client }).load(data.compactRadioRenderer);
|
|
85
87
|
}
|
|
88
|
+
else if ("lockupViewModel" in data) {
|
|
89
|
+
// new data structure for related contents
|
|
90
|
+
var type = data.lockupViewModel.contentType;
|
|
91
|
+
if (type === "LOCKUP_CONTENT_TYPE_VIDEO") {
|
|
92
|
+
return new VideoCompact({ client: client }).loadLockup(data.lockupViewModel);
|
|
93
|
+
}
|
|
94
|
+
else if (type === "LOCKUP_CONTENT_TYPE_PLAYLIST") {
|
|
95
|
+
return new PlaylistCompact({ client: client }).loadLockup(data.lockupViewModel);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
86
98
|
};
|
|
87
99
|
BaseVideoParser.parseRelatedFromSecondaryContent = function (secondaryContents, client) {
|
|
88
100
|
return secondaryContents
|
|
@@ -17,9 +17,9 @@ var ChannelParser = /** @class */ (function () {
|
|
|
17
17
|
function ChannelParser() {
|
|
18
18
|
}
|
|
19
19
|
ChannelParser.loadChannel = function (target, data) {
|
|
20
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j
|
|
20
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
21
21
|
var channelId, title, handle, description, avatar, subscriberCountText, videoCountText, tvBanner, mobileBanner, banner;
|
|
22
|
-
var
|
|
22
|
+
var _k = data.header, c4TabbedHeaderRenderer = _k.c4TabbedHeaderRenderer, pageHeaderRenderer = _k.pageHeaderRenderer;
|
|
23
23
|
if (c4TabbedHeaderRenderer) {
|
|
24
24
|
channelId = c4TabbedHeaderRenderer.channelId;
|
|
25
25
|
title = c4TabbedHeaderRenderer.title;
|
|
@@ -35,12 +35,16 @@ var ChannelParser = /** @class */ (function () {
|
|
|
35
35
|
data.contents.twoColumnBrowseResultsRenderer.tabs[0].tabRenderer.endpoint
|
|
36
36
|
.browseEndpoint.browseId;
|
|
37
37
|
title = pageHeaderRenderer.pageTitle;
|
|
38
|
-
var
|
|
39
|
-
var
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
38
|
+
var _l = pageHeaderRenderer.content.pageHeaderViewModel, metadata = _l.metadata, imageModel = _l.image, bannerModel = _l.banner, descriptionModel = _l.description;
|
|
39
|
+
var metadataParts = metadata.contentMetadataViewModel.metadataRows
|
|
40
|
+
.map(function (m) { return m.metadataParts; })
|
|
41
|
+
.flat();
|
|
42
|
+
var handlePart = metadataParts.find(function (m) { var _a; return (_a = m.text.styleRuns) === null || _a === void 0 ? void 0 : _a.some(function (s) { return "weightLabel" in s; }); });
|
|
43
|
+
var subscriberCountPart = metadataParts.find(function (m) { return m.accessibilityLabel; });
|
|
44
|
+
var videoCountPart = metadataParts.find(function (m) { var _a; return (_a = m.text.styleRuns) === null || _a === void 0 ? void 0 : _a.some(function (s) { return "startIndex" in s; }); });
|
|
45
|
+
handle = (_j = handlePart === null || handlePart === void 0 ? void 0 : handlePart.text) === null || _j === void 0 ? void 0 : _j.content;
|
|
46
|
+
videoCountText = videoCountPart === null || videoCountPart === void 0 ? void 0 : videoCountPart.text.content;
|
|
47
|
+
subscriberCountText = subscriberCountPart === null || subscriberCountPart === void 0 ? void 0 : subscriberCountPart.text.content;
|
|
44
48
|
avatar = imageModel.decoratedAvatarViewModel.avatar.avatarViewModel.image.sources;
|
|
45
49
|
banner = bannerModel === null || bannerModel === void 0 ? void 0 : bannerModel.imageBannerViewModel.image.sources;
|
|
46
50
|
description = descriptionModel === null || descriptionModel === void 0 ? void 0 : descriptionModel.descriptionPreviewViewModel.description.content;
|
|
@@ -67,6 +67,15 @@ var PlaylistCompact = /** @class */ (function (_super) {
|
|
|
67
67
|
PlaylistCompactParser.loadPlaylistCompact(this, data);
|
|
68
68
|
return this;
|
|
69
69
|
};
|
|
70
|
+
/**
|
|
71
|
+
* Load this instance with raw lockup data from Youtube
|
|
72
|
+
*
|
|
73
|
+
* @hidden
|
|
74
|
+
*/
|
|
75
|
+
PlaylistCompact.prototype.loadLockup = function (data) {
|
|
76
|
+
PlaylistCompactParser.loadLockupPlaylistCompact(this, data);
|
|
77
|
+
return this;
|
|
78
|
+
};
|
|
70
79
|
/**
|
|
71
80
|
* Get {@link Playlist} object based on current playlist id
|
|
72
81
|
*
|
|
@@ -22,6 +22,29 @@ var PlaylistCompactParser = /** @class */ (function () {
|
|
|
22
22
|
}
|
|
23
23
|
return target;
|
|
24
24
|
};
|
|
25
|
+
PlaylistCompactParser.loadLockupPlaylistCompact = function (target, data) {
|
|
26
|
+
var _a;
|
|
27
|
+
var lockupMetadataViewModel = data.metadata.lockupMetadataViewModel;
|
|
28
|
+
var channelMetadata = (_a = lockupMetadataViewModel.metadata.contentMetadataViewModel.metadataRows) === null || _a === void 0 ? void 0 : _a[0].metadataParts[0];
|
|
29
|
+
var thumbnailViewModel = data.contentImage.collectionThumbnailViewModel.primaryThumbnail.thumbnailViewModel;
|
|
30
|
+
if (channelMetadata === null || channelMetadata === void 0 ? void 0 : channelMetadata.text.commandRuns) {
|
|
31
|
+
// not a mix
|
|
32
|
+
var channel = new BaseChannel({
|
|
33
|
+
client: target.client,
|
|
34
|
+
name: channelMetadata.text.content,
|
|
35
|
+
id: channelMetadata.text.commandRuns[0].onTap.innertubeCommand.browseEndpoint
|
|
36
|
+
.browseId,
|
|
37
|
+
});
|
|
38
|
+
target.channel = channel;
|
|
39
|
+
}
|
|
40
|
+
target.id = data.contentId;
|
|
41
|
+
target.title = lockupMetadataViewModel.title.content;
|
|
42
|
+
target.videoCount =
|
|
43
|
+
stripToInt(thumbnailViewModel.overlays[0].thumbnailOverlayBadgeViewModel.thumbnailBadges[0]
|
|
44
|
+
.thumbnailBadgeViewModel.text) || 0;
|
|
45
|
+
target.thumbnails = new Thumbnails().load(thumbnailViewModel.image.sources);
|
|
46
|
+
return target;
|
|
47
|
+
};
|
|
25
48
|
return PlaylistCompactParser;
|
|
26
49
|
}());
|
|
27
50
|
export { PlaylistCompactParser };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
var __extends = (this && this.__extends) || (function () {
|
|
2
|
+
var extendStatics = function (d, b) {
|
|
3
|
+
extendStatics = Object.setPrototypeOf ||
|
|
4
|
+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
5
|
+
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
6
|
+
return extendStatics(d, b);
|
|
7
|
+
};
|
|
8
|
+
return function (d, b) {
|
|
9
|
+
extendStatics(d, b);
|
|
10
|
+
function __() { this.constructor = d; }
|
|
11
|
+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
12
|
+
};
|
|
13
|
+
})();
|
|
14
|
+
import { Base } from "../Base";
|
|
15
|
+
import { PostParser } from "./PostParser";
|
|
16
|
+
/** Represents a chat in a live stream */
|
|
17
|
+
var Post = /** @class */ (function (_super) {
|
|
18
|
+
__extends(Post, _super);
|
|
19
|
+
/** @hidden */
|
|
20
|
+
function Post(attr) {
|
|
21
|
+
var _this = _super.call(this, attr.client) || this;
|
|
22
|
+
Object.assign(_this, attr);
|
|
23
|
+
return _this;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Load this instance with raw data from Youtube
|
|
27
|
+
*
|
|
28
|
+
* @hidden
|
|
29
|
+
*/
|
|
30
|
+
Post.prototype.load = function (data) {
|
|
31
|
+
PostParser.loadPost(this, data);
|
|
32
|
+
return this;
|
|
33
|
+
};
|
|
34
|
+
return Post;
|
|
35
|
+
}(Base));
|
|
36
|
+
export { Post };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { BaseChannel } from "../BaseChannel";
|
|
2
|
+
var PostParser = /** @class */ (function () {
|
|
3
|
+
function PostParser() {
|
|
4
|
+
}
|
|
5
|
+
PostParser.loadPost = function (target, data) {
|
|
6
|
+
var _a, _b, _c, _d;
|
|
7
|
+
var postId = data.postId, authorText = data.authorText, authorThumbnail = data.authorThumbnail, authorEndpoint = data.authorEndpoint, contentText = data.contentText, publishedTimeText = data.publishedTimeText, voteCount = data.voteCount;
|
|
8
|
+
// Basic information
|
|
9
|
+
target.id = postId;
|
|
10
|
+
target.content = (_a = contentText === null || contentText === void 0 ? void 0 : contentText.runs) === null || _a === void 0 ? void 0 : _a.map(function (r) { return r.text; }).join("");
|
|
11
|
+
target.channel = new BaseChannel({
|
|
12
|
+
id: (_b = authorEndpoint === null || authorEndpoint === void 0 ? void 0 : authorEndpoint.browseEndpoint) === null || _b === void 0 ? void 0 : _b.browseId,
|
|
13
|
+
name: (_c = authorText.runs) === null || _c === void 0 ? void 0 : _c[0].text,
|
|
14
|
+
thumbnails: authorThumbnail.thumbnails,
|
|
15
|
+
client: target.client,
|
|
16
|
+
});
|
|
17
|
+
target.timestamp = (_d = publishedTimeText.runs[0]) === null || _d === void 0 ? void 0 : _d.text;
|
|
18
|
+
target.voteCount = voteCount.simpleText;
|
|
19
|
+
return target;
|
|
20
|
+
};
|
|
21
|
+
return PostParser;
|
|
22
|
+
}());
|
|
23
|
+
export { PostParser };
|
|
@@ -46,6 +46,16 @@ var SearchResultParser = /** @class */ (function () {
|
|
|
46
46
|
contents.push(new VideoCompact({ client: client }).load(c.videoRenderer));
|
|
47
47
|
else if ("channelRenderer" in c)
|
|
48
48
|
contents.push(new BaseChannel({ client: client }).load(c.channelRenderer));
|
|
49
|
+
else if ("lockupViewModel" in c) {
|
|
50
|
+
// new data structure for search result
|
|
51
|
+
var type = c.lockupViewModel.contentType;
|
|
52
|
+
if (type === "LOCKUP_CONTENT_TYPE_VIDEO") {
|
|
53
|
+
contents.push(new VideoCompact({ client: client }).loadLockup(c.lockupViewModel));
|
|
54
|
+
}
|
|
55
|
+
else if (type === "LOCKUP_CONTENT_TYPE_PLAYLIST") {
|
|
56
|
+
contents.push(new PlaylistCompact({ client: client }).loadLockup(c.lockupViewModel));
|
|
57
|
+
}
|
|
58
|
+
}
|
|
49
59
|
}
|
|
50
60
|
}
|
|
51
61
|
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
@@ -75,6 +75,15 @@ var VideoCompact = /** @class */ (function (_super) {
|
|
|
75
75
|
VideoCompactParser.loadVideoCompact(this, data);
|
|
76
76
|
return this;
|
|
77
77
|
};
|
|
78
|
+
/**
|
|
79
|
+
* Load this instance with raw lockup data from Youtube
|
|
80
|
+
*
|
|
81
|
+
* @hidden
|
|
82
|
+
*/
|
|
83
|
+
VideoCompact.prototype.loadLockup = function (data) {
|
|
84
|
+
VideoCompactParser.loadLockupVideoCompact(this, data);
|
|
85
|
+
return this;
|
|
86
|
+
};
|
|
78
87
|
/**
|
|
79
88
|
* Get {@link Video} object based on current video id
|
|
80
89
|
*
|
|
@@ -37,6 +37,33 @@ var VideoCompactParser = /** @class */ (function () {
|
|
|
37
37
|
target.viewCount = stripToInt((viewCountText === null || viewCountText === void 0 ? void 0 : viewCountText.simpleText) || (viewCountText === null || viewCountText === void 0 ? void 0 : viewCountText.runs[0].text));
|
|
38
38
|
return target;
|
|
39
39
|
};
|
|
40
|
+
VideoCompactParser.loadLockupVideoCompact = function (target, data) {
|
|
41
|
+
var _a, _b;
|
|
42
|
+
var lockupMetadataViewModel = data.metadata.lockupMetadataViewModel;
|
|
43
|
+
var decoratedAvatarViewModel = lockupMetadataViewModel.image.decoratedAvatarViewModel;
|
|
44
|
+
var thumbnailBadge = data.contentImage.thumbnailViewModel.overlays[0].thumbnailOverlayBadgeViewModel
|
|
45
|
+
.thumbnailBadges[0].thumbnailBadgeViewModel;
|
|
46
|
+
var metadataRows = lockupMetadataViewModel.metadata.contentMetadataViewModel.metadataRows;
|
|
47
|
+
var channel = new BaseChannel({
|
|
48
|
+
client: target.client,
|
|
49
|
+
name: metadataRows[0].metadataParts[0].text.content,
|
|
50
|
+
id: decoratedAvatarViewModel.rendererContext.commandContext.onTap.innertubeCommand
|
|
51
|
+
.browseEndpoint.browseId,
|
|
52
|
+
thumbnails: new Thumbnails().load(decoratedAvatarViewModel.avatar.avatarViewModel.image.sources),
|
|
53
|
+
});
|
|
54
|
+
var isLive = ((_a = thumbnailBadge.icon) === null || _a === void 0 ? void 0 : _a.sources[0].clientResource.imageName) === "LIVE";
|
|
55
|
+
target.channel = channel;
|
|
56
|
+
target.id = data.contentId;
|
|
57
|
+
target.title = lockupMetadataViewModel.title.content;
|
|
58
|
+
target.isLive = ((_b = thumbnailBadge.icon) === null || _b === void 0 ? void 0 : _b.sources[0].clientResource.imageName) === "LIVE";
|
|
59
|
+
target.duration = !isLive ? getDuration(thumbnailBadge.text) : null;
|
|
60
|
+
target.thumbnails = new Thumbnails().load(data.contentImage.thumbnailViewModel.image.sources);
|
|
61
|
+
target.viewCount = stripToInt(metadataRows[1].metadataParts[0].text.content);
|
|
62
|
+
target.uploadDate = !isLive
|
|
63
|
+
? metadataRows[1].metadataParts[metadataRows[1].metadataParts.length - 1].text.content
|
|
64
|
+
: undefined;
|
|
65
|
+
return target;
|
|
66
|
+
};
|
|
40
67
|
return VideoCompactParser;
|
|
41
68
|
}());
|
|
42
69
|
export { VideoCompactParser };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { HTTP, HTTPOptions
|
|
1
|
+
import { HTTP, HTTPOptions } from "../../common";
|
|
2
2
|
import { MusicAlbumCompact } from "../MusicAlbumCompact";
|
|
3
3
|
import { MusicArtistCompact } from "../MusicArtistCompact";
|
|
4
4
|
import { MusicLyrics } from "../MusicLyrics";
|
|
@@ -22,17 +22,13 @@ export declare class MusicClient {
|
|
|
22
22
|
* @param type Search type
|
|
23
23
|
*
|
|
24
24
|
*/
|
|
25
|
-
search(query: string): Promise<
|
|
26
|
-
search<T extends MusicSearchType>(query: string, type: T): Promise<MusicSearchResult<T>>;
|
|
25
|
+
search<T extends MusicSearchType>(query: string, type?: T): Promise<MusicSearchResult<T>>;
|
|
27
26
|
/**
|
|
28
27
|
* Searches for all video, song, album, playlist, or artist
|
|
29
28
|
*
|
|
30
29
|
* @param query The search query
|
|
31
30
|
*/
|
|
32
|
-
searchAll(query: string): Promise<
|
|
33
|
-
top?: MusicTopShelf;
|
|
34
|
-
shelves: Shelf<MusicVideoCompact[] | MusicAlbumCompact[] | MusicPlaylistCompact[] | MusicArtistCompact[]>[];
|
|
35
|
-
}>;
|
|
31
|
+
searchAll(query: string): Promise<MusicSearchResult>;
|
|
36
32
|
/**
|
|
37
33
|
* Get lyrics of a song
|
|
38
34
|
*
|
|
@@ -1,12 +1,15 @@
|
|
|
1
|
+
import { MusicAlbumCompact } from "../MusicAlbumCompact";
|
|
2
|
+
import { MusicArtistCompact } from "../MusicArtistCompact";
|
|
1
3
|
import { FetchResult, MusicContinuable, MusicContinuableConstructorParams } from "../MusicContinuable";
|
|
4
|
+
import { MusicPlaylistCompact } from "../MusicPlaylistCompact";
|
|
2
5
|
import { MusicSongCompact } from "../MusicSongCompact";
|
|
3
6
|
import { MusicVideoCompact } from "../MusicVideoCompact";
|
|
4
7
|
export declare enum MusicSearchTypeEnum {
|
|
5
8
|
Song = "song",
|
|
6
9
|
Video = "video"
|
|
7
10
|
}
|
|
8
|
-
export declare type MusicSearchType = "song" | "video" | MusicSearchTypeEnum;
|
|
9
|
-
export declare type MusicSearchResultItem<T =
|
|
11
|
+
export declare type MusicSearchType = "song" | "video" | MusicSearchTypeEnum | undefined;
|
|
12
|
+
export declare type MusicSearchResultItem<T = undefined> = T extends "song" ? MusicSongCompact : T extends "video" ? MusicVideoCompact : MusicVideoCompact | MusicAlbumCompact | MusicPlaylistCompact | MusicArtistCompact;
|
|
10
13
|
declare type MusicLyricsProperties = MusicContinuableConstructorParams & {
|
|
11
14
|
type?: MusicSearchType;
|
|
12
15
|
};
|
|
@@ -32,7 +35,7 @@ declare type MusicLyricsProperties = MusicContinuableConstructorParams & {
|
|
|
32
35
|
*
|
|
33
36
|
* @noInheritDoc
|
|
34
37
|
*/
|
|
35
|
-
export declare class MusicSearchResult<T extends MusicSearchType
|
|
38
|
+
export declare class MusicSearchResult<T extends MusicSearchType = undefined> extends MusicContinuable<MusicSearchResultItem<T>> {
|
|
36
39
|
private type;
|
|
37
40
|
/** @hidden */
|
|
38
41
|
constructor({ client, type }: MusicLyricsProperties);
|
|
@@ -44,7 +47,7 @@ export declare class MusicSearchResult<T extends MusicSearchType | undefined = "
|
|
|
44
47
|
*
|
|
45
48
|
* @hidden
|
|
46
49
|
*/
|
|
47
|
-
search(query: string, type
|
|
50
|
+
search(query: string, type?: MusicSearchType): Promise<MusicSearchResult<T>>;
|
|
48
51
|
protected fetch(): Promise<FetchResult<MusicSearchResultItem<T>>>;
|
|
49
52
|
}
|
|
50
53
|
export {};
|
|
@@ -1,13 +1,25 @@
|
|
|
1
1
|
import { YoutubeRawData } from "../../common";
|
|
2
2
|
import { MusicClient } from "../MusicClient";
|
|
3
|
-
import {
|
|
3
|
+
import { MusicSongCompact } from "../MusicSongCompact";
|
|
4
|
+
import { MusicVideoCompact } from "../MusicVideoCompact";
|
|
5
|
+
import { MusicSearchResultItem } from "./MusicSearchResult";
|
|
4
6
|
declare type ParseReturnType = {
|
|
5
7
|
data: MusicSearchResultItem[];
|
|
6
8
|
continuation: string | undefined;
|
|
7
9
|
};
|
|
8
10
|
export declare class MusicSearchResultParser {
|
|
9
|
-
static parseInitialSearchResult(data: YoutubeRawData,
|
|
10
|
-
static parseContinuationSearchResult(data: YoutubeRawData,
|
|
11
|
+
static parseInitialSearchResult(data: YoutubeRawData, client: MusicClient): ParseReturnType;
|
|
12
|
+
static parseContinuationSearchResult(data: YoutubeRawData, client: MusicClient): ParseReturnType;
|
|
13
|
+
private static parseTopResult;
|
|
11
14
|
private static parseSearchResult;
|
|
15
|
+
private static parseSearchItem;
|
|
16
|
+
static parseVideoItem(item: YoutubeRawData, pageType: string, client: MusicClient): MusicSongCompact | MusicVideoCompact | undefined;
|
|
17
|
+
private static parsePlaylistItem;
|
|
18
|
+
private static parseAlbumItem;
|
|
19
|
+
private static parseArtistItem;
|
|
20
|
+
private static parseAlbum;
|
|
21
|
+
private static parseArtists;
|
|
22
|
+
private static parseChannel;
|
|
23
|
+
private static parseArtistsOrChannel;
|
|
12
24
|
}
|
|
13
25
|
export {};
|
|
@@ -2,6 +2,7 @@ import { Thumbnails, YoutubeRawData } from "../../common";
|
|
|
2
2
|
import { Base, BaseProperties } from "../Base";
|
|
3
3
|
import { ChannelLive } from "./ChannelLive";
|
|
4
4
|
import { ChannelPlaylists } from "./ChannelPlaylists";
|
|
5
|
+
import { ChannelPosts } from "./ChannelPosts";
|
|
5
6
|
import { ChannelShorts } from "./ChannelShorts";
|
|
6
7
|
import { ChannelVideos } from "./ChannelVideos";
|
|
7
8
|
/** @hidden */
|
|
@@ -17,7 +18,7 @@ export declare class BaseChannel extends Base implements BaseChannelProperties {
|
|
|
17
18
|
/** The channel's name */
|
|
18
19
|
name: string;
|
|
19
20
|
/** The channel's handle start with @ */
|
|
20
|
-
handle
|
|
21
|
+
handle?: string;
|
|
21
22
|
/** The channel's description */
|
|
22
23
|
description?: string;
|
|
23
24
|
/** Thumbnails of this Channel */
|
|
@@ -36,6 +37,8 @@ export declare class BaseChannel extends Base implements BaseChannelProperties {
|
|
|
36
37
|
live: ChannelLive;
|
|
37
38
|
/** Continuable of playlists */
|
|
38
39
|
playlists: ChannelPlaylists;
|
|
40
|
+
/** Continuable of posts */
|
|
41
|
+
posts: ChannelPosts;
|
|
39
42
|
/** @hidden */
|
|
40
43
|
constructor(attr: BaseChannelProperties);
|
|
41
44
|
/** The URL of the channel page */
|
|
@@ -7,6 +7,7 @@ export declare class BaseChannelParser {
|
|
|
7
7
|
readonly shorts: "EgZzaG9ydHPyBgUKA5oBAA%3D%3D";
|
|
8
8
|
readonly live: "EgdzdHJlYW1z8gYECgJ6AA%3D%3D";
|
|
9
9
|
readonly playlists: "EglwbGF5bGlzdHPyBgQKAkIA";
|
|
10
|
+
readonly posts: "EgVwb3N0c_IGBAoCSgA%3D";
|
|
10
11
|
};
|
|
11
12
|
static loadBaseChannel(target: BaseChannel, data: YoutubeRawData): BaseChannel;
|
|
12
13
|
/** Parse tab data from request, tab name is ignored if it's a continuation data */
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Continuable, ContinuableConstructorParams, FetchResult } from "../Continuable";
|
|
2
|
+
import { Post } from "../Post";
|
|
3
|
+
import { BaseChannel } from "./BaseChannel";
|
|
4
|
+
declare type ConstructorParams = ContinuableConstructorParams & {
|
|
5
|
+
channel?: BaseChannel;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* {@link Continuable} of posts inside a {@link BaseChannel}
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```js
|
|
12
|
+
* const channel = await youtube.findOne(CHANNEL_NAME, {type: "channel"});
|
|
13
|
+
* await channel.posts.next();
|
|
14
|
+
* console.log(channel.posts.items) // first 30 posts
|
|
15
|
+
*
|
|
16
|
+
* let newPosts = await channel.posts.next();
|
|
17
|
+
* console.log(newPosts) // 30 loaded posts
|
|
18
|
+
* console.log(channel.posts.items) // first 60 posts
|
|
19
|
+
*
|
|
20
|
+
* await channel.posts.next(0); // load the rest of the posts in the channel
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export declare class ChannelPosts extends Continuable<Post> {
|
|
24
|
+
/** The channel this posts belongs to */
|
|
25
|
+
channel?: BaseChannel;
|
|
26
|
+
/** @hidden */
|
|
27
|
+
constructor({ client, channel }: ConstructorParams);
|
|
28
|
+
protected fetch(): Promise<FetchResult<Post>>;
|
|
29
|
+
}
|
|
30
|
+
export {};
|
|
@@ -29,6 +29,12 @@ export declare class PlaylistCompact extends Base implements PlaylistCompactProp
|
|
|
29
29
|
* @hidden
|
|
30
30
|
*/
|
|
31
31
|
load(data: YoutubeRawData): PlaylistCompact;
|
|
32
|
+
/**
|
|
33
|
+
* Load this instance with raw lockup data from Youtube
|
|
34
|
+
*
|
|
35
|
+
* @hidden
|
|
36
|
+
*/
|
|
37
|
+
loadLockup(data: YoutubeRawData): PlaylistCompact;
|
|
32
38
|
/**
|
|
33
39
|
* Get {@link Playlist} object based on current playlist id
|
|
34
40
|
*
|
|
@@ -2,4 +2,5 @@ import { YoutubeRawData } from "../../common";
|
|
|
2
2
|
import { PlaylistCompact } from "./PlaylistCompact";
|
|
3
3
|
export declare class PlaylistCompactParser {
|
|
4
4
|
static loadPlaylistCompact(target: PlaylistCompact, data: YoutubeRawData): PlaylistCompact;
|
|
5
|
+
static loadLockupPlaylistCompact(target: PlaylistCompact, data: YoutubeRawData): PlaylistCompact;
|
|
5
6
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { YoutubeRawData } from "../../common";
|
|
2
|
+
import { Base, BaseProperties } from "../Base";
|
|
3
|
+
import { BaseChannel } from "../BaseChannel";
|
|
4
|
+
/** @hidden */
|
|
5
|
+
interface PostProperties extends BaseProperties {
|
|
6
|
+
id?: string;
|
|
7
|
+
channel?: BaseChannel;
|
|
8
|
+
content?: string;
|
|
9
|
+
timestamp?: string;
|
|
10
|
+
voteCount?: string;
|
|
11
|
+
}
|
|
12
|
+
/** Represents a chat in a live stream */
|
|
13
|
+
export declare class Post extends Base implements PostProperties {
|
|
14
|
+
id?: string;
|
|
15
|
+
/** The channel who posted this post */
|
|
16
|
+
channel: BaseChannel;
|
|
17
|
+
/** The content of this post */
|
|
18
|
+
content: string;
|
|
19
|
+
/** Timestamp */
|
|
20
|
+
timestamp: string;
|
|
21
|
+
/** Vote count like '1.2K likes' */
|
|
22
|
+
voteCount: string;
|
|
23
|
+
/** @hidden */
|
|
24
|
+
constructor(attr: PostProperties);
|
|
25
|
+
/**
|
|
26
|
+
* Load this instance with raw data from Youtube
|
|
27
|
+
*
|
|
28
|
+
* @hidden
|
|
29
|
+
*/
|
|
30
|
+
load(data: YoutubeRawData): Post;
|
|
31
|
+
}
|
|
32
|
+
export {};
|
|
@@ -46,6 +46,12 @@ export declare class VideoCompact extends Base implements VideoCompactProperties
|
|
|
46
46
|
* @hidden
|
|
47
47
|
*/
|
|
48
48
|
load(data: YoutubeRawData): VideoCompact;
|
|
49
|
+
/**
|
|
50
|
+
* Load this instance with raw lockup data from Youtube
|
|
51
|
+
*
|
|
52
|
+
* @hidden
|
|
53
|
+
*/
|
|
54
|
+
loadLockup(data: YoutubeRawData): VideoCompact;
|
|
49
55
|
/**
|
|
50
56
|
* Get {@link Video} object based on current video id
|
|
51
57
|
*
|
|
@@ -2,4 +2,5 @@ import { YoutubeRawData } from "../../common";
|
|
|
2
2
|
import { VideoCompact } from "./VideoCompact";
|
|
3
3
|
export declare class VideoCompactParser {
|
|
4
4
|
static loadVideoCompact(target: VideoCompact, data: YoutubeRawData): VideoCompact;
|
|
5
|
+
static loadLockupVideoCompact(target: VideoCompact, data: YoutubeRawData): VideoCompact;
|
|
5
6
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "youtubei",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
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",
|