youtubei 0.0.1-rc.3 → 0.0.1-rc.30
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/README.md +6 -5
- package/dist/classes/Base.d.ts +10 -0
- package/dist/classes/{client/types.js → Base.js} +3 -0
- package/dist/classes/BaseVideo.d.ts +59 -0
- package/dist/classes/BaseVideo.js +121 -0
- package/dist/classes/Channel.d.ts +27 -31
- package/dist/classes/Channel.js +59 -135
- package/dist/classes/ChannelCompact.d.ts +74 -23
- package/dist/classes/ChannelCompact.js +114 -103
- package/dist/classes/Chat.d.ts +29 -0
- package/dist/classes/Chat.js +31 -0
- package/dist/classes/Client.d.ts +49 -0
- package/dist/classes/Client.js +97 -0
- package/dist/classes/Comment.d.ts +50 -0
- package/dist/classes/Comment.js +84 -0
- package/dist/classes/LiveVideo.d.ts +47 -0
- package/dist/classes/LiveVideo.js +94 -0
- package/dist/classes/MixPlaylist.d.ts +32 -0
- package/dist/classes/MixPlaylist.js +44 -0
- package/dist/classes/Playlist.d.ts +35 -18
- package/dist/classes/Playlist.js +80 -116
- package/dist/classes/PlaylistCompact.d.ts +27 -15
- package/dist/classes/PlaylistCompact.js +42 -46
- package/dist/classes/Reply.d.ts +38 -0
- package/dist/classes/Reply.js +35 -0
- package/dist/classes/SearchResult.d.ts +52 -8
- package/dist/classes/SearchResult.js +101 -122
- package/dist/classes/Thumbnails.d.ts +42 -0
- package/dist/classes/Thumbnails.js +66 -0
- package/dist/classes/Video.d.ts +44 -37
- package/dist/classes/Video.js +74 -83
- package/dist/classes/VideoCompact.d.ts +38 -19
- package/dist/classes/VideoCompact.js +53 -53
- package/dist/classes/index.d.ts +10 -2
- package/dist/classes/index.js +20 -4
- package/dist/common/HTTP.d.ts +26 -0
- package/dist/common/HTTP.js +85 -0
- package/dist/common/decorators.js +6 -26
- package/dist/common/helper.d.ts +4 -0
- package/dist/common/helper.js +37 -18
- package/dist/common/index.d.ts +2 -1
- package/dist/common/index.js +5 -3
- package/dist/common/mixins.d.ts +2 -0
- package/dist/common/mixins.js +12 -0
- package/dist/common/types.d.ts +0 -5
- package/dist/constants.d.ts +5 -2
- package/dist/constants.js +6 -3
- package/package.json +23 -20
- package/.prettierrc +0 -8
- package/.vscode/settings.json +0 -4
- package/CHANGELOG.md +0 -6
- package/debug.log +0 -47
- package/dist/classes/BaseCompact.d.ts +0 -10
- package/dist/classes/BaseCompact.js +0 -27
- package/dist/classes/client/Client.d.ts +0 -23
- package/dist/classes/client/Client.js +0 -128
- package/dist/classes/client/index.d.ts +0 -2
- package/dist/classes/client/index.js +0 -19
- package/dist/classes/client/types.d.ts +0 -12
- package/dist/common/axios.d.ts +0 -4
- package/dist/common/axios.js +0 -44
- package/jest.config.js +0 -5
package/dist/classes/Video.js
CHANGED
|
@@ -1,93 +1,84 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
};
|
|
11
|
-
return __assign.apply(this, arguments);
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
12
10
|
};
|
|
13
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
12
|
+
const _1 = require(".");
|
|
13
|
+
const common_1 = require("../common");
|
|
14
|
+
const constants_1 = require("../constants");
|
|
15
|
+
/** Represents a Video, usually returned from `client.getVideo()` */
|
|
16
|
+
class Video extends _1.BaseVideo {
|
|
17
|
+
/** @hidden */
|
|
18
|
+
constructor(video = {}) {
|
|
19
|
+
super();
|
|
20
|
+
/**
|
|
21
|
+
* Comments of this video
|
|
22
|
+
*
|
|
23
|
+
* You need to load the comment first by calling `video.nextComments()` as youtube doesn't send any comments data when loading the video (from `client.getVideo()`)
|
|
24
|
+
*/
|
|
25
|
+
this.comments = [];
|
|
21
26
|
Object.assign(this, video);
|
|
22
27
|
}
|
|
23
28
|
/**
|
|
24
|
-
* Load instance
|
|
29
|
+
* Load this instance with raw data from Youtube
|
|
25
30
|
*
|
|
26
|
-
* @
|
|
31
|
+
* @hidden
|
|
27
32
|
*/
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
this.id = videoInfo.videoDetails.videoId;
|
|
37
|
-
this.title = videoInfo.title.runs[0].text;
|
|
38
|
-
this.duration = +videoInfo.videoDetails.lengthSeconds || null;
|
|
39
|
-
this.uploadDate = videoInfo.dateText.simpleText;
|
|
40
|
-
this.viewCount = +videoInfo.videoDetails.viewCount;
|
|
41
|
-
this.isLiveContent = videoInfo.videoDetails.isLiveContent;
|
|
42
|
-
var thumbnails = videoInfo.videoDetails.thumbnail.thumbnails;
|
|
43
|
-
this.thumbnail = thumbnails[thumbnails.length - 1].url;
|
|
44
|
-
// Channel
|
|
45
|
-
var _f = videoInfo.owner.videoOwnerRenderer, title = _f.title, thumbnail = _f.thumbnail;
|
|
46
|
-
this.channel = new _1.Channel({
|
|
47
|
-
id: title.runs[0].navigationEndpoint.browseEndpoint.browseId,
|
|
48
|
-
name: title.runs[0].text,
|
|
49
|
-
thumbnails: thumbnail.thumbnails,
|
|
50
|
-
url: "https://www.youtube.com/channel/" + title.runs[0].navigationEndpoint.browseEndpoint.browseId,
|
|
51
|
-
});
|
|
52
|
-
// Like Count and Dislike Count
|
|
53
|
-
var topLevelButtons = videoInfo.videoActions.menuRenderer.topLevelButtons;
|
|
54
|
-
this.likeCount =
|
|
55
|
-
+((_a = topLevelButtons[0].toggleButtonRenderer.defaultText.accessibility) === null || _a === void 0 ? void 0 : _a.accessibilityData.label.replace(/[^0-9]/g, "")) || null;
|
|
56
|
-
this.dislikeCount =
|
|
57
|
-
+((_b = topLevelButtons[1].toggleButtonRenderer.defaultText.accessibility) === null || _b === void 0 ? void 0 : _b.accessibilityData.label.replace(/[^0-9]/g, "")) || null;
|
|
58
|
-
// Tags and description
|
|
59
|
-
this.tags =
|
|
60
|
-
((_d = (_c = videoInfo.superTitleLink) === null || _c === void 0 ? void 0 : _c.runs) === null || _d === void 0 ? void 0 : _d.reduce(function (tags, t) {
|
|
61
|
-
if (t.text.trim())
|
|
62
|
-
tags.push(t.text.trim());
|
|
63
|
-
return tags;
|
|
64
|
-
}, [])) || [];
|
|
65
|
-
this.description =
|
|
66
|
-
((_e = videoInfo.description) === null || _e === void 0 ? void 0 : _e.runs.map(function (d) { return d.text; }).join("")) || "";
|
|
67
|
-
// Up Next and related videos
|
|
68
|
-
this.related = [];
|
|
69
|
-
var secondaryContents = youtubeRawData[3].response.contents.twoColumnWatchNextResults.secondaryResults
|
|
70
|
-
.secondaryResults.results;
|
|
71
|
-
for (var _i = 0, secondaryContents_1 = secondaryContents; _i < secondaryContents_1.length; _i++) {
|
|
72
|
-
var secondaryContent = secondaryContents_1[_i];
|
|
73
|
-
if ("compactAutoplayRenderer" in secondaryContent) {
|
|
74
|
-
var content = secondaryContent.compactAutoplayRenderer.contents[0];
|
|
75
|
-
if ("compactVideoRenderer" in content) {
|
|
76
|
-
this.upNext = new _1.VideoCompact().load(content.compactVideoRenderer);
|
|
77
|
-
}
|
|
78
|
-
else if ("compactRadioRenderer" in content) {
|
|
79
|
-
this.upNext = new _1.PlaylistCompact().load(content.compactRadioRenderer);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
else if ("compactVideoRenderer" in secondaryContent) {
|
|
83
|
-
this.related.push(new _1.VideoCompact().load(secondaryContent.compactVideoRenderer));
|
|
84
|
-
}
|
|
85
|
-
else if ("compactRadioRenderer" in secondaryContent) {
|
|
86
|
-
this.related.push(new _1.PlaylistCompact().load(secondaryContent.compactRadioRenderer));
|
|
87
|
-
}
|
|
88
|
-
}
|
|
33
|
+
load(data) {
|
|
34
|
+
super.load(data);
|
|
35
|
+
this.comments = [];
|
|
36
|
+
// Duration
|
|
37
|
+
const videoInfo = _1.BaseVideo.parseRawData(data);
|
|
38
|
+
this.duration = +videoInfo.videoDetails.lengthSeconds;
|
|
39
|
+
const itemSectionRenderer = data[3].response.contents.twoColumnWatchNextResults.results.results.contents.find((c) => c.itemSectionRenderer).itemSectionRenderer;
|
|
40
|
+
this.commentContinuation = common_1.getContinuationFromItems(itemSectionRenderer.contents);
|
|
89
41
|
return this;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Load next 20 comments of the video, and push the loaded comments to {@link Video.comments}
|
|
45
|
+
* You can only load up to 2000 comments from a video, this is due to the limitation from Youtube
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```js
|
|
49
|
+
* const video = await youtube.getVideo(VIDEO_ID);
|
|
50
|
+
* await video.nextComments();
|
|
51
|
+
* console.log(video.comments) // first 20 comments
|
|
52
|
+
*
|
|
53
|
+
* let newComments = await video.nextComments();
|
|
54
|
+
* console.log(newComments) // 20 loaded comments
|
|
55
|
+
* console.log(video.comments) // first 40 comments
|
|
56
|
+
*
|
|
57
|
+
* await video.nextComments(0); // load the rest of the comments in the video
|
|
58
|
+
* ```
|
|
59
|
+
*
|
|
60
|
+
* @param count How many times to load the next comments. Set 0 to load all comments (might take a while on a video with many comments!)
|
|
61
|
+
*
|
|
62
|
+
* @returns Loaded comments
|
|
63
|
+
*/
|
|
64
|
+
nextComments(count = 1) {
|
|
65
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
66
|
+
const newComments = [];
|
|
67
|
+
for (let i = 0; i < count || count == 0; i++) {
|
|
68
|
+
if (!this.commentContinuation)
|
|
69
|
+
break;
|
|
70
|
+
const response = yield this.client.http.post(`${constants_1.I_END_POINT}/next`, {
|
|
71
|
+
data: { continuation: this.commentContinuation },
|
|
72
|
+
});
|
|
73
|
+
const endpoints = response.data.onResponseReceivedEndpoints.pop();
|
|
74
|
+
const continuationItems = (endpoints.reloadContinuationItemsCommand || endpoints.appendContinuationItemsAction).continuationItems;
|
|
75
|
+
this.commentContinuation = common_1.getContinuationFromItems(continuationItems);
|
|
76
|
+
const comments = common_1.mapFilter(continuationItems, "commentThreadRenderer");
|
|
77
|
+
newComments.push(...comments.map((c) => new _1.Comment({ video: this, client: this.client }).load(c)));
|
|
78
|
+
}
|
|
79
|
+
this.comments.push(...newComments);
|
|
80
|
+
return newComments;
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
93
84
|
exports.default = Video;
|
|
@@ -1,32 +1,51 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { YoutubeRawData } from "../common";
|
|
2
|
+
import { Base, ChannelCompact, Thumbnails, BaseAttributes, Video, LiveVideo } from ".";
|
|
3
|
+
/** @hidden */
|
|
4
|
+
interface VideoCompactAttributes extends BaseAttributes {
|
|
5
5
|
title: string;
|
|
6
|
-
thumbnails:
|
|
6
|
+
thumbnails: Thumbnails;
|
|
7
7
|
duration: number | null;
|
|
8
|
-
|
|
9
|
-
channel?:
|
|
8
|
+
isLive: boolean;
|
|
9
|
+
channel?: ChannelCompact;
|
|
10
10
|
uploadDate?: string;
|
|
11
|
-
viewCount?: number;
|
|
11
|
+
viewCount?: number | null;
|
|
12
12
|
}
|
|
13
|
-
/**
|
|
14
|
-
|
|
15
|
-
*/
|
|
16
|
-
export default class VideoCompact extends BaseCompact implements VideoCompactAttributes {
|
|
13
|
+
/** Represent a compact video (e.g. from search result, playlist's videos, channel's videos) */
|
|
14
|
+
export default class VideoCompact extends Base implements VideoCompactAttributes {
|
|
15
|
+
/** The title of the video */
|
|
17
16
|
title: string;
|
|
17
|
+
/** Thumbnails of the video with different sizes */
|
|
18
|
+
thumbnails: Thumbnails;
|
|
19
|
+
/** Description of the video (not a full description, rather a preview / snippet) */
|
|
20
|
+
description: string;
|
|
21
|
+
/** The duration of this video in second, null if the video is live */
|
|
18
22
|
duration: number | null;
|
|
19
|
-
|
|
20
|
-
|
|
23
|
+
/** Whether this video is a live now or not */
|
|
24
|
+
isLive: boolean;
|
|
25
|
+
/** The channel who uploads this video */
|
|
26
|
+
channel?: ChannelCompact;
|
|
27
|
+
/** The date this video is uploaded at */
|
|
21
28
|
uploadDate?: string;
|
|
22
|
-
|
|
29
|
+
/** How many view does this video have, null if the view count is hidden */
|
|
30
|
+
viewCount?: number | null;
|
|
31
|
+
/** @hidden */
|
|
23
32
|
constructor(videoCompact?: Partial<VideoCompactAttributes>);
|
|
33
|
+
/** Whether this video is private / deleted or not, only useful in playlist's videos */
|
|
34
|
+
get isPrivateOrDeleted(): boolean;
|
|
24
35
|
/**
|
|
25
|
-
* Load instance
|
|
36
|
+
* Load this instance with raw data from Youtube
|
|
26
37
|
*
|
|
27
|
-
* @
|
|
38
|
+
* @hidden
|
|
28
39
|
*/
|
|
29
|
-
load(
|
|
30
|
-
|
|
40
|
+
load(data: YoutubeRawData): VideoCompact;
|
|
41
|
+
/**
|
|
42
|
+
* Get {@link Video} object based on current video id
|
|
43
|
+
*
|
|
44
|
+
* Equivalent to
|
|
45
|
+
* ```js
|
|
46
|
+
* client.getVideo(videoCompact.id);
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
getVideo(): Promise<Video | LiveVideo>;
|
|
31
50
|
}
|
|
32
51
|
export {};
|
|
@@ -1,71 +1,71 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
function __() { this.constructor = d; }
|
|
12
|
-
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
13
|
-
};
|
|
14
|
-
})();
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
15
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
return
|
|
12
|
+
const common_1 = require("../common");
|
|
13
|
+
const _1 = require(".");
|
|
14
|
+
/** Represent a compact video (e.g. from search result, playlist's videos, channel's videos) */
|
|
15
|
+
class VideoCompact extends _1.Base {
|
|
16
|
+
/** @hidden */
|
|
17
|
+
constructor(videoCompact = {}) {
|
|
18
|
+
super();
|
|
19
|
+
Object.assign(this, videoCompact);
|
|
20
|
+
}
|
|
21
|
+
/** Whether this video is private / deleted or not, only useful in playlist's videos */
|
|
22
|
+
get isPrivateOrDeleted() {
|
|
23
|
+
return !this.duration;
|
|
28
24
|
}
|
|
29
25
|
/**
|
|
30
|
-
* Load instance
|
|
26
|
+
* Load this instance with raw data from Youtube
|
|
31
27
|
*
|
|
32
|
-
* @
|
|
28
|
+
* @hidden
|
|
33
29
|
*/
|
|
34
|
-
|
|
35
|
-
var _a, _b
|
|
36
|
-
|
|
30
|
+
load(data) {
|
|
31
|
+
var _a, _b;
|
|
32
|
+
const { videoId, title, lengthText, thumbnail, ownerText, shortBylineText, publishedTimeText, viewCountText, badges, thumbnailOverlays, channelThumbnailSupportedRenderers, detailedMetadataSnippets, } = data;
|
|
37
33
|
this.id = videoId;
|
|
38
34
|
this.title = title.simpleText || ((_a = title.runs[0]) === null || _a === void 0 ? void 0 : _a.text);
|
|
39
|
-
this.thumbnails = thumbnail.thumbnails;
|
|
40
|
-
this.uploadDate = publishedTimeText ? publishedTimeText.simpleText
|
|
35
|
+
this.thumbnails = new _1.Thumbnails().load(thumbnail.thumbnails);
|
|
36
|
+
this.uploadDate = publishedTimeText === null || publishedTimeText === void 0 ? void 0 : publishedTimeText.simpleText;
|
|
37
|
+
this.description =
|
|
38
|
+
(detailedMetadataSnippets === null || detailedMetadataSnippets === void 0 ? void 0 : detailedMetadataSnippets[0].snippetText.runs.map((r) => r.text).join("")) || "";
|
|
41
39
|
this.duration =
|
|
42
|
-
common_1.getDuration((lengthText === null || lengthText === void 0 ? void 0 : lengthText.simpleText) || ((_b = thumbnailOverlays[0].thumbnailOverlayTimeStatusRenderer) === null || _b === void 0 ? void 0 : _b.text.simpleText) ||
|
|
40
|
+
common_1.getDuration((lengthText === null || lengthText === void 0 ? void 0 : lengthText.simpleText) || ((_b = thumbnailOverlays === null || thumbnailOverlays === void 0 ? void 0 : thumbnailOverlays[0].thumbnailOverlayTimeStatusRenderer) === null || _b === void 0 ? void 0 : _b.text.simpleText) ||
|
|
43
41
|
"") || null;
|
|
44
|
-
this.
|
|
45
|
-
? badges[0].metadataBadgeRenderer.style === "BADGE_STYLE_TYPE_LIVE_NOW"
|
|
46
|
-
: false;
|
|
42
|
+
this.isLive = !!((badges === null || badges === void 0 ? void 0 : badges[0].metadataBadgeRenderer.style) === "BADGE_STYLE_TYPE_LIVE_NOW");
|
|
47
43
|
// Channel
|
|
48
44
|
if (ownerText || shortBylineText) {
|
|
49
|
-
|
|
50
|
-
|
|
45
|
+
const { browseId } = (ownerText || shortBylineText).runs[0].navigationEndpoint.browseEndpoint;
|
|
46
|
+
const thumbnails = channelThumbnailSupportedRenderers === null || channelThumbnailSupportedRenderers === void 0 ? void 0 : channelThumbnailSupportedRenderers.channelThumbnailWithLinkRenderer.thumbnail.thumbnails;
|
|
47
|
+
this.channel = new _1.ChannelCompact({
|
|
51
48
|
id: browseId,
|
|
52
49
|
name: (ownerText || shortBylineText).runs[0].text,
|
|
53
|
-
|
|
50
|
+
thumbnails: thumbnails ? new _1.Thumbnails().load(thumbnails) : undefined,
|
|
51
|
+
client: this.client,
|
|
54
52
|
});
|
|
55
53
|
}
|
|
56
|
-
|
|
57
|
-
this.viewCount = +((_c = viewCountText === null || viewCountText === void 0 ? void 0 : viewCountText.simpleText) === null || _c === void 0 ? void 0 : _c.replace(/[^0-9]/g, "")) || undefined;
|
|
58
|
-
else
|
|
59
|
-
this.viewCount = +(viewCountText === null || viewCountText === void 0 ? void 0 : viewCountText.runs[0].text.replace(/[^0-9]/g, "")) || undefined;
|
|
54
|
+
this.viewCount = common_1.stripToInt((viewCountText === null || viewCountText === void 0 ? void 0 : viewCountText.simpleText) || (viewCountText === null || viewCountText === void 0 ? void 0 : viewCountText.runs[0].text));
|
|
60
55
|
return this;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Get {@link Video} object based on current video id
|
|
59
|
+
*
|
|
60
|
+
* Equivalent to
|
|
61
|
+
* ```js
|
|
62
|
+
* client.getVideo(videoCompact.id);
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
getVideo() {
|
|
66
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
67
|
+
return yield this.client.getVideo(this.id);
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
71
|
exports.default = VideoCompact;
|
package/dist/classes/index.d.ts
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
|
-
export { default as Client } from "./
|
|
2
|
-
export { default as
|
|
1
|
+
export { default as Client, Client as ClientTypes } from "./Client";
|
|
2
|
+
export { default as Base, BaseAttributes } from "./Base";
|
|
3
|
+
export { default as BaseVideo, BaseVideoAttributes } from "./BaseVideo";
|
|
3
4
|
export { default as VideoCompact } from "./VideoCompact";
|
|
5
|
+
export { default as Thumbnails } from "./Thumbnails";
|
|
4
6
|
export { default as Channel } from "./Channel";
|
|
7
|
+
export { default as ChannelCompact } from "./ChannelCompact";
|
|
8
|
+
export { default as Comment } from "./Comment";
|
|
9
|
+
export { default as Reply } from "./Reply";
|
|
10
|
+
export { default as Chat } from "./Chat";
|
|
5
11
|
export { default as PlaylistCompact } from "./PlaylistCompact";
|
|
6
12
|
export { default as Playlist } from "./Playlist";
|
|
7
13
|
export { default as Video } from "./Video";
|
|
14
|
+
export { default as LiveVideo } from "./LiveVideo";
|
|
8
15
|
export { default as SearchResult } from "./SearchResult";
|
|
16
|
+
export { default as MixPlaylist } from "./MixPlaylist";
|
package/dist/classes/index.js
CHANGED
|
@@ -3,20 +3,36 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.SearchResult = exports.Video = exports.Playlist = exports.PlaylistCompact = exports.Channel = exports.VideoCompact = exports.
|
|
7
|
-
var Client_1 = require("./
|
|
6
|
+
exports.MixPlaylist = exports.SearchResult = exports.LiveVideo = exports.Video = exports.Playlist = exports.PlaylistCompact = exports.Chat = exports.Reply = exports.Comment = exports.ChannelCompact = exports.Channel = exports.Thumbnails = exports.VideoCompact = exports.BaseVideo = exports.Base = exports.Client = void 0;
|
|
7
|
+
var Client_1 = require("./Client");
|
|
8
8
|
Object.defineProperty(exports, "Client", { enumerable: true, get: function () { return __importDefault(Client_1).default; } });
|
|
9
|
-
var
|
|
10
|
-
Object.defineProperty(exports, "
|
|
9
|
+
var Base_1 = require("./Base");
|
|
10
|
+
Object.defineProperty(exports, "Base", { enumerable: true, get: function () { return __importDefault(Base_1).default; } });
|
|
11
|
+
var BaseVideo_1 = require("./BaseVideo");
|
|
12
|
+
Object.defineProperty(exports, "BaseVideo", { enumerable: true, get: function () { return __importDefault(BaseVideo_1).default; } });
|
|
11
13
|
var VideoCompact_1 = require("./VideoCompact");
|
|
12
14
|
Object.defineProperty(exports, "VideoCompact", { enumerable: true, get: function () { return __importDefault(VideoCompact_1).default; } });
|
|
15
|
+
var Thumbnails_1 = require("./Thumbnails");
|
|
16
|
+
Object.defineProperty(exports, "Thumbnails", { enumerable: true, get: function () { return __importDefault(Thumbnails_1).default; } });
|
|
13
17
|
var Channel_1 = require("./Channel");
|
|
14
18
|
Object.defineProperty(exports, "Channel", { enumerable: true, get: function () { return __importDefault(Channel_1).default; } });
|
|
19
|
+
var ChannelCompact_1 = require("./ChannelCompact");
|
|
20
|
+
Object.defineProperty(exports, "ChannelCompact", { enumerable: true, get: function () { return __importDefault(ChannelCompact_1).default; } });
|
|
21
|
+
var Comment_1 = require("./Comment");
|
|
22
|
+
Object.defineProperty(exports, "Comment", { enumerable: true, get: function () { return __importDefault(Comment_1).default; } });
|
|
23
|
+
var Reply_1 = require("./Reply");
|
|
24
|
+
Object.defineProperty(exports, "Reply", { enumerable: true, get: function () { return __importDefault(Reply_1).default; } });
|
|
25
|
+
var Chat_1 = require("./Chat");
|
|
26
|
+
Object.defineProperty(exports, "Chat", { enumerable: true, get: function () { return __importDefault(Chat_1).default; } });
|
|
15
27
|
var PlaylistCompact_1 = require("./PlaylistCompact");
|
|
16
28
|
Object.defineProperty(exports, "PlaylistCompact", { enumerable: true, get: function () { return __importDefault(PlaylistCompact_1).default; } });
|
|
17
29
|
var Playlist_1 = require("./Playlist");
|
|
18
30
|
Object.defineProperty(exports, "Playlist", { enumerable: true, get: function () { return __importDefault(Playlist_1).default; } });
|
|
19
31
|
var Video_1 = require("./Video");
|
|
20
32
|
Object.defineProperty(exports, "Video", { enumerable: true, get: function () { return __importDefault(Video_1).default; } });
|
|
33
|
+
var LiveVideo_1 = require("./LiveVideo");
|
|
34
|
+
Object.defineProperty(exports, "LiveVideo", { enumerable: true, get: function () { return __importDefault(LiveVideo_1).default; } });
|
|
21
35
|
var SearchResult_1 = require("./SearchResult");
|
|
22
36
|
Object.defineProperty(exports, "SearchResult", { enumerable: true, get: function () { return __importDefault(SearchResult_1).default; } });
|
|
37
|
+
var MixPlaylist_1 = require("./MixPlaylist");
|
|
38
|
+
Object.defineProperty(exports, "MixPlaylist", { enumerable: true, get: function () { return __importDefault(MixPlaylist_1).default; } });
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import https from "https";
|
|
3
|
+
import { YoutubeRawData } from "./types";
|
|
4
|
+
import { Client } from "../classes/Client";
|
|
5
|
+
interface Options extends https.RequestOptions {
|
|
6
|
+
params: Record<string, any>;
|
|
7
|
+
data: any;
|
|
8
|
+
headers: Record<string, string>;
|
|
9
|
+
}
|
|
10
|
+
export default class HTTP {
|
|
11
|
+
private _httpClient;
|
|
12
|
+
private _cookie;
|
|
13
|
+
private _defaultRequestOptions;
|
|
14
|
+
private _defaultClientOptions;
|
|
15
|
+
constructor({ cookie, requestOptions, youtubeClientOptions, https: useHttps, }: Client.ClientOptions);
|
|
16
|
+
/** Send GET request to Youtube */
|
|
17
|
+
get(path: string, options: Partial<Options>): Promise<YoutubeRawData>;
|
|
18
|
+
/** Send POST request to Youtube */
|
|
19
|
+
post(path: string, options: Partial<Options>): Promise<YoutubeRawData>;
|
|
20
|
+
/**
|
|
21
|
+
* Send request to Youtube
|
|
22
|
+
*/
|
|
23
|
+
private request;
|
|
24
|
+
private static returnPromise;
|
|
25
|
+
}
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
3
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
4
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
5
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
6
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
7
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
8
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
9
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
10
|
+
});
|
|
11
|
+
};
|
|
12
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
13
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
14
|
+
};
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
const https_1 = __importDefault(require("https"));
|
|
17
|
+
const http_1 = __importDefault(require("http"));
|
|
18
|
+
const zlib_1 = __importDefault(require("zlib"));
|
|
19
|
+
const querystring_1 = __importDefault(require("querystring"));
|
|
20
|
+
const constants_1 = require("../constants");
|
|
21
|
+
class HTTP {
|
|
22
|
+
constructor({ cookie, requestOptions, youtubeClientOptions, https: useHttps, }) {
|
|
23
|
+
this._cookie = cookie;
|
|
24
|
+
this._defaultRequestOptions = requestOptions;
|
|
25
|
+
this._defaultClientOptions = youtubeClientOptions;
|
|
26
|
+
this._httpClient = useHttps ? https_1.default : http_1.default;
|
|
27
|
+
}
|
|
28
|
+
/** Send GET request to Youtube */
|
|
29
|
+
get(path, options) {
|
|
30
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
31
|
+
options = Object.assign({ method: "GET", path }, options);
|
|
32
|
+
return yield this.request(options);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
/** Send POST request to Youtube */
|
|
36
|
+
post(path, options) {
|
|
37
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
38
|
+
options = Object.assign(Object.assign({ method: "POST", path }, options), { params: Object.assign({ key: constants_1.INNERTUBE_API_KEY }, options.params), data: Object.assign({ context: {
|
|
39
|
+
client: Object.assign({ clientName: "WEB", clientVersion: constants_1.INNERTUBE_CLIENT_VERSION }, this._defaultClientOptions),
|
|
40
|
+
} }, options.data) });
|
|
41
|
+
return yield this.request(options);
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Send request to Youtube
|
|
46
|
+
*/
|
|
47
|
+
request(partialOptions) {
|
|
48
|
+
return new Promise((resolve, reject) => {
|
|
49
|
+
const options = Object.assign(Object.assign(Object.assign({ hostname: constants_1.BASE_URL, port: 443 }, partialOptions), this._defaultRequestOptions), { path: `${partialOptions.path}?${querystring_1.default.stringify(partialOptions.params)}`, headers: Object.assign({ "x-youtube-client-version": constants_1.INNERTUBE_CLIENT_VERSION, "x-youtube-client-name": "1", "content-type": "application/json", "accept-encoding": "gzip", cookie: this._cookie }, partialOptions.headers) });
|
|
50
|
+
let body = options.data || "";
|
|
51
|
+
if (options.data)
|
|
52
|
+
body = JSON.stringify(body);
|
|
53
|
+
const request = this._httpClient.request(options, (res) => {
|
|
54
|
+
var _a, _b;
|
|
55
|
+
if ((_a = res.headers["set-cookie"]) === null || _a === void 0 ? void 0 : _a.length)
|
|
56
|
+
this._cookie = `${this._cookie} ${(_b = res.headers["set-cookie"]) === null || _b === void 0 ? void 0 : _b.map((c) => c.split(";").shift()).join(";")}`;
|
|
57
|
+
const gunzip = zlib_1.default.createGunzip();
|
|
58
|
+
res.pipe(gunzip);
|
|
59
|
+
const buffer = [];
|
|
60
|
+
gunzip
|
|
61
|
+
.on("data", (data) => {
|
|
62
|
+
buffer.push(data.toString());
|
|
63
|
+
})
|
|
64
|
+
.on("end", () => {
|
|
65
|
+
const data = JSON.parse(buffer.join("").toString());
|
|
66
|
+
HTTP.returnPromise({
|
|
67
|
+
status: res.statusCode,
|
|
68
|
+
headers: res.headers,
|
|
69
|
+
data,
|
|
70
|
+
}, resolve, reject);
|
|
71
|
+
})
|
|
72
|
+
.on("error", reject);
|
|
73
|
+
});
|
|
74
|
+
request.on("error", reject);
|
|
75
|
+
request.write(body);
|
|
76
|
+
request.end();
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
static returnPromise(response, resolve, reject) {
|
|
80
|
+
if (response.status === 500)
|
|
81
|
+
reject(response.data);
|
|
82
|
+
resolve(response);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
exports.default = HTTP;
|
|
@@ -1,34 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __extends = (this && this.__extends) || (function () {
|
|
3
|
-
var extendStatics = function (d, b) {
|
|
4
|
-
extendStatics = Object.setPrototypeOf ||
|
|
5
|
-
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
6
|
-
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
7
|
-
return extendStatics(d, b);
|
|
8
|
-
};
|
|
9
|
-
return function (d, b) {
|
|
10
|
-
extendStatics(d, b);
|
|
11
|
-
function __() { this.constructor = d; }
|
|
12
|
-
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
13
|
-
};
|
|
14
|
-
})();
|
|
15
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
3
|
exports.extendsBuiltIn = void 0;
|
|
17
4
|
function extendsBuiltIn() {
|
|
18
|
-
return
|
|
19
|
-
return
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
24
|
-
args[_i] = arguments[_i];
|
|
25
|
-
}
|
|
26
|
-
var _this = _super.call(this, args) || this;
|
|
27
|
-
Object.setPrototypeOf(_this, target.prototype);
|
|
28
|
-
return _this;
|
|
5
|
+
return (target) => {
|
|
6
|
+
return class extends target {
|
|
7
|
+
constructor(...args) {
|
|
8
|
+
super(args);
|
|
9
|
+
Object.setPrototypeOf(this, target.prototype);
|
|
29
10
|
}
|
|
30
|
-
|
|
31
|
-
}(target));
|
|
11
|
+
};
|
|
32
12
|
};
|
|
33
13
|
}
|
|
34
14
|
exports.extendsBuiltIn = extendsBuiltIn;
|
package/dist/common/helper.d.ts
CHANGED
|
@@ -1,2 +1,6 @@
|
|
|
1
|
+
import { YoutubeRawData } from "./types";
|
|
1
2
|
export declare const getDuration: (s: string) => number;
|
|
2
3
|
export declare const getQueryParameter: (url: string, queryName: string) => string;
|
|
4
|
+
export declare const stripToInt: (string: string) => number | null;
|
|
5
|
+
export declare const getContinuationFromItems: (items: YoutubeRawData, accessors?: string[]) => string | undefined;
|
|
6
|
+
export declare const mapFilter: (items: YoutubeRawData, key: string) => YoutubeRawData;
|