youtubei 1.8.4 → 1.8.6

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.
@@ -13,6 +13,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.HTTP = void 0;
16
+ const promises_1 = __importDefault(require("fs/promises"));
16
17
  const node_fetch_1 = __importDefault(require("node-fetch"));
17
18
  const url_1 = require("url");
18
19
  const OAuth_1 = require("./OAuth");
@@ -37,6 +38,7 @@ class HTTP {
37
38
  this.authorizationPromise = null;
38
39
  this.defaultFetchOptions = options.fetchOptions || {};
39
40
  this.defaultClientOptions = options.youtubeClientOptions || {};
41
+ this.rawResponseLogPath = options.rawResponseLogPath;
40
42
  }
41
43
  get(path, options) {
42
44
  return __awaiter(this, void 0, void 0, function* () {
@@ -79,6 +81,9 @@ class HTTP {
79
81
  }
80
82
  const response = yield node_fetch_1.default(urlString, options);
81
83
  const data = yield response.json();
84
+ if (this.rawResponseLogPath) {
85
+ yield promises_1.default.appendFile(this.rawResponseLogPath, JSON.stringify({ url: urlString, response: data }) + "\n");
86
+ }
82
87
  this.parseCookie(response);
83
88
  return { data };
84
89
  });
@@ -46,10 +46,20 @@ class ChannelShorts extends Continuable_1.Continuable {
46
46
  });
47
47
  const items = BaseChannelParser_1.BaseChannelParser.parseTabData("shorts", response.data);
48
48
  const continuation = common_1.getContinuationFromItems(items);
49
- const data = common_1.mapFilter(items, "reelItemRenderer");
49
+ const data = items.filter((i) => "reelItemRenderer" in i || "shortsLockupViewModel" in i);
50
50
  return {
51
51
  continuation,
52
- items: data.map((i) => new VideoCompact_1.VideoCompact({ client: this.client, channel: this.channel }).load(i)),
52
+ items: data.map((i) => {
53
+ const video = new VideoCompact_1.VideoCompact({
54
+ client: this.client,
55
+ channel: this.channel,
56
+ });
57
+ if (i.reelItemRenderer)
58
+ video.load(i.reelItemRenderer);
59
+ else if (i.shortsLockupViewModel)
60
+ video.loadLockup(i.lockupViewModel);
61
+ return video;
62
+ }),
53
63
  };
54
64
  });
55
65
  }
@@ -8,7 +8,7 @@ const VideoCompact_1 = require("../VideoCompact");
8
8
  const VideoCaptions_1 = require("./VideoCaptions");
