youtubei 1.3.7 → 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.
Files changed (57) hide show
  1. package/dist/cjs/common/shared/HTTP/HTTP.js +18 -7
  2. package/dist/cjs/youtube/BaseVideo/BaseVideoParser.js +7 -2
  3. package/dist/cjs/youtube/BaseVideo/VideoCaptions.js +81 -0
  4. package/dist/cjs/youtube/BaseVideo/index.js +1 -0
  5. package/dist/cjs/youtube/Caption/Caption.js +17 -0
  6. package/dist/cjs/youtube/Caption/CaptionLanguage.js +17 -0
  7. package/dist/cjs/youtube/{Transcript/proto → Caption}/index.js +2 -1
  8. package/dist/cjs/youtube/Client/Client.js +9 -13
  9. package/dist/cjs/youtube/Comment/CommentParser.js +11 -12
  10. package/dist/cjs/youtube/LiveVideo/LiveVideo.js +15 -15
  11. package/dist/cjs/youtube/Video/Video.js +4 -6
  12. package/dist/cjs/youtube/Video/VideoParser.js +3 -3
  13. package/dist/cjs/youtube/VideoCompact/VideoCompact.js +2 -2
  14. package/dist/cjs/youtube/VideoCompact/VideoCompactParser.js +4 -2
  15. package/dist/cjs/youtube/index.js +0 -1
  16. package/dist/esm/common/shared/HTTP/HTTP.js +59 -12
  17. package/dist/esm/youtube/BaseVideo/BaseVideoParser.js +7 -2
  18. package/dist/esm/youtube/BaseVideo/VideoCaptions.js +133 -0
  19. package/dist/esm/youtube/BaseVideo/index.js +1 -0
  20. package/dist/esm/youtube/Caption/Caption.js +19 -0
  21. package/dist/esm/youtube/Caption/CaptionLanguage.js +15 -0
  22. package/dist/esm/youtube/Caption/index.js +2 -0
  23. package/dist/esm/youtube/Client/Client.js +13 -18
  24. package/dist/esm/youtube/Comment/CommentParser.js +11 -12
  25. package/dist/esm/youtube/LiveVideo/LiveVideo.js +15 -15
  26. package/dist/esm/youtube/Video/Video.js +5 -7
  27. package/dist/esm/youtube/Video/VideoParser.js +4 -4
  28. package/dist/esm/youtube/VideoCompact/VideoCompact.js +2 -2
  29. package/dist/esm/youtube/VideoCompact/VideoCompactParser.js +4 -2
  30. package/dist/esm/youtube/index.js +0 -1
  31. package/dist/typings/common/shared/HTTP/HTTP.d.ts +2 -2
  32. package/dist/typings/youtube/BaseVideo/BaseVideo.d.ts +3 -0
  33. package/dist/typings/youtube/BaseVideo/VideoCaptions.d.ts +40 -0
  34. package/dist/typings/youtube/BaseVideo/index.d.ts +1 -0
  35. package/dist/typings/youtube/Caption/Caption.d.ts +22 -0
  36. package/dist/typings/youtube/Caption/CaptionLanguage.d.ts +30 -0
  37. package/dist/typings/youtube/Caption/index.d.ts +2 -0
  38. package/dist/typings/youtube/Client/Client.d.ts +8 -3
  39. package/dist/typings/youtube/LiveVideo/LiveVideo.d.ts +5 -5
  40. package/dist/typings/youtube/Video/Video.d.ts +3 -6
  41. package/dist/typings/youtube/VideoCompact/VideoCompact.d.ts +2 -2
  42. package/dist/typings/youtube/index.d.ts +0 -1
  43. package/package.json +1 -1
  44. package/dist/cjs/youtube/Transcript/Transcript.js +0 -27
  45. package/dist/cjs/youtube/Transcript/TranscriptParser.js +0 -13
  46. package/dist/cjs/youtube/Transcript/index.js +0 -15
  47. package/dist/cjs/youtube/Transcript/proto/TranscriptParamsProto.js +0 -12
  48. package/dist/esm/youtube/Transcript/Transcript.js +0 -29
  49. package/dist/esm/youtube/Transcript/TranscriptParser.js +0 -13
  50. package/dist/esm/youtube/Transcript/index.js +0 -3
  51. package/dist/esm/youtube/Transcript/proto/TranscriptParamsProto.js +0 -2
  52. package/dist/esm/youtube/Transcript/proto/index.js +0 -1
  53. package/dist/typings/youtube/Transcript/Transcript.d.ts +0 -29
  54. package/dist/typings/youtube/Transcript/TranscriptParser.d.ts +0 -5
  55. package/dist/typings/youtube/Transcript/index.d.ts +0 -3
  56. package/dist/typings/youtube/Transcript/proto/TranscriptParamsProto.d.ts +0 -7
  57. package/dist/typings/youtube/Transcript/proto/index.d.ts +0 -1
