youtubei 0.0.1-rc.26 → 0.0.1-rc.29

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.
@@ -9,7 +9,6 @@ export interface BaseVideoAttributes extends BaseAttributes {
9
9
  uploadDate: string;
10
10
  viewCount: number | null;
11
11
  likeCount: number | null;
12
- dislikeCount: number | null;
13
12
  isLiveContent: boolean;
14
13
  tags: string[];
15
14
  upNext: VideoCompact | PlaylistCompact | null;
@@ -32,8 +31,6 @@ export default class BaseVideo extends Base implements BaseVideoAttributes {
32
31
  viewCount: number | null;
33
32
  /** How many like does this video have, null if the like count hidden */
34
33
  likeCount: number | null;
35
- /** How many dislike does this video have, null if the dislike count is hidden */
36
- dislikeCount: number | null;
37
34
  /** Whether this video is a live content or not */
38
35
  isLiveContent: boolean;
39
36
  /** The tags of this video */
@@ -37,17 +37,17 @@ class BaseVideo extends _1.Base {
37
37
  this.isLiveContent = videoInfo.videoDetails.isLiveContent;
38
38
  this.thumbnails = new _1.Thumbnails().load(videoInfo.videoDetails.thumbnail.thumbnails);
39
39
  // Channel
40
- const { title, thumbnail } = videoInfo.owner.videoOwnerRenderer;
40
+ const { title, thumbnail, subscriberCountText } = videoInfo.owner.videoOwnerRenderer;
41
41
  this.channel = new _1.ChannelCompact({
42
42
  client: this.client,
43
43
  id: title.runs[0].navigationEndpoint.browseEndpoint.browseId,
44
44
  name: title.runs[0].text,
45
+ subscriberCount: subscriberCountText === null || subscriberCountText === void 0 ? void 0 : subscriberCountText.simpleText,
45
46
  thumbnails: new _1.Thumbnails().load(thumbnail.thumbnails),
46
47
  });
47
48
  // Like Count and Dislike Count
48
49
  const topLevelButtons = videoInfo.videoActions.menuRenderer.topLevelButtons;
49
50
  this.likeCount = common_1.stripToInt(BaseVideo.parseButtonRenderer(topLevelButtons[0]));
50
- this.dislikeCount = common_1.stripToInt(BaseVideo.parseButtonRenderer(topLevelButtons[1]));
51
51
  // Tags and description
52
52
  this.tags =
53
53
  ((_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)) || [];
@@ -43,6 +43,8 @@ class Channel extends ChannelCompact_1.default {
43
43
  if (!shelfRenderer)
44
44
  continue;
45
45
  const { title, content, subtitle } = shelfRenderer;
46
+ if (!content.horizontalListRenderer)
47
+ continue;
46
48
  const items = content.horizontalListRenderer.items
47
49
  .map((i) => {
48
50
  if (i.gridVideoRenderer)
@@ -7,9 +7,9 @@ export declare namespace Client {
7
7
  type SearchType = "video" | "channel" | "playlist" | "all";
8
8
  type SearchOptions = {
9
9
  /** Search type, can be `"video"`, `"channel"`, `"playlist"`, or `"all"` */
10
- type: SearchType;
10
+ type?: SearchType;
11
11
  /** Raw search params to be passed on the request, ignores `type` value if this is provided */
12
- params: string;
12
+ params?: string;
13
13
  };
14
14
  type ClientOptions = {
15
15
  cookie: string;
@@ -33,7 +33,7 @@ export default class Client {
33
33
  * @param searchOptions Search options
34
34
  *
35
35
  */
36
- search<T extends Client.SearchOptions>(query: string, searchOptions?: Partial<T>): Promise<SearchResult<T["type"]>>;
36
+ search<T extends Client.SearchOptions>(query: string, searchOptions?: T): Promise<SearchResult<T["type"]>>;
37
37
  /**
38
38
  * Search for videos / playlists / channels and returns the first result
39
39
  *
@@ -30,14 +30,14 @@ class LiveVideo extends _1.BaseVideo {
30
30
  * @hidden
31
31
  */
32
32
  load(data) {
33
+ var _a;
33
34
  super.load(data);
34
35
  const videoInfo = _1.BaseVideo.parseRawData(data);
35
36
  this.watchingCount = +videoInfo.viewCount.videoViewCountRenderer.viewCount.runs
36
37
  .map((r) => r.text)
37
38
  .join(" ")
38
39
  .replace(/[^0-9]/g, "");
39
- this.chatContinuation =
40
- data[3].response.contents.twoColumnWatchNextResults.conversationBar.liveChatRenderer.continuations[0].reloadContinuationData.continuation;
40
+ this.chatContinuation = (_a = data[3].response.contents.twoColumnWatchNextResults.conversationBar.liveChatRenderer) === null || _a === void 0 ? void 0 : _a.continuations[0].reloadContinuationData.continuation;
41
41
  return this;
42
42
  }
43
43
  /**
@@ -65,6 +65,8 @@ class LiveVideo extends _1.BaseVideo {
65
65
  const response = yield this.client.http.post(constants_1.LIVE_CHAT_END_POINT, {
66
66
  data: { continuation: this.chatContinuation },
67
67
  });
68
+ if (!response.continuationContents)
69
+ return;
68
70
  this.parseChat(response.data);
69
71
  const timedContinuation = response.data.continuationContents.liveChatContinuation.continuations[0]
70
72
  .timedContinuationData;
@@ -68,9 +68,7 @@ let SearchResult = SearchResult_1 = class SearchResult extends Array {
68
68
  const response = yield this.client.http.post(`${constants_1.I_END_POINT}/search`, {
69
69
  data: {
70
70
  query,
71
- params: !options.params
72
- ? SearchResult_1.getSearchTypeParam(options.type)
73
- : options.params,
71
+ params: options.params || SearchResult_1.getSearchTypeParam(options.type || "all"),
74
72
  },
75
73
  });
76
74
  this.estimatedResults = +response.data.estimatedResults;
@@ -46,7 +46,7 @@ class HTTP {
46
46
  */
47
47
  request(partialOptions) {
48
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" }, partialOptions.headers) });
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
50
  let body = options.data || "";
51
51
  if (options.data)
52
52
  body = JSON.stringify(body);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "youtubei",
3
- "version": "0.0.1-rc.26",
3
+ "version": "0.0.1-rc.29",
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/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,89 +0,0 @@
1
- import { YoutubeRawData } from "../common";
2
- import { Base, PlaylistCompact, Thumbnails, VideoCompact, BaseAttributes } from ".";
3
- /** @hidden */
4
- interface CompactChannelAttributes extends BaseAttributes {
5
- name: string;
6
- thumbnails?: Thumbnails;
7
- videoCount?: number;
8
- subscriberCount?: string;
9
- }
10
- /** Represents a Youtube Channel */
11
- export default class CompactChannel extends Base implements CompactChannelAttributes {
12
- /** The channel's name */
13
- name: string;
14
- /** Thumbnails of the Channel with different sizes */
15
- thumbnails?: Thumbnails;
16
- /** How many video does this channel have */
17
- videoCount?: number;
18
- /**
19
- * How many subscriber does this channel have,
20
- *
21
- * This is not the exact amount, but a literal string like `"1.95M subscribers"`
22
- */
23
- subscriberCount?: string;
24
- /** Loaded videos on the channel, fetched from `channel.nextVideos()` */
25
- videos: VideoCompact[];
26
- /** Loaded playlists on the channel, fetched from `channel.nextPlaylists()` */
27
- playlists: PlaylistCompact[];
28
- private _videoContinuation?;
29
- private _playlistContinuation?;
30
- /** @hidden */
31
- constructor(channel?: Partial<CompactChannelAttributes>);
32
- /** The URL of the channel page */
33
- get url(): string;
34
- /**
35
- * Load this instance with raw data from Youtube
36
- *
37
- * @hidden
38
- */
39
- load(data: YoutubeRawData): CompactChannel;
40
- /**
41
- * Load next 30 videos made by the channel, and push the loaded videos to {@link Channel.videos}
42
- *
43
- * @example
44
- * ```js
45
- * const channel = await youtube.findOne(CHANNEL_NAME, {type: "channel"});
46
- * await channel.nextVideos();
47
- * console.log(channel.videos) // first 30 videos
48
- *
49
- * let newVideos = await channel.nextVideos();
50
- * console.log(newVideos) // 30 loaded videos
51
- * console.log(channel.videos) // first 60 videos
52
- *
53
- * await channel.nextVideos(0); // load the rest of the videos in the channel
54
- * ```
55
- *
56
- * @param count How many time to load the next videos, pass `0` to load all
57
- *
58
- * @return New loaded videos
59
- */
60
- nextVideos(count?: number): Promise<VideoCompact[]>;
61
- /**
62
- * Load next 30 playlists made by the channel, and push the loaded playlists to {@link Channel.playlists}
63
- *
64
- * @example
65
- * ```js
66
- * const channel = await youtube.findOne(CHANNEL_NAME, {type: "channel"});
67
- * await channel.nextPlaylists();
68
- * console.log(channel.playlists) // first 30 playlists
69
- *
70
- * let newPlaylists = await channel.nextPlaylists();
71
- * console.log(newPlaylists) // 30 loaded playlists
72
- * console.log(channel.playlists) // first 60 playlists
73
- *
74
- * await channel.nextPlaylists(0); // load the rest of the playlists in the channel
75
- * ```
76
- *
77
- * @param count How many time to load the next playlists, pass `0` to load all
78
- *
79
- * @return New loaded playlists
80
- */
81
- nextPlaylists(count?: number): Promise<PlaylistCompact[]>;
82
- /** Get tab data from youtube */
83
- private getTabData;
84
- /** Parse tab data from request, tab name is ignored if it's a continuation data */
85
- private static parseTabData;
86
- /** Get continuation token from items (if exists) */
87
- private static getContinuationFromItems;
88
- }
89
- export {};
@@ -1,142 +0,0 @@
1
- "use strict";
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
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- const common_1 = require("../common");
13
- const _1 = require(".");
14
- const constants_1 = require("../constants");
15
- /** Represents a Youtube Channel */
16
- class CompactChannel extends _1.Base {
17
- /** @hidden */
18
- constructor(channel = {}) {
19
- super();
20
- this._videoContinuation = null;
21
- this._playlistContinuation = null;
22
- Object.assign(this, channel);
23
- this.videos = [];
24
- this.playlists = [];
25
- }
26
- /** The URL of the channel page */
27
- get url() {
28
- return `https://www.youtube.com/channel/${this.id}`;
29
- }
30
- /**
31
- * Load this instance with raw data from Youtube
32
- *
33
- * @hidden
34
- */
35
- load(data) {
36
- const { channelId, title, thumbnail, videoCountText, subscriberCountText } = data;
37
- this.id = channelId;
38
- this.name = title.simpleText;
39
- this.thumbnails = new _1.Thumbnails().load(thumbnail.thumbnails);
40
- this.videoCount = common_1.stripToInt(videoCountText === null || videoCountText === void 0 ? void 0 : videoCountText.runs[0].text) || 0;
41
- this.subscriberCount = subscriberCountText === null || subscriberCountText === void 0 ? void 0 : subscriberCountText.simpleText;
42
- this.videos = [];
43
- this.playlists = [];
44
- return this;
45
- }
46
- /**
47
- * Load next 30 videos made by the channel, and push the loaded videos to {@link Channel.videos}
48
- *
49
- * @example
50
- * ```js
51
- * const channel = await youtube.findOne(CHANNEL_NAME, {type: "channel"});
52
- * await channel.nextVideos();
53
- * console.log(channel.videos) // first 30 videos
54
- *
55
- * let newVideos = await channel.nextVideos();
56
- * console.log(newVideos) // 30 loaded videos
57
- * console.log(channel.videos) // first 60 videos
58
- *
59
- * await channel.nextVideos(0); // load the rest of the videos in the channel
60
- * ```
61
- *
62
- * @param count How many time to load the next videos, pass `0` to load all
63
- *
64
- * @return New loaded videos
65
- */
66
- nextVideos(count = 1) {
67
- return __awaiter(this, void 0, void 0, function* () {
68
- const newVideos = [];
69
- for (let i = 0; i < count || count == 0; i++) {
70
- if (this._videoContinuation === undefined)
71
- break;
72
- const items = yield this.getTabData("videos");
73
- this._videoContinuation = CompactChannel.getContinuationFromItems(items);
74
- newVideos.push(...items
75
- .filter((i) => i.gridVideoRenderer)
76
- .map((i) => new _1.VideoCompact({ client: this.client }).load(i.gridVideoRenderer)));
77
- }
78
- this.videos.push(...newVideos);
79
- return newVideos;
80
- });
81
- }
82
- /**
83
- * Load next 30 playlists made by the channel, and push the loaded playlists to {@link Channel.playlists}
84
- *
85
- * @example
86
- * ```js
87
- * const channel = await youtube.findOne(CHANNEL_NAME, {type: "channel"});
88
- * await channel.nextPlaylists();
89
- * console.log(channel.playlists) // first 30 playlists
90
- *
91
- * let newPlaylists = await channel.nextPlaylists();
92
- * console.log(newPlaylists) // 30 loaded playlists
93
- * console.log(channel.playlists) // first 60 playlists
94
- *
95
- * await channel.nextPlaylists(0); // load the rest of the playlists in the channel
96
- * ```
97
- *
98
- * @param count How many time to load the next playlists, pass `0` to load all
99
- *
100
- * @return New loaded playlists
101
- */
102
- nextPlaylists(count = 1) {
103
- return __awaiter(this, void 0, void 0, function* () {
104
- const newPlaylists = [];
105
- for (let i = 0; i < count || count == 0; i++) {
106
- if (this._playlistContinuation === undefined)
107
- break;
108
- const items = yield this.getTabData("playlists");
109
- this._playlistContinuation = CompactChannel.getContinuationFromItems(items);
110
- newPlaylists.push(...items
111
- .filter((i) => i.gridPlaylistRenderer)
112
- .map((i) => new _1.PlaylistCompact({ client: this.client }).load(i.gridPlaylistRenderer)));
113
- }
114
- this.playlists.push(...newPlaylists);
115
- return newPlaylists;
116
- });
117
- }
118
- /** Get tab data from youtube */
119
- getTabData(name) {
120
- return __awaiter(this, void 0, void 0, function* () {
121
- const params = name === "videos" ? "EgZ2aWRlb3M%3D" : "EglwbGF5bGlzdHMgAQ%3D%3D";
122
- const continuation = name === "videos" ? this._videoContinuation : this._playlistContinuation;
123
- const response = yield this.client.http.post(`${constants_1.I_END_POINT}/browse`, {
124
- data: { browseId: this.id, params, continuation },
125
- });
126
- return CompactChannel.parseTabData(name, response.data);
127
- });
128
- }
129
- /** Parse tab data from request, tab name is ignored if it's a continuation data */
130
- static parseTabData(name, data) {
131
- var _a;
132
- const index = name === "videos" ? 1 : 2;
133
- return (((_a = data.contents) === null || _a === void 0 ? void 0 : _a.twoColumnBrowseResultsRenderer.tabs[index].tabRenderer.content.sectionListRenderer.contents[0].itemSectionRenderer.contents[0].gridRenderer.items) ||
134
- data.onResponseReceivedActions[0].appendContinuationItemsAction.continuationItems);
135
- }
136
- /** Get continuation token from items (if exists) */
137
- static getContinuationFromItems(items) {
138
- var _a;
139
- return (_a = items[items.length - 1].continuationItemRenderer) === null || _a === void 0 ? void 0 : _a.continuationEndpoint.continuationCommand.token;
140
- }
141
- }
142
- exports.default = CompactChannel;