9
9
  class BaseVideoParser {
10
10
  static loadBaseVideo(target, data) {
11
- var _a, _b, _c, _d;
11
+ var _a, _b, _c, _d, _e, _f;
12
12
  const videoInfo = BaseVideoParser.parseRawData(data);
13
13
  // Basic information
14
14
  target.id = videoInfo.videoDetails.videoId;
@@ -16,6 +16,8 @@ class BaseVideoParser {
16
16
  target.uploadDate = videoInfo.dateText.simpleText;
17
17
  target.viewCount = +videoInfo.videoDetails.viewCount || null;
18
18
  target.isLiveContent = videoInfo.videoDetails.isLiveContent;
19
+ target.formats = ((_a = videoInfo.streamingData) === null || _a === void 0 ? void 0 : _a.formats) || [];
20
+ target.adaptiveFormats = ((_b = videoInfo.streamingData) === null || _b === void 0 ? void 0 : _b.adaptiveFormats) || [];
19
21
  target.thumbnails = new common_1.Thumbnails().load(videoInfo.videoDetails.thumbnail.thumbnails);
20
22
  // Channel
21
23
  const { title, thumbnail, subscriberCountText } = videoInfo.owner.videoOwnerRenderer;
@@ -53,13 +55,13 @@ class BaseVideoParser {
53
55
  : null;
54
56
  // Tags and description
55
57
  target.tags =
56
- ((_b = (_a = videoInfo.superTitleLink) === null || _a === void 0 ? void 0 : _a.runs) === null || _b === void 0 ? void 0 : _b.map((r) => r.text.trim()).filter((t) => t)) || [];
58
+ ((_d = (_c = videoInfo.superTitleLink) === null || _c === void 0 ? void 0 : _c.runs) === null || _d === void 0 ? void 0 : _d.map((r) => r.text.trim()).filter((t) => t)) || [];
57
59
  target.description = videoInfo.videoDetails.shortDescription || "";
58
60
  // related videos
59
- let secondaryContents = (_c = data.response.contents.twoColumnWatchNextResults.secondaryResults) === null || _c === void 0 ? void 0 : _c.secondaryResults.results;
60
- const itemSectionRenderer = (_d = secondaryContents === null || secondaryContents === void 0 ? void 0 : secondaryContents.find((c) => {
61
+ let secondaryContents = (_e = data.response.contents.twoColumnWatchNextResults.secondaryResults) === null || _e === void 0 ? void 0 : _e.secondaryResults.results;
62
+ const itemSectionRenderer = (_f = secondaryContents === null || secondaryContents === void 0 ? void 0 : secondaryContents.find((c) => {
61
63
  return c.itemSectionRenderer;
62
- })) === null || _d === void 0 ? void 0 : _d.itemSectionRenderer;
64
+ })) === null || _f === void 0 ? void 0 : _f.itemSectionRenderer;
63
65
  if (itemSectionRenderer)
64
66
  secondaryContents = itemSectionRenderer.contents;
65
67
  if (secondaryContents) {
@@ -85,8 +87,8 @@ class BaseVideoParser {
85
87
  const primaryInfo = contents.find((c) => "videoPrimaryInfoRenderer" in c)
86
88
  .videoPrimaryInfoRenderer;
87
89
  const secondaryInfo = contents.find((c) => "videoSecondaryInfoRenderer" in c).videoSecondaryInfoRenderer;
88
- const { videoDetails, captions } = data.playerResponse;
89
- return Object.assign(Object.assign(Object.assign({}, secondaryInfo), primaryInfo), { videoDetails, captions });
90
+ const { videoDetails, captions, streamingData } = data.playerResponse;
91
+ return Object.assign(Object.assign(Object.assign({}, secondaryInfo), primaryInfo), { videoDetails, captions, streamingData });
90
92
  }
91
93
  static parseCompactRenderer(data, client) {
92
94
  if ("compactVideoRenderer" in data) {
@@ -39,11 +39,12 @@ class VideoCompactParser {
39
39
  return target;
40
40
  }
41
41
  static loadLockupVideoCompact(target, data) {
42
- var _a, _b;
42
+ var _a, _b, _c;
43
43
  const lockupMetadataViewModel = data.metadata.lockupMetadataViewModel;
44
44
  const decoratedAvatarViewModel = lockupMetadataViewModel.image.decoratedAvatarViewModel;
45
- const thumbnailBadge = data.contentImage.thumbnailViewModel.overlays[0].thumbnailOverlayBadgeViewModel
46
- .thumbnailBadges[0].thumbnailBadgeViewModel;
45
+ const thumbnailOverlay = data.contentImage.thumbnailViewModel.overlays[0];
46
+ const thumbnailBadge = (((_a = thumbnailOverlay.thumbnailBottomOverlayViewModel) === null || _a === void 0 ? void 0 : _a.badges[0]) ||
47
+ thumbnailOverlay.thumbnailOverlayBadgeViewModel.thumbnailBadges[0]).thumbnailBadgeViewModel;
47
48
  const metadataRows = lockupMetadataViewModel.metadata.contentMetadataViewModel.metadataRows;
48
49
  const channel = new BaseChannel_1.BaseChannel({
49
50
  client: target.client,
@@ -52,11 +53,11 @@ class VideoCompactParser {
52
53
  .browseEndpoint.browseId,
53
54
  thumbnails: new common_1.Thumbnails().load(decoratedAvatarViewModel.avatar.avatarViewModel.image.sources),
54
55
  });
55
- const isLive = ((_a = thumbnailBadge.icon) === null || _a === void 0 ? void 0 : _a.sources[0].clientResource.imageName) === "LIVE";
56
+ const isLive = ((_b = thumbnailBadge.icon) === null || _b === void 0 ? void 0 : _b.sources[0].clientResource.imageName) === "LIVE";
56
57
  target.channel = channel;
57
58
  target.id = data.contentId;
58
59
  target.title = lockupMetadataViewModel.title.content;
59
- target.isLive = ((_b = thumbnailBadge.icon) === null || _b === void 0 ? void 0 : _b.sources[0].clientResource.imageName) === "LIVE";
60
+ target.isLive = ((_c = thumbnailBadge.icon) === null || _c === void 0 ? void 0 : _c.sources[0].clientResource.imageName) === "LIVE";
60
61
  target.duration = !isLive ? common_1.getDuration(thumbnailBadge.text) : null;
61
62
  target.thumbnails = new common_1.Thumbnails().load(data.contentImage.thumbnailViewModel.image.sources);
62
63
  target.viewCount = common_1.stripToInt(metadataRows[1].metadataParts[0].text.content);
@@ -72,6 +72,7 @@ var __read = (this && this.__read) || function (o, n) {
72
72
  }
73
73
  return ar;
74
74
  };
75
+ import fs from "fs/promises";
75
76
  import fetch from "node-fetch";
76
77
  import { URLSearchParams } from "url";
77
78
  import { OAuth } from "./OAuth";
@@ -96,6 +97,7 @@ var HTTP = /** @class */ (function () {
96
97
  this.authorizationPromise = null;
97
98
  this.defaultFetchOptions = options.fetchOptions || {};
98
99
  this.defaultClientOptions = options.youtubeClientOptions || {};
100
+ this.rawResponseLogPath = options.rawResponseLogPath;
99
101
  }
100
102
  HTTP.prototype.get = function (path, options) {
101
103
  return __awaiter(this, void 0, void 0, function () {
@@ -172,6 +174,12 @@ var HTTP = /** @class */ (function () {
172
174
  return [4 /*yield*/, response.json()];
173
175
  case 6:
174
176
  data = _e.sent();
177
+ if (!this.rawResponseLogPath) return [3 /*break*/, 8];
178
+ return [4 /*yield*/, fs.appendFile(this.rawResponseLogPath, JSON.stringify({ url: urlString, response: data }) + "\n")];
179
+ case 7:
180
+ _e.sent();
181
+ _e.label = 8;
182
+ case 8:
175
183
  this.parseCookie(response);
176
184
  return [2 /*return*/, { data: data }];
177
185
  }
@@ -47,7 +47,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
47
47
  if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
48
48
  }
49
49
  };
50
- import { getContinuationFromItems, mapFilter } from "../../common";
50
+ import { getContinuationFromItems } from "../../common";
51
51
  import { Continuable } from "../Continuable";
52
52
  import { VideoCompact } from "../VideoCompact";
53
53
  import { I_END_POINT } from "../constants";
@@ -93,11 +93,19 @@ var ChannelShorts = /** @class */ (function (_super) {
93
93
  response = _b.sent();
94
94
  items = BaseChannelParser.parseTabData("shorts", response.data);
95
95
  continuation = getContinuationFromItems(items);
96
- data = mapFilter(items, "reelItemRenderer");
96
+ data = items.filter(function (i) { return "reelItemRenderer" in i || "shortsLockupViewModel" in i; });
97
97
  return [2 /*return*/, {
98
98
  continuation: continuation,
99
99
  items: data.map(function (i) {
100
- return new VideoCompact({ client: _this.client, channel: _this.channel }).load(i);
100
+ var video = new VideoCompact({
101
+ client: _this.client,
102
+ channel: _this.channel,
103
+ });
104
+ if (i.reelItemRenderer)
105
+ video.load(i.reelItemRenderer);
106
+ else if (i.shortsLockupViewModel)
107
+ video.loadLockup(i.lockupViewModel);
108
+ return video;
101
109
  }),
102
110
  }];
103
111
  }
@@ -18,7 +18,7 @@ var BaseVideoParser = /** @class */ (function () {
18
18
  function BaseVideoParser() {
19
19
  }
20
20
  BaseVideoParser.loadBaseVideo = function (target, data) {
21
- var _a, _b, _c, _d;
21
+ var _a, _b, _c, _d, _e, _f;
22
22
  var videoInfo = BaseVideoParser.parseRawData(data);
23
23
  // Basic information
24
24
  target.id = videoInfo.videoDetails.videoId;
@@ -26,9 +26,11 @@ var BaseVideoParser = /** @class */ (function () {
26
26
  target.uploadDate = videoInfo.dateText.simpleText;
27
27
  target.viewCount = +videoInfo.videoDetails.viewCount || null;
28
28
  target.isLiveContent = videoInfo.videoDetails.isLiveContent;
29
+ target.formats = ((_a = videoInfo.streamingData) === null || _a === void 0 ? void 0 : _a.formats) || [];
30
+ target.adaptiveFormats = ((_b = videoInfo.streamingData) === null || _b === void 0 ? void 0 : _b.adaptiveFormats) || [];
29
31
  target.thumbnails = new Thumbnails().load(videoInfo.videoDetails.thumbnail.thumbnails);
30
32
  // Channel
31
- var _e = videoInfo.owner.videoOwnerRenderer, title = _e.title, thumbnail = _e.thumbnail, subscriberCountText = _e.subscriberCountText;
33
+ var _g = videoInfo.owner.videoOwnerRenderer, title = _g.title, thumbnail = _g.thumbnail, subscriberCountText = _g.subscriberCountText;
32
34
  if (title) {
33
35
  target.channel = new BaseChannel({
34
36
  client: target.client,
@@ -63,13 +65,13 @@ var BaseVideoParser = /** @class */ (function () {
63
65
  : null;
64
66
  // Tags and description
65
67
  target.tags =
66
- ((_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; })) || [];
68
+ ((_d = (_c = videoInfo.superTitleLink) === null || _c === void 0 ? void 0 : _c.runs) === null || _d === void 0 ? void 0 : _d.map(function (r) { return r.text.trim(); }).filter(function (t) { return t; })) || [];
67
69
  target.description = videoInfo.videoDetails.shortDescription || "";
68
70
  // related videos
69
- var secondaryContents = (_c = data.response.contents.twoColumnWatchNextResults.secondaryResults) === null || _c === void 0 ? void 0 : _c.secondaryResults.results;
70
- var itemSectionRenderer = (_d = secondaryContents === null || secondaryContents === void 0 ? void 0 : secondaryContents.find(function (c) {
71
+ var secondaryContents = (_e = data.response.contents.twoColumnWatchNextResults.secondaryResults) === null || _e === void 0 ? void 0 : _e.secondaryResults.results;
72
+ var itemSectionRenderer = (_f = secondaryContents === null || secondaryContents === void 0 ? void 0 : secondaryContents.find(function (c) {
71
73
  return c.itemSectionRenderer;
72
- })) === null || _d === void 0 ? void 0 : _d.itemSectionRenderer;
74
+ })) === null || _f === void 0 ? void 0 : _f.itemSectionRenderer;
73
75
  if (itemSectionRenderer)
74
76
  secondaryContents = itemSectionRenderer.contents;
75
77
  if (secondaryContents) {
@@ -95,8 +97,8 @@ var BaseVideoParser = /** @class */ (function () {
95
97
  var primaryInfo = contents.find(function (c) { return "videoPrimaryInfoRenderer" in c; })
96
98
  .videoPrimaryInfoRenderer;
97
99
  var secondaryInfo = contents.find(function (c) { return "videoSecondaryInfoRenderer" in c; }).videoSecondaryInfoRenderer;
98
- var _a = data.playerResponse, videoDetails = _a.videoDetails, captions = _a.captions;
99
- return __assign(__assign(__assign({}, secondaryInfo), primaryInfo), { videoDetails: videoDetails, captions: captions });
100
+ var _a = data.playerResponse, videoDetails = _a.videoDetails, captions = _a.captions, streamingData = _a.streamingData;
101
+ return __assign(__assign(__assign({}, secondaryInfo), primaryInfo), { videoDetails: videoDetails, captions: captions, streamingData: streamingData });
100
102
  };
101
103
  BaseVideoParser.parseCompactRenderer = function (data, client) {
102
104
  if ("compactVideoRenderer" in data) {
@@ -38,11 +38,12 @@ var VideoCompactParser = /** @class */ (function () {
38
38
  return target;
39
39
  };
40
40
  VideoCompactParser.loadLockupVideoCompact = function (target, data) {
41
- var _a, _b;
41
+ var _a, _b, _c;
42
42
  var lockupMetadataViewModel = data.metadata.lockupMetadataViewModel;
43
43
  var decoratedAvatarViewModel = lockupMetadataViewModel.image.decoratedAvatarViewModel;
44
- var thumbnailBadge = data.contentImage.thumbnailViewModel.overlays[0].thumbnailOverlayBadgeViewModel
45
- .thumbnailBadges[0].thumbnailBadgeViewModel;
44
+ var thumbnailOverlay = data.contentImage.thumbnailViewModel.overlays[0];
45
+ var thumbnailBadge = (((_a = thumbnailOverlay.thumbnailBottomOverlayViewModel) === null || _a === void 0 ? void 0 : _a.badges[0]) ||
46
+ thumbnailOverlay.thumbnailOverlayBadgeViewModel.thumbnailBadges[0]).thumbnailBadgeViewModel;
46
47
  var metadataRows = lockupMetadataViewModel.metadata.contentMetadataViewModel.metadataRows;
47
48
  var channel = new BaseChannel({
48
49
  client: target.client,
@@ -51,11 +52,11 @@ var VideoCompactParser = /** @class */ (function () {
51
52
  .browseEndpoint.browseId,
52
53
  thumbnails: new Thumbnails().load(decoratedAvatarViewModel.avatar.avatarViewModel.image.sources),
53
54
  });
54
- var isLive = ((_a = thumbnailBadge.icon) === null || _a === void 0 ? void 0 : _a.sources[0].clientResource.imageName) === "LIVE";
55
+ var isLive = ((_b = thumbnailBadge.icon) === null || _b === void 0 ? void 0 : _b.sources[0].clientResource.imageName) === "LIVE";
55
56
  target.channel = channel;
56
57
  target.id = data.contentId;
57
58
  target.title = lockupMetadataViewModel.title.content;
58
- target.isLive = ((_b = thumbnailBadge.icon) === null || _b === void 0 ? void 0 : _b.sources[0].clientResource.imageName) === "LIVE";
59
+ target.isLive = ((_c = thumbnailBadge.icon) === null || _c === void 0 ? void 0 : _c.sources[0].clientResource.imageName) === "LIVE";
59
60
  target.duration = !isLive ? getDuration(thumbnailBadge.text) : null;
60
61
  target.thumbnails = new Thumbnails().load(data.contentImage.thumbnailViewModel.image.sources);
61
62
  target.viewCount = stripToInt(metadataRows[1].metadataParts[0].text.content);
@@ -22,6 +22,7 @@ export declare type HTTPOptions = {
22
22
  initialCookie?: string;
23
23
  oauth?: OAuthOptions;
24
24
  pot?: PotOptions;
25
+ rawResponseLogPath?: string;
25
26
  };
26
27
  declare type Response<T = any> = {
27
28
  data: T;
@@ -45,6 +46,7 @@ export declare class HTTP {
45
46
  private authorizationPromise;
46
47
  private pot?;
47
48
  oauth: OAuthOptions & OAuthProps;
49
+ private rawResponseLogPath?;
48
50
  constructor(options: HTTPOptions);
49
51
  get(path: string, options?: Partial<Options>): Promise<Response>;
50
52
  post(path: string, options?: Partial<Options>): Promise<Response>;
@@ -17,6 +17,8 @@ export interface BaseVideoProperties extends BaseProperties {
17
17
  likeCount?: number | null;
18
18
  isLiveContent?: boolean;
19
19
  tags?: string[];
20
+ formats?: YoutubeRawData[];
21
+ adaptiveFormats?: YoutubeRawData[];
20
22
  }
21
23
  /** Represents a Video */
22
24
  export declare class BaseVideo extends Base implements BaseVideoProperties {
@@ -40,6 +42,10 @@ export declare class BaseVideo extends Base implements BaseVideoProperties {
40
42
  /** Whether this video is a live content or not */
41
43
  isLiveContent: boolean;
42
44
  /** The tags of this video */
45
+ /** The formats of the video */
46
+ formats: YoutubeRawData[];
47
+ /** The adaptive formats of the video */
48
+ adaptiveFormats: YoutubeRawData[];
43
49
  tags: string[];
44
50
  /** Continuable of videos / playlists related to this video */
45
51
  related: VideoRelated;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "youtubei",
3
- "version": "1.8.4",
3
+ "version": "1.8.6",
4
4
  "description": "Simple package to get information from youtube such as videos, playlists, channels, video information & comments, related videos, up next video, and more!",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",