youtubei 1.3.6 → 1.4.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 +18 -7
- package/dist/cjs/youtube/BaseVideo/BaseVideoParser.js +9 -4
- package/dist/cjs/youtube/BaseVideo/VideoCaptions.js +81 -0
- package/dist/cjs/youtube/BaseVideo/index.js +1 -0
- package/dist/cjs/youtube/Caption/Caption.js +17 -0
- package/dist/cjs/youtube/Caption/CaptionLanguage.js +17 -0
- package/dist/cjs/youtube/{Transcript/proto → Caption}/index.js +2 -1
- package/dist/cjs/youtube/Client/Client.js +16 -18
- package/dist/cjs/youtube/Comment/CommentParser.js +11 -12
- package/dist/cjs/youtube/LiveVideo/LiveVideo.js +15 -15
- package/dist/cjs/youtube/LiveVideo/LiveVideoParser.js +1 -1
- package/dist/cjs/youtube/Video/Video.js +4 -6
- package/dist/cjs/youtube/Video/VideoParser.js +5 -5
- package/dist/cjs/youtube/VideoCompact/VideoCompact.js +2 -2
- package/dist/cjs/youtube/VideoCompact/VideoCompactParser.js +9 -5
- package/dist/cjs/youtube/index.js +0 -1
- package/dist/esm/common/shared/HTTP/HTTP.js +59 -12
- package/dist/esm/youtube/BaseVideo/BaseVideoParser.js +9 -4
- package/dist/esm/youtube/BaseVideo/VideoCaptions.js +133 -0
- package/dist/esm/youtube/BaseVideo/index.js +1 -0
- package/dist/esm/youtube/Caption/Caption.js +19 -0
- package/dist/esm/youtube/Caption/CaptionLanguage.js +15 -0
- package/dist/esm/youtube/Caption/index.js +2 -0
- package/dist/esm/youtube/Client/Client.js +21 -24
- package/dist/esm/youtube/Comment/CommentParser.js +11 -12
- package/dist/esm/youtube/LiveVideo/LiveVideo.js +15 -15
- package/dist/esm/youtube/LiveVideo/LiveVideoParser.js +1 -1
- package/dist/esm/youtube/Video/Video.js +5 -7
- package/dist/esm/youtube/Video/VideoParser.js +6 -6
- package/dist/esm/youtube/VideoCompact/VideoCompact.js +2 -2
- package/dist/esm/youtube/VideoCompact/VideoCompactParser.js +9 -5
- package/dist/esm/youtube/index.js +0 -1
- package/dist/typings/common/shared/HTTP/HTTP.d.ts +2 -2
- package/dist/typings/youtube/BaseVideo/BaseVideo.d.ts +3 -0
- package/dist/typings/youtube/BaseVideo/VideoCaptions.d.ts +40 -0
- package/dist/typings/youtube/BaseVideo/index.d.ts +1 -0
- package/dist/typings/youtube/Caption/Caption.d.ts +22 -0
- package/dist/typings/youtube/Caption/CaptionLanguage.d.ts +30 -0
- package/dist/typings/youtube/Caption/index.d.ts +2 -0
- package/dist/typings/youtube/Client/Client.d.ts +8 -3
- package/dist/typings/youtube/LiveVideo/LiveVideo.d.ts +5 -5
- package/dist/typings/youtube/Video/Video.d.ts +3 -6
- package/dist/typings/youtube/VideoCompact/VideoCompact.d.ts +2 -2
- package/dist/typings/youtube/index.d.ts +0 -1
- package/package.json +1 -1
- package/dist/cjs/youtube/Transcript/Transcript.js +0 -27
- package/dist/cjs/youtube/Transcript/TranscriptParser.js +0 -13
- package/dist/cjs/youtube/Transcript/index.js +0 -15
- package/dist/cjs/youtube/Transcript/proto/TranscriptParamsProto.js +0 -12
- package/dist/esm/youtube/Transcript/Transcript.js +0 -29
- package/dist/esm/youtube/Transcript/TranscriptParser.js +0 -13
- package/dist/esm/youtube/Transcript/index.js +0 -3
- package/dist/esm/youtube/Transcript/proto/TranscriptParamsProto.js +0 -2
- package/dist/esm/youtube/Transcript/proto/index.js +0 -1
- package/dist/typings/youtube/Transcript/Transcript.d.ts +0 -29
- package/dist/typings/youtube/Transcript/TranscriptParser.d.ts +0 -5
- package/dist/typings/youtube/Transcript/index.d.ts +0 -3
- package/dist/typings/youtube/Transcript/proto/TranscriptParamsProto.d.ts +0 -7
- package/dist/typings/youtube/Transcript/proto/index.d.ts +0 -1
|
@@ -13,6 +13,7 @@ import { getContinuationFromItems, stripToInt, Thumbnails } from "../../common";
|
|
|
13
13
|
import { BaseChannel } from "../BaseChannel";
|
|
14
14
|
import { PlaylistCompact } from "../PlaylistCompact";
|
|
15
15
|
import { VideoCompact } from "../VideoCompact";
|
|
16
|
+
import { VideoCaptions } from "./VideoCaptions";
|
|
16
17
|
var BaseVideoParser = /** @class */ (function () {
|
|
17
18
|
function BaseVideoParser() {
|
|
18
19
|
}
|
|
@@ -43,11 +44,15 @@ var BaseVideoParser = /** @class */ (function () {
|
|
|
43
44
|
((_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; })) || [];
|
|
44
45
|
target.description = videoInfo.videoDetails.shortDescription || "";
|
|
45
46
|
// related videos
|
|
46
|
-
var secondaryContents = (_c = data
|
|
47
|
+
var secondaryContents = (_c = data.response.contents.twoColumnWatchNextResults.secondaryResults) === null || _c === void 0 ? void 0 : _c.secondaryResults.results;
|
|
47
48
|
if (secondaryContents) {
|
|
48
49
|
target.related.items = BaseVideoParser.parseRelatedFromSecondaryContent(secondaryContents, target.client);
|
|
49
50
|
target.related.continuation = getContinuationFromItems(secondaryContents);
|
|
50
51
|
}
|
|
52
|
+
// captions
|
|
53
|
+
if (videoInfo.captions) {
|
|
54
|
+
target.captions = new VideoCaptions({ client: target.client, video: target }).load(videoInfo.captions.playerCaptionsTracklistRenderer);
|
|
55
|
+
}
|
|
51
56
|
return target;
|
|
52
57
|
};
|
|
53
58
|
BaseVideoParser.parseRelated = function (data, client) {
|
|
@@ -59,12 +64,12 @@ var BaseVideoParser = /** @class */ (function () {
|
|
|
59
64
|
return getContinuationFromItems(secondaryContents);
|
|
60
65
|
};
|
|
61
66
|
BaseVideoParser.parseRawData = function (data) {
|
|
62
|
-
var contents = data
|
|
67
|
+
var contents = data.response.contents.twoColumnWatchNextResults.results.results.contents;
|
|
63
68
|
var primaryInfo = contents.find(function (c) { return "videoPrimaryInfoRenderer" in c; })
|
|
64
69
|
.videoPrimaryInfoRenderer;
|
|
65
70
|
var secondaryInfo = contents.find(function (c) { return "videoSecondaryInfoRenderer" in c; }).videoSecondaryInfoRenderer;
|
|
66
|
-
var
|
|
67
|
-
return __assign(__assign(__assign({}, secondaryInfo), primaryInfo), { videoDetails: videoDetails });
|
|
71
|
+
var _a = data.playerResponse, videoDetails = _a.videoDetails, captions = _a.captions;
|
|
72
|
+
return __assign(__assign(__assign({}, secondaryInfo), primaryInfo), { videoDetails: videoDetails, captions: captions });
|
|
68
73
|
};
|
|
69
74
|
BaseVideoParser.parseCompactRenderer = function (data, client) {
|
|
70
75
|
if ("compactVideoRenderer" in data) {
|
|
@@ -0,0 +1,133 @@
|
|
|
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 { Base } from "../Base";
|
|
51
|
+
import { Caption, CaptionLanguage } from "../Caption";
|
|
52
|
+
/**
|
|
53
|
+
* Captions of a video
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```js
|
|
57
|
+
*
|
|
58
|
+
* console.log(result.captions.languages.map((l) => `${l.code} - ${l.name}`)); // printing out available languages for captions
|
|
59
|
+
*
|
|
60
|
+
* console.log(await result.captions.get("en")); // printing out captions of a specific language using language code
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
var VideoCaptions = /** @class */ (function (_super) {
|
|
64
|
+
__extends(VideoCaptions, _super);
|
|
65
|
+
/** @hidden */
|
|
66
|
+
function VideoCaptions(_a) {
|
|
67
|
+
var video = _a.video, client = _a.client;
|
|
68
|
+
var _this = _super.call(this, client) || this;
|
|
69
|
+
_this.video = video;
|
|
70
|
+
_this.languages = [];
|
|
71
|
+
return _this;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Load this instance with raw data from Youtube
|
|
75
|
+
*
|
|
76
|
+
* @hidden
|
|
77
|
+
*/
|
|
78
|
+
VideoCaptions.prototype.load = function (data) {
|
|
79
|
+
var _this = this;
|
|
80
|
+
var captionTracks = data.captionTracks;
|
|
81
|
+
if (captionTracks) {
|
|
82
|
+
this.languages = captionTracks.map(function (track) {
|
|
83
|
+
return new CaptionLanguage({
|
|
84
|
+
captions: _this,
|
|
85
|
+
name: track.name.simpleText,
|
|
86
|
+
code: track.languageCode,
|
|
87
|
+
isTranslatable: !!track.isTranslatable,
|
|
88
|
+
url: track.baseUrl,
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
return this;
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* Get captions of a specific language or a translation of a specific language
|
|
96
|
+
*/
|
|
97
|
+
VideoCaptions.prototype.get = function (languageCode, translationLanguageCode) {
|
|
98
|
+
var _a, _b;
|
|
99
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
100
|
+
var url, params, response, captions;
|
|
101
|
+
return __generator(this, function (_c) {
|
|
102
|
+
switch (_c.label) {
|
|
103
|
+
case 0:
|
|
104
|
+
if (!languageCode)
|
|
105
|
+
languageCode = this.client.options.youtubeClientOptions.hl;
|
|
106
|
+
url = (_a = this.languages.find(function (l) { return l.code.toUpperCase() === (languageCode === null || languageCode === void 0 ? void 0 : languageCode.toUpperCase()); })) === null || _a === void 0 ? void 0 : _a.url;
|
|
107
|
+
if (!url)
|
|
108
|
+
return [2 /*return*/, undefined];
|
|
109
|
+
params = { fmt: "json3" };
|
|
110
|
+
if (translationLanguageCode)
|
|
111
|
+
params["tlang"] = translationLanguageCode;
|
|
112
|
+
return [4 /*yield*/, this.client.http.get(url, { params: params })];
|
|
113
|
+
case 1:
|
|
114
|
+
response = _c.sent();
|
|
115
|
+
captions = (_b = response.data.events) === null || _b === void 0 ? void 0 : _b.reduce(function (curr, e) {
|
|
116
|
+
var _a;
|
|
117
|
+
if (e.segs === undefined)
|
|
118
|
+
return curr;
|
|
119
|
+
curr.push(new Caption({
|
|
120
|
+
duration: e.dDurationMs,
|
|
121
|
+
start: e.tStartMs,
|
|
122
|
+
text: (_a = e.segs) === null || _a === void 0 ? void 0 : _a.map(function (s) { return Object.values(s).join(""); }).join(" "),
|
|
123
|
+
}));
|
|
124
|
+
return curr;
|
|
125
|
+
}, []);
|
|
126
|
+
return [2 /*return*/, captions];
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
};
|
|
131
|
+
return VideoCaptions;
|
|
132
|
+
}(Base));
|
|
133
|
+
export { VideoCaptions };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represent a single video caption entry
|
|
3
|
+
*/
|
|
4
|
+
var Caption = /** @class */ (function () {
|
|
5
|
+
/** @hidden */
|
|
6
|
+
function Caption(attr) {
|
|
7
|
+
Object.assign(this, attr);
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(Caption.prototype, "end", {
|
|
10
|
+
/** transcript end time in milliseconds */
|
|
11
|
+
get: function () {
|
|
12
|
+
return this.start + this.duration;
|
|
13
|
+
},
|
|
14
|
+
enumerable: false,
|
|
15
|
+
configurable: true
|
|
16
|
+
});
|
|
17
|
+
return Caption;
|
|
18
|
+
}());
|
|
19
|
+
export { Caption };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents a caption language option
|
|
3
|
+
*/
|
|
4
|
+
var CaptionLanguage = /** @class */ (function () {
|
|
5
|
+
/** @hidden */
|
|
6
|
+
function CaptionLanguage(attr) {
|
|
7
|
+
Object.assign(this, attr);
|
|
8
|
+
}
|
|
9
|
+
/** Get the captions of this language using the url */
|
|
10
|
+
CaptionLanguage.prototype.get = function (translationLanguageCode) {
|
|
11
|
+
return this.captions.get(this.code, translationLanguageCode);
|
|
12
|
+
};
|
|
13
|
+
return CaptionLanguage;
|
|
14
|
+
}());
|
|
15
|
+
export { CaptionLanguage };
|
|
@@ -51,15 +51,14 @@ import { LiveVideo } from "../LiveVideo";
|
|
|
51
51
|
import { MixPlaylist } from "../MixPlaylist";
|
|
52
52
|
import { Playlist } from "../Playlist";
|
|
53
53
|
import { SearchResult } from "../SearchResult";
|
|
54
|
-
import { Transcript, TranscriptParamsProto } from "../Transcript";
|
|
55
54
|
import { Video } from "../Video";
|
|
56
55
|
import { BASE_URL, INNERTUBE_API_KEY, INNERTUBE_CLIENT_NAME, INNERTUBE_CLIENT_VERSION, I_END_POINT, WATCH_END_POINT, } from "../constants";
|
|
57
56
|
/** Youtube Client */
|
|
58
57
|
var Client = /** @class */ (function () {
|
|
59
58
|
function Client(options) {
|
|
60
59
|
if (options === void 0) { options = {}; }
|
|
61
|
-
|
|
62
|
-
this.http = new HTTP(__assign({ apiKey: INNERTUBE_API_KEY, baseUrl: BASE_URL, clientName: INNERTUBE_CLIENT_NAME, clientVersion: INNERTUBE_CLIENT_VERSION },
|
|
60
|
+
this.options = __assign(__assign({ initialCookie: "", fetchOptions: {} }, options), { youtubeClientOptions: __assign({ hl: "en", gl: "US" }, options.youtubeClientOptions) });
|
|
61
|
+
this.http = new HTTP(__assign({ apiKey: INNERTUBE_API_KEY, baseUrl: BASE_URL, clientName: INNERTUBE_CLIENT_NAME, clientVersion: INNERTUBE_CLIENT_VERSION }, this.options));
|
|
63
62
|
}
|
|
64
63
|
/**
|
|
65
64
|
* Searches for videos / playlists / channels
|
|
@@ -136,7 +135,7 @@ var Client = /** @class */ (function () {
|
|
|
136
135
|
Client.prototype.getVideo = function (videoId) {
|
|
137
136
|
var _a;
|
|
138
137
|
return __awaiter(this, void 0, void 0, function () {
|
|
139
|
-
var response;
|
|
138
|
+
var response, data;
|
|
140
139
|
return __generator(this, function (_b) {
|
|
141
140
|
switch (_b.label) {
|
|
142
141
|
case 0: return [4 /*yield*/, this.http.get("" + WATCH_END_POINT, {
|
|
@@ -144,13 +143,15 @@ var Client = /** @class */ (function () {
|
|
|
144
143
|
})];
|
|
145
144
|
case 1:
|
|
146
145
|
response = _b.sent();
|
|
147
|
-
|
|
148
|
-
response.data
|
|
146
|
+
data = Array.isArray(response.data)
|
|
147
|
+
? response.data.reduce(function (prev, curr) { return (__assign(__assign({}, prev), curr)); }, {})
|
|
148
|
+
: response.data;
|
|
149
|
+
if (!((_a = data.response) === null || _a === void 0 ? void 0 : _a.contents) || data.playerResponse.playabilityStatus.status === "ERROR") {
|
|
149
150
|
return [2 /*return*/, undefined];
|
|
150
151
|
}
|
|
151
|
-
return [2 /*return*/, (!
|
|
152
|
-
? new Video({ client: this }).load(
|
|
153
|
-
: new LiveVideo({ client: this }).load(
|
|
152
|
+
return [2 /*return*/, (!data.playerResponse.playabilityStatus.liveStreamability
|
|
153
|
+
? new Video({ client: this }).load(data)
|
|
154
|
+
: new LiveVideo({ client: this }).load(data))];
|
|
154
155
|
}
|
|
155
156
|
});
|
|
156
157
|
});
|
|
@@ -175,23 +176,19 @@ var Client = /** @class */ (function () {
|
|
|
175
176
|
});
|
|
176
177
|
});
|
|
177
178
|
};
|
|
178
|
-
|
|
179
|
+
/**
|
|
180
|
+
* Get video transcript / caption by video id
|
|
181
|
+
*/
|
|
182
|
+
Client.prototype.getVideoTranscript = function (videoId, languageCode) {
|
|
183
|
+
var _a;
|
|
179
184
|
return __awaiter(this, void 0, void 0, function () {
|
|
180
|
-
var
|
|
181
|
-
return __generator(this, function (
|
|
182
|
-
switch (
|
|
183
|
-
case 0:
|
|
184
|
-
bufferParams = TranscriptParamsProto.encode({ videoId: videoId }).finish();
|
|
185
|
-
return [4 /*yield*/, this.http.post(I_END_POINT + "/get_transcript", {
|
|
186
|
-
data: { params: Buffer.from(bufferParams).toString("base64") },
|
|
187
|
-
})];
|
|
185
|
+
var video;
|
|
186
|
+
return __generator(this, function (_b) {
|
|
187
|
+
switch (_b.label) {
|
|
188
|
+
case 0: return [4 /*yield*/, this.getVideo(videoId)];
|
|
188
189
|
case 1:
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
return [2 /*return*/, undefined];
|
|
192
|
-
return [2 /*return*/, response.data.actions[0].updateEngagementPanelAction.content.transcriptRenderer.body.transcriptBodyRenderer.cueGroups
|
|
193
|
-
.map(function (t) { return t.transcriptCueGroupRenderer.cues[0].transcriptCueRenderer; })
|
|
194
|
-
.map(function (t) { return new Transcript().load(t); })];
|
|
190
|
+
video = _b.sent();
|
|
191
|
+
return [2 /*return*/, (_a = video === null || video === void 0 ? void 0 : video.captions) === null || _a === void 0 ? void 0 : _a.get(languageCode)];
|
|
195
192
|
}
|
|
196
193
|
});
|
|
197
194
|
});
|
|
@@ -5,25 +5,24 @@ var CommentParser = /** @class */ (function () {
|
|
|
5
5
|
function CommentParser() {
|
|
6
6
|
}
|
|
7
7
|
CommentParser.loadComment = function (target, data) {
|
|
8
|
-
var
|
|
8
|
+
var properties = data.properties, toolbar = data.toolbar, author = data.author, avatar = data.avatar;
|
|
9
9
|
// Basic information
|
|
10
|
-
target.id = commentId;
|
|
11
|
-
target.content =
|
|
12
|
-
target.publishDate =
|
|
13
|
-
target.likeCount = +
|
|
14
|
-
target.isAuthorChannelOwner =
|
|
15
|
-
target.isPinned =
|
|
16
|
-
target.replyCount = replyCount;
|
|
10
|
+
target.id = properties.commentId;
|
|
11
|
+
target.content = properties.content.content;
|
|
12
|
+
target.publishDate = properties.publishedTime;
|
|
13
|
+
target.likeCount = +toolbar.likeCountLiked; // probably broken
|
|
14
|
+
target.isAuthorChannelOwner = !!author.isCreator;
|
|
15
|
+
target.isPinned = false; // TODO fix this
|
|
16
|
+
target.replyCount = +toolbar.replyCount;
|
|
17
17
|
// Reply Continuation
|
|
18
18
|
target.replies.continuation = data.replies
|
|
19
19
|
? getContinuationFromItems(data.replies.commentRepliesRenderer.contents)
|
|
20
20
|
: undefined;
|
|
21
21
|
// Author
|
|
22
|
-
var browseId = authorEndpoint.browseEndpoint.browseId;
|
|
23
22
|
target.author = new BaseChannel({
|
|
24
|
-
id:
|
|
25
|
-
name:
|
|
26
|
-
thumbnails: new Thumbnails().load(
|
|
23
|
+
id: author.id,
|
|
24
|
+
name: author.displayName,
|
|
25
|
+
thumbnails: new Thumbnails().load(avatar.image.sources),
|
|
27
26
|
client: target.client,
|
|
28
27
|
});
|
|
29
28
|
return target;
|
|
@@ -70,10 +70,10 @@ var LiveVideo = /** @class */ (function (_super) {
|
|
|
70
70
|
/** @hidden */
|
|
71
71
|
function LiveVideo(attr) {
|
|
72
72
|
var _this = _super.call(this, attr) || this;
|
|
73
|
-
_this.
|
|
74
|
-
_this.
|
|
75
|
-
_this.
|
|
76
|
-
_this.
|
|
73
|
+
_this.delay = 0;
|
|
74
|
+
_this.timeoutMs = 0;
|
|
75
|
+
_this.isChatPlaying = false;
|
|
76
|
+
_this.chatQueue = [];
|
|
77
77
|
Object.assign(_this, attr);
|
|
78
78
|
return _this;
|
|
79
79
|
}
|
|
@@ -94,18 +94,18 @@ var LiveVideo = /** @class */ (function (_super) {
|
|
|
94
94
|
*/
|
|
95
95
|
LiveVideo.prototype.playChat = function (delay) {
|
|
96
96
|
if (delay === void 0) { delay = 0; }
|
|
97
|
-
if (this.
|
|
97
|
+
if (this.isChatPlaying)
|
|
98
98
|
return;
|
|
99
|
-
this.
|
|
100
|
-
this.
|
|
99
|
+
this.delay = delay;
|
|
100
|
+
this.isChatPlaying = true;
|
|
101
101
|
this.pollChatContinuation();
|
|
102
102
|
};
|
|
103
103
|
/** Stop request polling for live chat */
|
|
104
104
|
LiveVideo.prototype.stopChat = function () {
|
|
105
|
-
if (!this.
|
|
105
|
+
if (!this.chatRequestPoolingTimeout)
|
|
106
106
|
return;
|
|
107
|
-
this.
|
|
108
|
-
clearTimeout(this.
|
|
107
|
+
this.isChatPlaying = false;
|
|
108
|
+
clearTimeout(this.chatRequestPoolingTimeout);
|
|
109
109
|
};
|
|
110
110
|
/** Start request polling */
|
|
111
111
|
LiveVideo.prototype.pollChatContinuation = function () {
|
|
@@ -125,10 +125,10 @@ var LiveVideo = /** @class */ (function (_super) {
|
|
|
125
125
|
chats = LiveVideoParser.parseChats(response.data);
|
|
126
126
|
_loop_1 = function (c) {
|
|
127
127
|
var chat = new Chat({ client: this_1.client }).load(c);
|
|
128
|
-
if (this_1.
|
|
128
|
+
if (this_1.chatQueue.find(function (c) { return c.id === chat.id; }))
|
|
129
129
|
return "continue";
|
|
130
|
-
this_1.
|
|
131
|
-
var timeout_1 = chat.timestamp / 1000 - (new Date().getTime() - this_1.
|
|
130
|
+
this_1.chatQueue.push(chat);
|
|
131
|
+
var timeout_1 = chat.timestamp / 1000 - (new Date().getTime() - this_1.delay);
|
|
132
132
|
setTimeout(function () { return _this.emit("chat", chat); }, timeout_1);
|
|
133
133
|
};
|
|
134
134
|
this_1 = this;
|
|
@@ -146,9 +146,9 @@ var LiveVideo = /** @class */ (function (_super) {
|
|
|
146
146
|
finally { if (e_1) throw e_1.error; }
|
|
147
147
|
}
|
|
148
148
|
_a = LiveVideoParser.parseContinuation(response.data), timeout = _a.timeout, continuation = _a.continuation;
|
|
149
|
-
this.
|
|
149
|
+
this.timeoutMs = timeout;
|
|
150
150
|
this.chatContinuation = continuation;
|
|
151
|
-
this.
|
|
151
|
+
this.chatRequestPoolingTimeout = setTimeout(function () { return _this.pollChatContinuation(); }, this.timeoutMs);
|
|
152
152
|
return [2 /*return*/];
|
|
153
153
|
}
|
|
154
154
|
});
|
|
@@ -9,7 +9,7 @@ var LiveVideoParser = /** @class */ (function () {
|
|
|
9
9
|
.map(function (r) { return r.text; })
|
|
10
10
|
.join(" ")
|
|
11
11
|
.replace(/[^0-9]/g, "");
|
|
12
|
-
target.chatContinuation = (_a = data
|
|
12
|
+
target.chatContinuation = (_a = data.response.contents.twoColumnWatchNextResults.conversationBar.liveChatRenderer) === null || _a === void 0 ? void 0 : _a.continuations[0].reloadContinuationData.continuation;
|
|
13
13
|
return target;
|
|
14
14
|
};
|
|
15
15
|
LiveVideoParser.parseChats = function (data) {
|
|
@@ -73,15 +73,13 @@ var Video = /** @class */ (function (_super) {
|
|
|
73
73
|
/**
|
|
74
74
|
* Get Video transcript (if exists)
|
|
75
75
|
*
|
|
76
|
-
*
|
|
77
|
-
* ```js
|
|
78
|
-
* client.getVideoTranscript(video.id);
|
|
79
|
-
* ```
|
|
76
|
+
* @deprecated use `video.captions.get()` instead
|
|
80
77
|
*/
|
|
81
|
-
Video.prototype.getTranscript = function () {
|
|
78
|
+
Video.prototype.getTranscript = function (languageCode) {
|
|
79
|
+
var _a;
|
|
82
80
|
return __awaiter(this, void 0, void 0, function () {
|
|
83
|
-
return __generator(this, function (
|
|
84
|
-
return [2 /*return*/, this.
|
|
81
|
+
return __generator(this, function (_b) {
|
|
82
|
+
return [2 /*return*/, (_a = this.captions) === null || _a === void 0 ? void 0 : _a.get(languageCode)];
|
|
85
83
|
});
|
|
86
84
|
});
|
|
87
85
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getContinuationFromItems,
|
|
1
|
+
import { getContinuationFromItems, Thumbnails } from "../../common";
|
|
2
2
|
import { BaseVideoParser } from "../BaseVideo";
|
|
3
3
|
import { Comment } from "../Comment";
|
|
4
4
|
var VideoParser = /** @class */ (function () {
|
|
@@ -8,11 +8,11 @@ var VideoParser = /** @class */ (function () {
|
|
|
8
8
|
var _a, _b, _c;
|
|
9
9
|
var videoInfo = BaseVideoParser.parseRawData(data);
|
|
10
10
|
target.duration = +videoInfo.videoDetails.lengthSeconds;
|
|
11
|
-
var itemSectionRenderer = (_a = data
|
|
11
|
+
var itemSectionRenderer = (_a = data.response.contents.twoColumnWatchNextResults.results.results.contents
|
|
12
12
|
.reverse()
|
|
13
13
|
.find(function (c) { return c.itemSectionRenderer; })) === null || _a === void 0 ? void 0 : _a.itemSectionRenderer;
|
|
14
14
|
target.comments.continuation = getContinuationFromItems((itemSectionRenderer === null || itemSectionRenderer === void 0 ? void 0 : itemSectionRenderer.contents) || []);
|
|
15
|
-
var chapters = (_c = (_b = data
|
|
15
|
+
var chapters = (_c = (_b = data.response.playerOverlays.playerOverlayRenderer.decoratedPlayerBarRenderer) === null || _b === void 0 ? void 0 : _b.decoratedPlayerBarRenderer.playerBar.multiMarkersPlayerBarRenderer.markersMap) === null || _c === void 0 ? void 0 : _c[0].value.chapters;
|
|
16
16
|
target.chapters =
|
|
17
17
|
(chapters === null || chapters === void 0 ? void 0 : chapters.map(function (_a) {
|
|
18
18
|
var c = _a.chapterRenderer;
|
|
@@ -25,9 +25,9 @@ var VideoParser = /** @class */ (function () {
|
|
|
25
25
|
return target;
|
|
26
26
|
};
|
|
27
27
|
VideoParser.parseComments = function (data, video) {
|
|
28
|
-
var
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
var comments = data.frameworkUpdates.entityBatchUpdate.mutations
|
|
29
|
+
.filter(function (m) { return m.payload.commentEntityPayload; })
|
|
30
|
+
.map(function (m) { return m.payload.commentEntityPayload; });
|
|
31
31
|
return comments.map(function (c) {
|
|
32
32
|
return new Comment({ video: video, client: video.client }).load(c);
|
|
33
33
|
});
|
|
@@ -101,10 +101,10 @@ var VideoCompact = /** @class */ (function (_super) {
|
|
|
101
101
|
* client.getVideoTranscript(video.id);
|
|
102
102
|
* ```
|
|
103
103
|
*/
|
|
104
|
-
VideoCompact.prototype.getTranscript = function () {
|
|
104
|
+
VideoCompact.prototype.getTranscript = function (languageCode) {
|
|
105
105
|
return __awaiter(this, void 0, void 0, function () {
|
|
106
106
|
return __generator(this, function (_a) {
|
|
107
|
-
return [2 /*return*/, this.client.getVideoTranscript(this.id)];
|
|
107
|
+
return [2 /*return*/, this.client.getVideoTranscript(this.id, languageCode)];
|
|
108
108
|
});
|
|
109
109
|
});
|
|
110
110
|
};
|
|
@@ -4,18 +4,22 @@ var VideoCompactParser = /** @class */ (function () {
|
|
|
4
4
|
function VideoCompactParser() {
|
|
5
5
|
}
|
|
6
6
|
VideoCompactParser.loadVideoCompact = function (target, data) {
|
|
7
|
-
var _a, _b, _c;
|
|
7
|
+
var _a, _b, _c, _d, _e;
|
|
8
8
|
var videoId = data.videoId, title = data.title, headline = data.headline, lengthText = data.lengthText, thumbnail = data.thumbnail, ownerText = data.ownerText, shortBylineText = data.shortBylineText, publishedTimeText = data.publishedTimeText, viewCountText = data.viewCountText, badges = data.badges, thumbnailOverlays = data.thumbnailOverlays, channelThumbnailSupportedRenderers = data.channelThumbnailSupportedRenderers, detailedMetadataSnippets = data.detailedMetadataSnippets;
|
|
9
9
|
target.id = videoId;
|
|
10
|
-
target.title = headline
|
|
10
|
+
target.title = headline
|
|
11
|
+
? headline.simpleText
|
|
12
|
+
: title.simpleText || ((_b = (_a = title.runs) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.text) || "";
|
|
11
13
|
target.thumbnails = new Thumbnails().load(thumbnail.thumbnails);
|
|
12
14
|
target.uploadDate = publishedTimeText === null || publishedTimeText === void 0 ? void 0 : publishedTimeText.simpleText;
|
|
13
15
|
target.description =
|
|
14
|
-
((
|
|
16
|
+
((_c = detailedMetadataSnippets === null || detailedMetadataSnippets === void 0 ? void 0 : detailedMetadataSnippets[0].snippetText.runs) === null || _c === void 0 ? void 0 : _c.map(function (r) { return r.text; }).join("")) || "";
|
|
15
17
|
target.duration =
|
|
16
|
-
getDuration((lengthText === null || lengthText === void 0 ? void 0 : lengthText.simpleText) || ((
|
|
18
|
+
getDuration((lengthText === null || lengthText === void 0 ? void 0 : lengthText.simpleText) || ((_d = thumbnailOverlays === null || thumbnailOverlays === void 0 ? void 0 : thumbnailOverlays[0].thumbnailOverlayTimeStatusRenderer) === null || _d === void 0 ? void 0 : _d.text.simpleText) ||
|
|
17
19
|
"") || null;
|
|
18
|
-
target.isLive =
|
|
20
|
+
target.isLive =
|
|
21
|
+
!!((badges === null || badges === void 0 ? void 0 : badges[0].metadataBadgeRenderer.style) === "BADGE_STYLE_TYPE_LIVE_NOW") ||
|
|
22
|
+
((_e = thumbnailOverlays === null || thumbnailOverlays === void 0 ? void 0 : thumbnailOverlays[0].thumbnailOverlayTimeStatusRenderer) === null || _e === void 0 ? void 0 : _e.style) === "LIVE";
|
|
19
23
|
// Channel
|
|
20
24
|
if (ownerText || shortBylineText) {
|
|
21
25
|
var browseEndpoint = (ownerText || shortBylineText).runs[0].navigationEndpoint
|
|
@@ -28,8 +28,8 @@ export declare class HTTP {
|
|
|
28
28
|
private defaultFetchOptions;
|
|
29
29
|
private defaultClientOptions;
|
|
30
30
|
constructor(options: HTTPOptions);
|
|
31
|
-
get(
|
|
32
|
-
post(
|
|
31
|
+
get(path: string, options?: Partial<Options>): Promise<Response>;
|
|
32
|
+
post(path: string, options?: Partial<Options>): Promise<Response>;
|
|
33
33
|
private request;
|
|
34
34
|
private parseCookie;
|
|
35
35
|
}
|
|
@@ -3,6 +3,7 @@ import { Base, BaseProperties } from "../Base";
|
|
|
3
3
|
import { BaseChannel } from "../BaseChannel";
|
|
4
4
|
import { PlaylistCompact } from "../PlaylistCompact";
|
|
5
5
|
import { VideoCompact } from "../VideoCompact";
|
|
6
|
+
import { VideoCaptions } from "./VideoCaptions";
|
|
6
7
|
import { VideoRelated } from "./VideoRelated";
|
|
7
8
|
/** @hidden */
|
|
8
9
|
export interface BaseVideoProperties extends BaseProperties {
|
|
@@ -40,6 +41,8 @@ export declare class BaseVideo extends Base implements BaseVideoProperties {
|
|
|
40
41
|
tags: string[];
|
|
41
42
|
/** Continuable of videos / playlists related to this video */
|
|
42
43
|
related: VideoRelated;
|
|
44
|
+
/** Captions helper class of this video (if caption exists in this video) */
|
|
45
|
+
captions: VideoCaptions | null;
|
|
43
46
|
/** @hidden */
|
|
44
47
|
constructor(attr: BaseVideoProperties);
|
|
45
48
|
/**
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { YoutubeRawData } from "../../common";
|
|
2
|
+
import { Base } from "../Base";
|
|
3
|
+
import { BaseVideo } from "../BaseVideo";
|
|
4
|
+
import { Caption, CaptionLanguage } from "../Caption";
|
|
5
|
+
import { Client } from "../Client";
|
|
6
|
+
/** @hidden */
|
|
7
|
+
interface ConstructorParams {
|
|
8
|
+
client: Client;
|
|
9
|
+
video?: BaseVideo;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Captions of a video
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```js
|
|
16
|
+
*
|
|
17
|
+
* console.log(result.captions.languages.map((l) => `${l.code} - ${l.name}`)); // printing out available languages for captions
|
|
18
|
+
*
|
|
19
|
+
* console.log(await result.captions.get("en")); // printing out captions of a specific language using language code
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export declare class VideoCaptions extends Base {
|
|
23
|
+
/** The video this captions belongs to */
|
|
24
|
+
video?: BaseVideo;
|
|
25
|
+
/** List of available languages for this video */
|
|
26
|
+
languages: Array<CaptionLanguage>;
|
|
27
|
+
/** @hidden */
|
|
28
|
+
constructor({ video, client }: ConstructorParams);
|
|
29
|
+
/**
|
|
30
|
+
* Load this instance with raw data from Youtube
|
|
31
|
+
*
|
|
32
|
+
* @hidden
|
|
33
|
+
*/
|
|
34
|
+
load(data: YoutubeRawData): VideoCaptions;
|
|
35
|
+
/**
|
|
36
|
+
* Get captions of a specific language or a translation of a specific language
|
|
37
|
+
*/
|
|
38
|
+
get(languageCode?: string, translationLanguageCode?: string): Promise<Caption[] | undefined>;
|
|
39
|
+
}
|
|
40
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** @hidden */
|
|
2
|
+
interface CaptionProperties {
|
|
3
|
+
text?: string;
|
|
4
|
+
start?: number;
|
|
5
|
+
duration?: number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Represent a single video caption entry
|
|
9
|
+
*/
|
|
10
|
+
export declare class Caption implements CaptionProperties {
|
|
11
|
+
/** caption content */
|
|
12
|
+
text: string;
|
|
13
|
+
/** caption start time in milliseconds */
|
|
14
|
+
start: number;
|
|
15
|
+
/** caption duration in milliseconds */
|
|
16
|
+
duration: number;
|
|
17
|
+
/** @hidden */
|
|
18
|
+
constructor(attr?: CaptionProperties);
|
|
19
|
+
/** transcript end time in milliseconds */
|
|
20
|
+
get end(): number;
|
|
21
|
+
}
|
|
22
|
+
export {};
|