@@ -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 };
@@ -1,3 +1,4 @@
1
1
  export * from "./BaseVideo";
2
2
  export * from "./BaseVideoParser";
3
+ export * from "./VideoCaptions";
3
4
  export * from "./VideoRelated";
@@ -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 };
@@ -0,0 +1,2 @@
1
+ export * from "./Caption";
2
+ export * from "./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
- var fullOptions = __assign(__assign({ initialCookie: "", fetchOptions: {} }, options), { youtubeClientOptions: __assign({ hl: "en", gl: "US" }, options.youtubeClientOptions) });
62
- this.http = new HTTP(__assign({ apiKey: INNERTUBE_API_KEY, baseUrl: BASE_URL, clientName: INNERTUBE_CLIENT_NAME, clientVersion: INNERTUBE_CLIENT_VERSION }, fullOptions));
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
@@ -177,23 +176,19 @@ var Client = /** @class */ (function () {
177
176
  });
178
177
  });
179
178
  };
180
- Client.prototype.getVideoTranscript = function (videoId) {
179
+ /**
180
+ * Get video transcript / caption by video id
181
+ */
182
+ Client.prototype.getVideoTranscript = function (videoId, languageCode) {
183
+ var _a;
181
184
  return __awaiter(this, void 0, void 0, function () {
182
- var bufferParams, response;
183
- return __generator(this, function (_a) {
184
- switch (_a.label) {
185
- case 0:
186
- bufferParams = TranscriptParamsProto.encode({ videoId: videoId }).finish();
187
- return [4 /*yield*/, this.http.post(I_END_POINT + "/get_transcript", {
188
- data: { params: Buffer.from(bufferParams).toString("base64") },
189
- })];
185
+ var video;
186
+ return __generator(this, function (_b) {
187
+ switch (_b.label) {
188
+ case 0: return [4 /*yield*/, this.getVideo(videoId)];
190
189
  case 1:
191
- response = _a.sent();
192
- if (!response.data.actions)
193
- return [2 /*return*/, undefined];
194
- return [2 /*return*/, response.data.actions[0].updateEngagementPanelAction.content.transcriptRenderer.body.transcriptBodyRenderer.cueGroups
195
- .map(function (t) { return t.transcriptCueGroupRenderer.cues[0].transcriptCueRenderer; })
196
- .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)];
197
192
  }
198
193
  });
199
194
  });
@@ -5,25 +5,24 @@ var CommentParser = /** @class */ (function () {
5
5
  function CommentParser() {
6
6
  }
7
7
  CommentParser.loadComment = function (target, data) {
8
- var _a = data.comment.commentRenderer, authorText = _a.authorText, authorThumbnail = _a.authorThumbnail, authorEndpoint = _a.authorEndpoint, contentText = _a.contentText, publishedTimeText = _a.publishedTimeText, commentId = _a.commentId, voteCount = _a.voteCount, authorIsChannelOwner = _a.authorIsChannelOwner, pinnedCommentBadge = _a.pinnedCommentBadge, replyCount = _a.replyCount;
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 = contentText.runs.map(function (r) { return r.text; }).join("");
12
- target.publishDate = publishedTimeText.runs.shift().text;
13
- target.likeCount = +((voteCount === null || voteCount === void 0 ? void 0 : voteCount.simpleText) || 0);
14
- target.isAuthorChannelOwner = authorIsChannelOwner;
15
- target.isPinned = !!pinnedCommentBadge;
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: browseId,
25
- name: authorText.simpleText,
26
- thumbnails: new Thumbnails().load(authorThumbnail.thumbnails),
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._delay = 0;
74
- _this._timeoutMs = 0;
75
- _this._isChatPlaying = false;
76
- _this._chatQueue = [];
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._isChatPlaying)
97
+ if (this.isChatPlaying)
98
98
  return;
99
- this._delay = delay;
100
- this._isChatPlaying = true;
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._chatRequestPoolingTimeout)
105
+ if (!this.chatRequestPoolingTimeout)
106
106
  return;
107
- this._isChatPlaying = false;
108
- clearTimeout(this._chatRequestPoolingTimeout);
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._chatQueue.find(function (c) { return c.id === chat.id; }))
128
+ if (this_1.chatQueue.find(function (c) { return c.id === chat.id; }))
129
129
  return "continue";
130
- this_1._chatQueue.push(chat);
131
- var timeout_1 = chat.timestamp / 1000 - (new Date().getTime() - this_1._delay);
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._timeoutMs = timeout;
149
+ this.timeoutMs = timeout;
150
150
  this.chatContinuation = continuation;
151
- this._chatRequestPoolingTimeout = setTimeout(function () { return _this.pollChatContinuation(); }, this._timeoutMs);
151
+ this.chatRequestPoolingTimeout = setTimeout(function () { return _this.pollChatContinuation(); }, this.timeoutMs);
152
152
  return [2 /*return*/];
153
153
  }
154
154
  });
@@ -73,15 +73,13 @@ var Video = /** @class */ (function (_super) {
73
73
  /**
74
74
  * Get Video transcript (if exists)
75
75
  *
76
- * Equivalent to
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 (_a) {
84
- return [2 /*return*/, this.client.getVideoTranscript(this.id)];
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, mapFilter, Thumbnails } from "../../common";
1
+ import { getContinuationFromItems, Thumbnails } from "../../common";
2
2
  import { BaseVideoParser } from "../BaseVideo";
3
3
  import { Comment } from "../Comment";
4
4
  var VideoParser = /** @class */ (function () {
@@ -25,9 +25,9 @@ var VideoParser = /** @class */ (function () {
25
25
  return target;
26
26
  };
27
27
  VideoParser.parseComments = function (data, video) {
28
- var endpoints = data.onResponseReceivedEndpoints.at(-1);
29
- var continuationItems = (endpoints.reloadContinuationItemsCommand || endpoints.appendContinuationItemsAction).continuationItems;
30
- var comments = mapFilter(continuationItems, "commentThreadRenderer");
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,7 +4,7 @@ var VideoCompactParser = /** @class */ (function () {
4
4
  function VideoCompactParser() {
5
5
  }
6
6
  VideoCompactParser.loadVideoCompact = function (target, data) {
7
- var _a, _b, _c, _d;
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
10
  target.title = headline
@@ -17,7 +17,9 @@ var VideoCompactParser = /** @class */ (function () {
17
17
  target.duration =
18
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) ||
19
19
  "") || null;
20
- target.isLive = !!((badges === null || badges === void 0 ? void 0 : badges[0].metadataBadgeRenderer.style) === "BADGE_STYLE_TYPE_LIVE_NOW");
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";
21
23
  // Channel
22
24
  if (ownerText || shortBylineText) {
23
25
  var browseEndpoint = (ownerText || shortBylineText).runs[0].navigationEndpoint
@@ -12,6 +12,5 @@ export * from "./Playlist";
12
12
  export * from "./PlaylistCompact";
13
13
  export * from "./Reply";
14
14
  export * from "./SearchResult";
15
- export * from "./Transcript";
16
15
  export * from "./Video";
17
16
  export * from "./VideoCompact";
@@ -28,8 +28,8 @@ export declare class HTTP {
28
28
  private defaultFetchOptions;
29
29
  private defaultClientOptions;
30
30
  constructor(options: HTTPOptions);
31
- get(url: string, options?: Partial<Options>): Promise<Response>;
32
- post(url: string, options?: Partial<Options>): Promise<Response>;
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 {};
@@ -1,3 +1,4 @@
1
1
  export * from "./BaseVideo";
2
2
  export * from "./BaseVideoParser";
3
+ export * from "./VideoCaptions";
3
4
  export * from "./VideoRelated";
@@ -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 {};
@@ -0,0 +1,30 @@
1
+ import { VideoCaptions } from "../BaseVideo";
2
+ import { Caption } from "./Caption";
3
+ /** @hidden */
4
+ interface CaptionLanguageProperties {
5
+ name?: string;
6
+ code?: string;
7
+ isTranslatable?: boolean;
8
+ url?: string;
9
+ captions?: VideoCaptions;
10
+ }
11
+ /**
12
+ * Represents a caption language option
13
+ */
14
+ export declare class CaptionLanguage implements CaptionLanguageProperties {
15
+ /** Caption language name */
16
+ name: string;
17
+ /** Caption language code */
18
+ code: string;
19
+ /** Whether this language is translatable */
20
+ isTranslatable: boolean;
21
+ /** Caption language url */
22
+ url: string;
23
+ /** @hidden */
24
+ captions: VideoCaptions;
25
+ /** @hidden */
26
+ constructor(attr?: CaptionLanguageProperties);
27
+ /** Get the captions of this language using the url */
28
+ get(translationLanguageCode?: string): Promise<Caption[] | undefined>;
29
+ }
30
+ export {};
@@ -0,0 +1,2 @@
1
+ export * from "./Caption";
2
+ export * from "./CaptionLanguage";
@@ -1,23 +1,25 @@
1
1
  import { RequestInit } from "node-fetch";
2
2
  import { HTTP } from "../../common";
3
+ import { Caption } from "../Caption";
3
4
  import { Channel } from "../Channel";
4
5
  import { LiveVideo } from "../LiveVideo";
5
6
  import { MixPlaylist } from "../MixPlaylist";
6
7
  import { Playlist } from "../Playlist";
7
8
  import { SearchOptions, SearchResult, SearchResultItem } from "../SearchResult";
8
- import { Transcript } from "../Transcript";
9
9
  import { Video } from "../Video";
10
10
  export declare type ClientOptions = {
11
11
  initialCookie: string;
12
12
  /** Optional options for http client */
13
13
  fetchOptions: Partial<RequestInit>;
14
14
  /** Optional options passed when sending a request to youtube (context.client) */
15
- youtubeClientOptions: Record<string, unknown>;
15
+ youtubeClientOptions: Record<string, string>;
16
16
  };
17
17
  /** Youtube Client */
18
18
  export declare class Client {
19
19
  /** @hidden */
20
20
  http: HTTP;
21
+ /** @hidden */
22
+ options: ClientOptions;
21
23
  constructor(options?: Partial<ClientOptions>);
22
24
  /**
23
25
  * Searches for videos / playlists / channels
@@ -39,5 +41,8 @@ export declare class Client {
39
41
  getVideo<T extends Video | LiveVideo | undefined>(videoId: string): Promise<T>;
40
42
  /** Get channel information by channel id+ */
41
43
  getChannel(channelId: string): Promise<Channel | undefined>;
42
- getVideoTranscript(videoId: string): Promise<Transcript[] | undefined>;
44
+ /**
45
+ * Get video transcript / caption by video id
46
+ */
47
+ getVideoTranscript(videoId: string, languageCode?: string): Promise<Caption[] | undefined>;
43
48
  }
@@ -19,11 +19,11 @@ declare class LiveVideo extends BaseVideo implements LiveVideoProperties {
19
19
  watchingCount: number;
20
20
  /** Current continuation token to load next chat */
21
21
  chatContinuation: string;
22
- private _delay;
23
- private _chatRequestPoolingTimeout;
24
- private _timeoutMs;
25
- private _isChatPlaying;
26
- private _chatQueue;
22
+ private delay;
23
+ private chatRequestPoolingTimeout;
24
+ private timeoutMs;
25
+ private isChatPlaying;
26
+ private chatQueue;
27
27
  /** @hidden */
28
28
  constructor(attr: LiveVideoProperties);
29
29
  /**
@@ -1,6 +1,6 @@
1
1
  import { Thumbnails, YoutubeRawData } from "../../common";
2
2
  import { BaseVideo, BaseVideoProperties } from "../BaseVideo";
3
- import { Transcript } from "../Transcript";
3
+ import { Caption } from "../Caption";
4
4
  import { VideoComments } from "./VideoComments";
5
5
  export declare type Chapter = {
6
6
  title: string;
@@ -32,11 +32,8 @@ export declare class Video extends BaseVideo implements VideoProperties {
32
32
  /**
33
33
  * Get Video transcript (if exists)
34
34
  *
35
- * Equivalent to
36
- * ```js
37
- * client.getVideoTranscript(video.id);
38
- * ```
35
+ * @deprecated use `video.captions.get()` instead
39
36
  */
40
- getTranscript(): Promise<Transcript[] | undefined>;
37
+ getTranscript(languageCode?: string): Promise<Caption[] | undefined>;
41
38
  }
42
39
  export {};