Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

youtubei.js

Package Overview
Dependencies
Maintainers
1
Versions
124
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

youtubei.js - npm Package Compare versions

Comparing version 1.4.2-d.1 to 1.4.2-d.2

6

lib/core/OAuth.js

@@ -17,3 +17,3 @@ 'use strict';

#auth_info = {};
#refresh_interval = 5;
#polling_interval = 5;
#ev = null;

@@ -65,3 +65,3 @@

this.refresh_interval = response.data.interval;
this.#polling_interval = response.data.interval;

@@ -126,3 +126,3 @@ this.#waitForAuth(response.data.device_code);

}
}, 1000 * this.#refresh_interval);
}, 1000 * this.#polling_interval);
}

@@ -129,0 +129,0 @@

@@ -26,4 +26,3 @@ 'use strict';

#actions;
#retry_count;
/**

@@ -45,3 +44,2 @@ * ```js

this.config = config || {};
this.#retry_count = 0;
return this.#init();

@@ -93,4 +91,4 @@ }

*
* @param {boolean} new_value
* @returns {Promise.<{ success: boolean; status_code: string; }>}
* @param {boolean} new_value - ON | OFF
* @returns {Promise.<{ success: boolean; status_code: number; data: object; }>}
*/

@@ -102,4 +100,4 @@ setSubscriptions: (new_value) => this.#setSetting(Constants.ACCOUNT_SETTINGS.SUBSCRIPTIONS, 'SPaccount_notifications', new_value),

*
* @param {boolean} new_value
* @returns {Promise.<{ success: boolean; status_code: string; }>}
* @param {boolean} new_value - ON | OFF
* @returns {Promise.<{ success: boolean; status_code: number; data: object; }>}
*/

@@ -111,4 +109,4 @@ setRecommendedVideos: (new_value) => this.#setSetting(Constants.ACCOUNT_SETTINGS.RECOMMENDED_VIDEOS, 'SPaccount_notifications', new_value),

*
* @param {boolean} new_value
* @returns {Promise.<{ success: boolean; status_code: string; }>}
* @param {boolean} new_value - ON | OFF
* @returns {Promise.<{ success: boolean; status_code: number; data: object; }>}
*/

@@ -120,4 +118,4 @@ setChannelActivity: (new_value) => this.#setSetting(Constants.ACCOUNT_SETTINGS.CHANNEL_ACTIVITY, 'SPaccount_notifications', new_value),

*
* @param {boolean} new_value
* @returns {Promise.<{ success: boolean; status_code: string; }>}
* @param {boolean} new_value - ON | OFF
* @returns {Promise.<{ success: boolean; status_code: number; data: object; }>}
*/

@@ -129,4 +127,4 @@ setCommentReplies: (new_value) => this.#setSetting(Constants.ACCOUNT_SETTINGS.COMMENT_REPLIES, 'SPaccount_notifications', new_value),

*
* @param {boolean} new_value
* @returns {Promise.<{ success: boolean; status_code: string; }>}
* @param {boolean} new_value - ON | OFF
* @returns {Promise.<{ success: boolean; status_code: number; data: object; }>}
*/

@@ -138,4 +136,4 @@ setMentions: (new_value) => this.#setSetting(Constants.ACCOUNT_SETTINGS.USER_MENTION, 'SPaccount_notifications', new_value),

*
* @param {boolean} new_value
* @returns {Promise.<{ success: boolean; status_code: string; }>}
* @param {boolean} new_value - ON | OFF
* @returns {Promise.<{ success: boolean; status_code: number; data: object; }>}
*/

@@ -148,4 +146,4 @@ setSharedContent: (new_value) => this.#setSetting(Constants.ACCOUNT_SETTINGS.SHARED_CONTENT, 'SPaccount_notifications', new_value)

*
* @param {boolean} new_value
* @returns {Promise.<{ success: boolean; status_code: string; }>}
* @param {boolean} new_value - ON | OFF
* @returns {Promise.<{ success: boolean; status_code: number; data: object; }>}
*/

@@ -157,4 +155,4 @@ setSubscriptionsPrivate: (new_value) => this.#setSetting(Constants.ACCOUNT_SETTINGS.SUBSCRIPTIONS_PRIVACY, 'SPaccount_privacy', new_value),

*
* @param {boolean} new_value
* @returns {Promise.<{ success: boolean; status_code: string; }>}
* @param {boolean} new_value - ON | OFF
* @returns {Promise.<{ success: boolean; status_code: number; data: object; }>}
*/

@@ -171,3 +169,3 @@ setSavedPlaylistsPrivate: (new_value) => this.#setSetting(Constants.ACCOUNT_SETTINGS.PLAYLISTS_PRIVACY, 'SPaccount_privacy', new_value)

* @param {string} video_id
* @returns {Promise.<{ success: boolean; status_code: string; }>}
* @returns {Promise.<{ success: boolean; status_code: number; data: object; }>}
*/

@@ -180,3 +178,3 @@ like: (video_id) => this.actions.engage('like/like', { video_id }),

* @param {string} video_id
* @returns {Promise.<{ success: boolean; status_code: string; }>}
* @returns {Promise.<{ success: boolean; status_code: number; data: object; }>}
*/

@@ -189,3 +187,3 @@ dislike: (video_id) => this.actions.engage('like/dislike', { video_id }),

* @param {string} video_id
* @returns {Promise.<{ success: boolean; status_code: string; }>}
* @returns {Promise.<{ success: boolean; status_code: number; data: object; }>}
*/

@@ -199,3 +197,3 @@ removeLike: (video_id) => this.actions.engage('like/removelike', { video_id }),

* @param {string} text
* @returns {Promise.<{ success: boolean; status_code: string; }>}
* @returns {Promise.<{ success: boolean; status_code: number; data: object; }>}
*/

@@ -213,3 +211,3 @@ comment: (video_id, text) => this.actions.engage('comment/create_comment', { video_id, text }),

*
* @returns {Promise.<{ success: boolean; status_code: string; }>}
* @returns {Promise.<{ success: boolean; status_code: number; translated_content: string; data: object; }>}
*/

@@ -230,3 +228,4 @@ translate: async (text, target_language, args = {}) => {

status_code: response.status_code,
translated_content: translated_content.content
translated_content: translated_content.content,
data: response.data
}

@@ -239,3 +238,3 @@ },

* @param {string} channel_id
* @returns {Promise.<{ success: boolean; status_code: string; }>}
* @returns {Promise.<{ success: boolean; status_code: number; data: object; }>}
*/

@@ -248,3 +247,3 @@ subscribe: (channel_id) => this.actions.engage('subscription/subscribe', { channel_id }),

* @param {string} channel_id
* @returns {Promise.<{ success: boolean; status_code: string; }>}
* @returns {Promise.<{ success: boolean; status_code: number; data: object; }>}
*/

@@ -259,3 +258,3 @@ unsubscribe: (channel_id) => this.actions.engage('subscription/unsubscribe', { channel_id }),

* @param {string} type PERSONALIZED | ALL | NONE
* @returns {Promise.<{ success: boolean; status_code: string; }>}
* @returns {Promise.<{ success: boolean; status_code: number; data: object; }>}
*/

@@ -270,14 +269,14 @@ setNotificationPreferences: (channel_id, type) => this.actions.notifications('modify_channel_preference', { channel_id, pref: type || 'NONE' }),

* @param {string} title
* @param {string} video_ids
* @param {Array.<string>} video_ids
*
* @returns {Promise.<{ success: boolean; status_code: string; playlist_id: string; }>}
* @returns {Promise.<{ success: boolean; status_code: number; playlist_id: string; data: object; }>}
*/
create: async (title, video_ids) => {
Utils.throwIfMissing({ title, video_ids });
const response = await this.actions.playlist('playlist/create', { title, ids: video_ids });
if (!response.success) return response;
return {
success: true,
success: response.success,
status_code: response.status_code,
playlist_id: response.data.playlistId
playlist_id: response.data.playlistId,
data: response.data
}

@@ -290,12 +289,12 @@ },

* @param {string} playlist_id
* @returns {Promise.<{ success: boolean; status_code: string; playlist_id: string; }>}
* @returns {Promise.<{ success: boolean; status_code: number; playlist_id: string; data: object; }>}
*/
delete: async (playlist_id) => {
Utils.throwIfMissing({ playlist_id });
const response = await this.actions.playlist('playlist/delete', { playlist_id });
if (!response.success) return response;
return {
success: true,
success: response.success,
status_code: response.status_code,
playlist_id
playlist_id: playlistId,
data: response.data
}

@@ -309,5 +308,6 @@ },

* @param {Array.<string>} video_ids
* @returns {Promise.<{ success: boolean; status_code: string; playlist_id: string; }>}
* @returns {Promise.<{ success: boolean; status_code: number; playlist_id: string; data: object; }>}
*/
addVideos: async (playlist_id, video_ids) => {
Utils.throwIfMissing({ playlist_id, video_ids });
const response = await this.actions.playlist('browse/edit_playlist', {

@@ -319,8 +319,7 @@ action: 'ACTION_ADD_VIDEO',

if (!response.success) return response;
return {
success: true,
success: response.success,
status_code: response.status_code,
playlist_id
playlist_id: playlistId,
data: response.data
}

@@ -334,5 +333,7 @@ },

* @param {Array.<string>} video_ids
* @returns {Promise.<{ success: boolean; status_code: string; playlist_id: string; }>}
*
* @returns {Promise.<{ success: boolean; status_code: number; playlist_id: string; data: object; }>}
*/
removeVideos: async (playlist_id, video_ids) => {
Utils.throwIfMissing({ playlist_id, video_ids });
const plinfo = await this.actions.browse(`VL${playlist_id}`);

@@ -351,9 +352,8 @@

});
if (!response.success) return response;
return {
success: true,
success: response.success,
status_code: response.status_code,
playlist_id
playlist_id: playlist_id,
data: response.data
}

@@ -370,11 +370,17 @@ }

* @param {string} new_value
* @returns {Promise.<{ success: boolean; status_code: string; }>}
* @returns {Promise.<{ success: boolean; status_code: number; data: object; }>}
*/
async #setSetting(setting_id, type, new_value) {
Utils.throwIfMissing({ setting_id, type, new_value });
const values = { ON: true, OFF: false };
if (!values.hasOwnProperty(new_value))
throw new Utils.InnertubeError('Invalid option', { option: new_value, available_options: Object.keys(values) });
const response = await this.actions.browse(type);
if (!response.success) return response;
const contents = ({
account_notifications: () => Utils.findNode(response.data, 'contents', 'Your preferences', 13, false).options,
account_privacy: () => Utils.findNode(response.data, 'contents', 'settingsSwitchRenderer', 13, false).options
SPaccount_notifications: () => Utils.findNode(response.data, 'contents', 'Your preferences', 13, false).options,
SPaccount_privacy: () => Utils.findNode(response.data, 'contents', 'settingsSwitchRenderer', 13, false).options
})[type.trim()]();

@@ -385,8 +391,8 @@

const setting_item_id = option.settingsSwitchRenderer.enableServiceEndpoint.setSettingEndpoint.settingItemId;
const set_setting = await this.actions.account('account/set_setting', { new_value: type == 'account_privacy' ? !new_value : new_value, setting_item_id });
const set_setting = await this.actions.account('account/set_setting', {
new_value: type == 'SPaccount_privacy' ? !values[new_value] : values[new_value],
setting_item_id
});
return {
success: set_setting.success,
status_code: set_setting.status_code,
}
return set_setting;
}

@@ -445,4 +451,2 @@

const response = await this.actions.account('account/account_menu');
if (!response.success) throw new Utils.InnertubeError('Could not get account info', response);
const menu = Utils.findNode(response, 'actions', 'multiPageMenuRenderer', 6, false);

@@ -464,4 +468,4 @@

* @param {string} options.client - client used to perform the search, can be: `YTMUSIC` or `YOUTUBE`.
* @param {string} options.order - filter results by order, can be: relevance | rating | age | views
* @param {string} options.period - filter videos uploaded within a period, can be: any | hour | day | week | month | year
* @param {string} options.order - filter results by order, can be: relevance | rating | age | views
* @param {string} options.duration - filter video results by duration, can be: any | short | long

@@ -472,8 +476,11 @@ *

*/
async search(query, options = { client: 'YOUTUBE', period: 'any', order: 'relevance', duration: 'any' }) {
const response = await this.actions.search({ query, options, is_ytm: options.client == 'YTMUSIC' });
async search(query, options) {
Utils.throwIfMissing({ query });
const final_options = Object.assign({ client: 'YOUTUBE', period: 'any', duration: 'any', order: 'relevance' }, options);
const response = await this.actions.search({ query, options: final_options, is_ytm: final_options.client == 'YTMUSIC' });
const results = new Parser(this, response.data, {
query,
client: options.client,
client: final_options.client,
data_type: 'SEARCH'

@@ -495,4 +502,5 @@ }).parse();

async getSearchSuggestions(input, options = { client: 'YOUTUBE' }) {
Utils.throwIfMissing({ input });
const response = await this.actions.getSearchSuggestions(options.client, input);
if (!response.success) throw new Utils.InnertubeError('Could not get search suggestions', response);
if (options.client === 'YTMUSIC' && !response.data.contents) return [];

@@ -516,8 +524,8 @@

async getDetails(video_id) {
if (!video_id) throw new Utils.MissingParamError('Video id is missing');
Utils.throwIfMissing({ video_id });
const response = await this.actions.getVideoInfo(video_id);
const continuation = await this.actions.next({ video_id });
continuation.success && (response.continuation = continuation.data);
response.continuation = continuation.data;
const details = new Parser(this, response, {

@@ -553,2 +561,4 @@ client: 'YOUTUBE',

async getComments(video_id, sort_by) {
Utils.throwIfMissing({ video_id });
const payload = Proto.encodeCommentsSectionParams(video_id, {

@@ -559,4 +569,2 @@ sort_by: sort_by || 'TOP_COMMENTS'

const response = await this.actions.next({ ctoken: payload });
if (!response.success) throw new Utils.InnertubeError('Could not retrieve comments', response);
const comments = new Parser(this, response.data, {

@@ -578,5 +586,6 @@ video_id,

async getChannel(id) {
Utils.throwIfMissing({ id });
const response = await this.actions.browse(id);
if (!response.success) throw new Utils.InnertubeError('Could not retrieve channel info.', response);
const channel_info = new Parser(this, response.data, {

@@ -596,4 +605,3 @@ client: 'YOUTUBE',

const response = await this.actions.browse('FEhistory');
if (!response.success) throw new Utils.InnertubeError('Could not retrieve watch history', response);
const history = new Parser(this, response, {

@@ -613,4 +621,3 @@ client: 'YOUTUBE',

const response = await this.actions.browse('FEwhat_to_watch');
if (!response.success) throw new Utils.InnertubeError('Could not retrieve home feed', response);
const homefeed = new Parser(this, response, {

@@ -633,4 +640,3 @@ client: 'YOUTUBE',

const response = await this.actions.browse('FEtrending');
if (!response.success) throw new Utils.InnertubeError('Could not retrieve trending content', response);
const trending = new Parser(this, response, {

@@ -649,4 +655,3 @@ client: 'YOUTUBE',

const response = await this.actions.browse('FElibrary');
if (!response.success) throw new Utils.InnertubeError('Could not retrieve library', response);
const library = new Parser(this, response.data, {

@@ -666,4 +671,3 @@ client: 'YOUTUBE',

const response = this.actions.browse('FEsubscriptions');
if (!response.success) throw new Utils.InnertubeError('Could not retrieve subscriptions feed', response);
const subsfeed = new Parser(this, response, {

@@ -683,4 +687,3 @@ client: 'YOUTUBE',

const response = await this.actions.notifications('get_notification_menu');
if (!response.success) throw new Utils.InnertubeError('Could not fetch notifications', response);
const notifications = new Parser(this, response.data, {

@@ -700,3 +703,2 @@ client: 'YOUTUBE',

const response = await this.actions.notifications('get_unseen_count');
if (!response.success) throw new Utils.InnertubeError('Could not get unseen notifications count', response);
return response.data.unseenCount;

@@ -712,9 +714,9 @@ }

async getLyrics(video_id) {
Utils.throwIfMissing({ video_id });
const continuation = await this.actions.next({ video_id: video_id, is_ytm: true });
if (!continuation.success) throw new Utils.InnertubeError('Could not retrieve lyrics', continuation);
const lyrics_tab = Utils.findNode(continuation, 'contents', 'Lyrics', 8, false);
const response = await this.actions.browse(lyrics_tab.endpoint?.browseEndpoint.browseId, { is_ytm: true });
if (!response.success || !response.data?.contents?.sectionListRenderer) throw new Utils.UnavailableContentError('Lyrics not available', { video_id });
if (!response.data?.contents?.sectionListRenderer) throw new Utils.UnavailableContentError('Lyrics not available', { video_id });

@@ -736,5 +738,5 @@ const lyrics = Utils.findNode(response.data, 'contents', 'runs', 6, false);

async getPlaylist(playlist_id, options = { client: 'YOUTUBE' }) {
Utils.throwIfMissing({ playlist_id });
const response = await this.actions.browse(`VL${playlist_id}`, { is_ytm: options.client == 'YTMUSIC' });
if (!response.success) throw new Utils.InnertubeError('Could not get playlist', response);
const playlist = new Parser(this, response.data, {

@@ -814,3 +816,3 @@ client: options.client,

*
* @param {string} id - video id
* @param {string} video_id - video id
* @param {object} options - download options.

@@ -823,3 +825,5 @@ * @param {string} options.quality - video quality; 360p, 720p, 1080p, etc...

*/
async getStreamingData(id, options = {}) {
async getStreamingData(video_id, options = {}) {
Utils.throwIfMissing({ video_id });
options.quality = options.quality || '360p';

@@ -829,3 +833,3 @@ options.type = options.type || 'videoandaudio';

const data = await this.actions.getVideoInfo(id);
const data = await this.actions.getVideoInfo(video_id);
const streaming_data = this.#chooseFormat(options, data);

@@ -842,3 +846,3 @@

*
* @param {string} id - video id
* @param {string} video_id - video id
* @param {object} options - download options.

@@ -851,5 +855,5 @@ * @param {string} [options.quality] - video quality; 360p, 720p, 1080p, etc...

*/
download(id, options = {}) {
if (!id) throw new Utils.MissingParamError('Video id is missing');
download(video_id, options = {}) {
Utils.throwIfMissing({ video_id });
options.quality = options.quality || '360p';

@@ -865,3 +869,3 @@ options.type = options.type || 'videoandaudio';

const stream = new Stream.PassThrough();
this.actions.getVideoInfo(id, cpn).then(async (video_data) => {
this.actions.getVideoInfo(video_id, cpn).then(async (video_data) => {
if (video_data.playabilityStatus.status === 'LOGIN_REQUIRED')

@@ -868,0 +872,0 @@ return stream.emit('error', { message: 'You must login to download age-restricted videos.', error_type: 'LOGIN_REQUIRED', playability_status: video_data.playabilityStatus.status });

@@ -72,4 +72,3 @@ 'use strict';

const response = await this.session.actions.search({ ctoken, is_ytm: false });
if (!response.success) throw new Utils.InnertubeError('Could not get continuation', response);
const continuation_items = Utils.findNode(response.data, 'onResponseReceivedCommands', 'itemSectionRenderer', 4, false);

@@ -367,4 +366,3 @@ return parseItems(continuation_items);

const response = await this.session.actions.browse(ctoken, { is_ctoken: true });
if (!response.success) throw new Utils.InnertubeError('Could not retrieve continuation', response);
return parseItems(response.data.onResponseReceivedActions[0].appendContinuationItemsAction.continuationItems);

@@ -432,4 +430,3 @@ }

const response = await this.session.actions.browse(ctoken, { is_ctoken: true });
if (!response.success) throw new Utils.InnertubeError('Could not retrieve continuation', response);
const ccontents = Utils.findNode(response.data, 'onResponseReceivedActions', 'itemSectionRenderer', 4, false);

@@ -508,4 +505,3 @@ subsfeed.items = [];

const response = await this.session.actions.notifications('get_notification_menu', { ctoken });
if (!response.success) throw new Utils.InnertubeError('Could not retrieve continuation', response);
return parseItems(response.data.actions[0].appendContinuationItemsAction.continuationItems);

@@ -543,3 +539,2 @@ }

const response = await this.session.actions.browse('FEtrending', { params });
if (!response.success) throw new Utils.InnertubeError('Could not retrieve category videos', response);

@@ -586,4 +581,3 @@ const tabs = Utils.findNode(response, 'contents', 'tabRenderer', 4, false);

const response = await this.session.actions.browse(ctoken, { is_ctoken: true });
if (!response.success) throw new Utils.InnertubeError('Could not retrieve continuation', response);
history.items = [];

@@ -590,0 +584,0 @@

@@ -27,7 +27,9 @@ 'use strict';

*
* @param {object} obj - The object.
* @param {string} key - Key of the property being accessed.
* @param {string} target - Anything that might be inside of the property.
* @param {number} depth - Maximum number of nested objects to flatten.
* @param {boolean} safe - If set to true arrays will be preserved.
* @param {object} obj - the object.
* @param {string} key - key of the property being accessed.
* @param {string} target - anything that might be inside of the property.
* @param {number} depth - maximum number of nested objects to flatten.
* @param {boolean} safe - if set to true arrays will be preserved.
*
* @returns {object|Array.<any>}
*/

@@ -42,7 +44,9 @@ function findNode(obj, key, target, depth, safe = true) {

/**
* Gets a string between two delimiters.
* Finds a string between two delimiters.
*
* @param {string} data - The data.
* @param {string} start_string - Start string.
* @param {string} end_string - End string.
* @param {string} data - the data.
* @param {string} start_string - start string.
* @param {string} end_string - end string.
*
* @returns {string}
*/

@@ -93,2 +97,8 @@ function getStringBetweenStrings(data, start_string, end_string) {

/**
* Generates a random string with a given length.
*
* @param {number} length
* @returns {string}
*/
function generateRandomString(length) {

@@ -131,2 +141,25 @@ const result = [];

/**
* Checks if a given client is valid.
*
* @param {string} client
* @returns {boolean}
*/
function isValidClient(client) {
return [ 'YOUTUBE', 'YTMUSIC' ].includes(client);
}
/**
* Throws an error if given parameters are undefined.
*
* @param {object} params
* @returns
*/
function throwIfMissing(params) {
for (const [key, value] of Object.entries(params)) {
if (!value)
throw new MissingParamError(`${key} is missing`);
}
}
/**
* Turns the ntoken transform data into a valid json array

@@ -148,4 +181,4 @@ *

const errors = { InnertubeError, UnavailableContentError, ParsingError, DownloadError, MissingParamError, NoStreamingDataError };
const functions = { findNode, getRandomUserAgent, generateSidAuth, generateRandomString, getStringBetweenStrings, camelToSnake, timeToSeconds, refineNTokenData };
const functions = { findNode, getRandomUserAgent, generateSidAuth, generateRandomString, getStringBetweenStrings, camelToSnake, isValidClient, throwIfMissing, timeToSeconds, refineNTokenData };
module.exports = { ...functions, ...errors };
{
"name": "youtubei.js",
"version": "1.4.2-d.1",
"version": "1.4.2-d.2",
"description": "A full-featured library that allows you to get detailed info about any video, subscribe, unsubscribe, like, dislike, comment, search, download videos/music and much more!",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -50,3 +50,3 @@ <h1 align=center>YouTube.js</h1>

<li><a href="#live-chats">Livechats</a></li>
<li><a href="#download-videos">Download videos</a></li>
<li><a href="#downloading-videos">Downloading videos</a></li>
<li><a href="#signing-in">Signing in</a></li>

@@ -120,16 +120,9 @@ </ul>

To improve performance, the Innertube instance should be initialized once and then reused throughout your program.
### A simple search:
YouTube:
Client: `YOUTUBE` | `YTMUSIC`
```js
const search = await youtube.search('Looking for life on Mars - Documentary');
const search = await youtube.search('Looking for life on Mars - Documentary', { client: 'YOUTUBE' });
```
YTMusic:
```js
const search = await youtube.search('Interstellar Main Theme', { client: 'YTMUSIC' });
```
<details>

@@ -259,5 +252,3 @@ <summary>YouTube Output</summary>

```js
const suggestions = await youtube.getSearchSuggestions('QUERY', {
client: 'YOUTUBE' // Use YTMUSIC if you want music search suggestions
})
const suggestions = await youtube.getSearchSuggestions('QUERY', { client: 'YOUTUBE' })
```

@@ -341,9 +332,10 @@

### Comments
### Comments:
Sorting options: `TOP_COMMENTS` | `NEWEST_FIRST`
```js
// Sorting options: `TOP_COMMENTS` and `NEWEST_FIRST`
const comments = await youtube.getComments('VIDEO_ID', 'TOP_COMMENTS');
```
Alternatively you can use:
Alternatively, you can use:

@@ -686,12 +678,6 @@ ```js

### Get playlist:
YouTube (default):
```js
const playlist = await youtube.getPlaylist('PLAYLIST_ID');
```
Client: `YOUTUBE` | `YTMUSIC`
YouTube Music:
```js
const playlist = await youtube.getPlaylist('PLAYLIST_ID', {
client: 'YTMUSIC'
});
const playlist = await youtube.getPlaylist('PLAYLIST_ID', { client: 'YOUTUBE' });
```

@@ -762,3 +748,3 @@

The library makes it easy to interact with YouTube programmatically. However, don't forget that you must be signed in to use the following features!
Don't forget that you must be signed in to use some of the following methods!

@@ -807,4 +793,6 @@ * Subscribe/Unsubscribe:

* Change notification preferences:
Options: `ALL` | `NONE` | `PERSONALIZED`
```js
// Options: ALL | NONE | PERSONALIZED
await youtube.interact.setNotificationPreferences('CHANNEL_ID', 'ALL');

@@ -825,3 +813,3 @@ ```

### Account Settings
It is also possible to manage an account's settings:
It is also possible to manage account settings:

@@ -858,5 +846,7 @@ * Get account info:

Options: `ON` | `OFF`
* Subscription notifications:
```js
await youtube.account.settings.notifications.setSubscriptions(true);
await youtube.account.settings.notifications.setSubscriptions('ON');
```

@@ -866,3 +856,3 @@

```js
await youtube.account.settings.notifications.setRecommendedVideos(true);
await youtube.account.settings.notifications.setRecommendedVideos('ON');
```

@@ -872,3 +862,3 @@

```js
await youtube.account.settings.notifications.setChannelActivity(true);
await youtube.account.settings.notifications.setChannelActivity('ON');
```

@@ -878,3 +868,3 @@

```js
await youtube.account.settings.notifications.setCommentReplies(true);
await youtube.account.settings.notifications.setCommentReplies('ON');
```

@@ -884,3 +874,3 @@

```js
await youtube.account.settings.notifications.setSharedContent(true);
await youtube.account.settings.notifications.setSharedContent('ON');
```

@@ -890,5 +880,7 @@

Options: `ON` | `OFF`
* Subscriptions privacy:
```js
await youtube.account.settings.privacy.setSubscriptionsPrivate(true);
await youtube.account.settings.privacy.setSubscriptionsPrivate('ON');
```

@@ -898,3 +890,3 @@

```js
await youtube.account.settings.privacy.setSavedPlaylistsPrivate(true);
await youtube.account.settings.privacy.setSavedPlaylistsPrivate('ON');
```

@@ -946,8 +938,37 @@

### Download videos:
### Downloading videos:
---
```js
const options = {
format: string,
quality: string,
type: string,
range: { start: number, end: number }
};
YouTube.js provides an easy-to-use and simple downloader:
const stream = youtube.download('VIDEO_ID', options);
```
Options:
* format:
`mp4` | `webm` etc.. (note: only formats provided by YouTube are available)
* quality:
`144p`, `240p`, `360p`, `480p`, `720p`, `1080p` etc..
* type:
`video` | `audio` | `videoandaudio`
* range: indicates which bytes should be downloaded
* start: an integer indicating the beginning of the range
* end: an integer indicating the end of the range
Cancel a download:
```js
stream.cancel();
```
Example:
```js
const fs = require('fs');

@@ -996,25 +1017,6 @@ const Innertube = require('youtubei.js');

You can also specify a range:
```js
const stream = youtube.download(VIDEO_ID, {
//...
type: 'videoandaudio',
range: { start: 0, end: 1048576 * 5 }
});
```
Cancel a download:
```js
stream.cancel();
```
Alternatively, you can get the deciphered streaming data and handle the download yourself:
```js
const streaming_data = await youtube.getStreamingData(search.videos[0].id, {
format: 'mp4',
quality: '360p',
type: 'videoandaudio'
});
const streaming_data = await youtube.getStreamingData('VIDEO_ID', options);
```

@@ -1021,0 +1023,0 @@

export = Livechat;
declare class Livechat {
declare class Livechat extends EventEmitter {
constructor(session: any, token: any, channel_id: any, video_id: any);

@@ -13,3 +13,3 @@ ctoken: any;

metadata_ctoken: any;
livechat_poller: any;
livechat_poller: NodeJS.Timeout;
sendMessage(text: any): Promise<any>;

@@ -25,1 +25,2 @@ /**

}
import EventEmitter = require("events");

@@ -11,3 +11,2 @@ export = OAuth;

client_secret: string;
refresh_interval: any;
/**

@@ -14,0 +13,0 @@ * Refreshes the access token if necessary.

@@ -9,4 +9,4 @@ export = Player;

get signature_decipher(): any;
isCached(): any;
isCached(): boolean;
#private;
}

@@ -55,8 +55,9 @@ export = Innertube;

*
* @param {boolean} new_value
* @returns {Promise.<{ success: boolean; status_code: string; }>}
* @param {boolean} new_value - ON | OFF
* @returns {Promise.<{ success: boolean; status_code: number; data: object; }>}
*/
setSubscriptions: (new_value: boolean) => Promise<{
success: boolean;
status_code: string;
status_code: number;
data: object;
}>;

@@ -66,8 +67,9 @@ /**

*
* @param {boolean} new_value
* @returns {Promise.<{ success: boolean; status_code: string; }>}
* @param {boolean} new_value - ON | OFF
* @returns {Promise.<{ success: boolean; status_code: number; data: object; }>}
*/
setRecommendedVideos: (new_value: boolean) => Promise<{
success: boolean;
status_code: string;
status_code: number;
data: object;
}>;

@@ -77,8 +79,9 @@ /**

*
* @param {boolean} new_value
* @returns {Promise.<{ success: boolean; status_code: string; }>}
* @param {boolean} new_value - ON | OFF
* @returns {Promise.<{ success: boolean; status_code: number; data: object; }>}
*/
setChannelActivity: (new_value: boolean) => Promise<{
success: boolean;
status_code: string;
status_code: number;
data: object;
}>;

@@ -88,8 +91,9 @@ /**

*
* @param {boolean} new_value
* @returns {Promise.<{ success: boolean; status_code: string; }>}
* @param {boolean} new_value - ON | OFF
* @returns {Promise.<{ success: boolean; status_code: number; data: object; }>}
*/
setCommentReplies: (new_value: boolean) => Promise<{
success: boolean;
status_code: string;
status_code: number;
data: object;
}>;

@@ -99,8 +103,9 @@ /**

*
* @param {boolean} new_value
* @returns {Promise.<{ success: boolean; status_code: string; }>}
* @param {boolean} new_value - ON | OFF
* @returns {Promise.<{ success: boolean; status_code: number; data: object; }>}
*/
setMentions: (new_value: boolean) => Promise<{
success: boolean;
status_code: string;
status_code: number;
data: object;
}>;

@@ -110,8 +115,9 @@ /**

*
* @param {boolean} new_value
* @returns {Promise.<{ success: boolean; status_code: string; }>}
* @param {boolean} new_value - ON | OFF
* @returns {Promise.<{ success: boolean; status_code: number; data: object; }>}
*/
setSharedContent: (new_value: boolean) => Promise<{
success: boolean;
status_code: string;
status_code: number;
data: object;
}>;

@@ -123,8 +129,9 @@ };

*
* @param {boolean} new_value
* @returns {Promise.<{ success: boolean; status_code: string; }>}
* @param {boolean} new_value - ON | OFF
* @returns {Promise.<{ success: boolean; status_code: number; data: object; }>}
*/
setSubscriptionsPrivate: (new_value: boolean) => Promise<{
success: boolean;
status_code: string;
status_code: number;
data: object;
}>;

@@ -134,8 +141,9 @@ /**

*
* @param {boolean} new_value
* @returns {Promise.<{ success: boolean; status_code: string; }>}
* @param {boolean} new_value - ON | OFF
* @returns {Promise.<{ success: boolean; status_code: number; data: object; }>}
*/
setSavedPlaylistsPrivate: (new_value: boolean) => Promise<{
success: boolean;
status_code: string;
status_code: number;
data: object;
}>;

@@ -150,7 +158,8 @@ };

* @param {string} video_id
* @returns {Promise.<{ success: boolean; status_code: string; }>}
* @returns {Promise.<{ success: boolean; status_code: number; data: object; }>}
*/
like: (video_id: string) => Promise<{
success: boolean;
status_code: string;
status_code: number;
data: object;
}>;

@@ -161,7 +170,8 @@ /**

* @param {string} video_id
* @returns {Promise.<{ success: boolean; status_code: string; }>}
* @returns {Promise.<{ success: boolean; status_code: number; data: object; }>}
*/
dislike: (video_id: string) => Promise<{
success: boolean;
status_code: string;
status_code: number;
data: object;
}>;

@@ -172,7 +182,8 @@ /**

* @param {string} video_id
* @returns {Promise.<{ success: boolean; status_code: string; }>}
* @returns {Promise.<{ success: boolean; status_code: number; data: object; }>}
*/
removeLike: (video_id: string) => Promise<{
success: boolean;
status_code: string;
status_code: number;
data: object;
}>;

@@ -184,7 +195,8 @@ /**

* @param {string} text
* @returns {Promise.<{ success: boolean; status_code: string; }>}
* @returns {Promise.<{ success: boolean; status_code: number; data: object; }>}
*/
comment: (video_id: string, text: string) => Promise<{
success: boolean;
status_code: string;
status_code: number;
data: object;
}>;

@@ -200,3 +212,3 @@ /**

*
* @returns {Promise.<{ success: boolean; status_code: string; }>}
* @returns {Promise.<{ success: boolean; status_code: number; translated_content: string; data: object; }>}
*/

@@ -208,3 +220,5 @@ translate: (text: string, target_language: string, args?: {

success: boolean;
status_code: string;
status_code: number;
translated_content: string;
data: object;
}>;

@@ -215,7 +229,8 @@ /**

* @param {string} channel_id
* @returns {Promise.<{ success: boolean; status_code: string; }>}
* @returns {Promise.<{ success: boolean; status_code: number; data: object; }>}
*/
subscribe: (channel_id: string) => Promise<{
success: boolean;
status_code: string;
status_code: number;
data: object;
}>;

@@ -226,7 +241,8 @@ /**

* @param {string} channel_id
* @returns {Promise.<{ success: boolean; status_code: string; }>}
* @returns {Promise.<{ success: boolean; status_code: number; data: object; }>}
*/
unsubscribe: (channel_id: string) => Promise<{
success: boolean;
status_code: string;
status_code: number;
data: object;
}>;

@@ -239,7 +255,8 @@ /**

* @param {string} type PERSONALIZED | ALL | NONE
* @returns {Promise.<{ success: boolean; status_code: string; }>}
* @returns {Promise.<{ success: boolean; status_code: number; data: object; }>}
*/
setNotificationPreferences: (channel_id: string, type: string) => Promise<{
success: boolean;
status_code: string;
status_code: number;
data: object;
}>;

@@ -252,10 +269,11 @@ };

* @param {string} title
* @param {string} video_ids
* @param {Array.<string>} video_ids
*
* @returns {Promise.<{ success: boolean; status_code: string; playlist_id: string; }>}
* @returns {Promise.<{ success: boolean; status_code: number; playlist_id: string; data: object; }>}
*/
create: (title: string, video_ids: string) => Promise<{
create: (title: string, video_ids: Array<string>) => Promise<{
success: boolean;
status_code: string;
status_code: number;
playlist_id: string;
data: object;
}>;

@@ -266,8 +284,9 @@ /**

* @param {string} playlist_id
* @returns {Promise.<{ success: boolean; status_code: string; playlist_id: string; }>}
* @returns {Promise.<{ success: boolean; status_code: number; playlist_id: string; data: object; }>}
*/
delete: (playlist_id: string) => Promise<{
success: boolean;
status_code: string;
status_code: number;
playlist_id: string;
data: object;
}>;

@@ -279,8 +298,9 @@ /**

* @param {Array.<string>} video_ids
* @returns {Promise.<{ success: boolean; status_code: string; playlist_id: string; }>}
* @returns {Promise.<{ success: boolean; status_code: number; playlist_id: string; data: object; }>}
*/
addVideos: (playlist_id: string, video_ids: Array<string>) => Promise<{
success: boolean;
status_code: string;
status_code: number;
playlist_id: string;
data: object;
}>;

@@ -292,8 +312,10 @@ /**

* @param {Array.<string>} video_ids
* @returns {Promise.<{ success: boolean; status_code: string; playlist_id: string; }>}
*
* @returns {Promise.<{ success: boolean; status_code: number; playlist_id: string; data: object; }>}
*/
removeVideos: (playlist_id: string, video_ids: Array<string>) => Promise<{
success: boolean;
status_code: string;
status_code: number;
playlist_id: string;
data: object;
}>;

@@ -341,4 +363,4 @@ };

* @param {string} options.client - client used to perform the search, can be: `YTMUSIC` or `YOUTUBE`.
* @param {string} options.order - filter results by order, can be: relevance | rating | age | views
* @param {string} options.period - filter videos uploaded within a period, can be: any | hour | day | week | month | year
* @param {string} options.order - filter results by order, can be: relevance | rating | age | views
* @param {string} options.duration - filter video results by duration, can be: any | short | long

@@ -349,6 +371,6 @@ *

*/
search(query: string, options?: {
search(query: string, options: {
client: string;
order: string;
period: string;
order: string;
duration: string;

@@ -539,3 +561,3 @@ }): Promise<{

*
* @param {string} id - video id
* @param {string} video_id - video id
* @param {object} options - download options.

@@ -548,3 +570,3 @@ * @param {string} options.quality - video quality; 360p, 720p, 1080p, etc...

*/
getStreamingData(id: string, options?: {
getStreamingData(video_id: string, options?: {
quality: string;

@@ -560,3 +582,3 @@ type: string;

*
* @param {string} id - video id
* @param {string} video_id - video id
* @param {object} options - download options.

@@ -569,3 +591,3 @@ * @param {string} [options.quality] - video quality; 360p, 720p, 1080p, etc...

*/
download(id: string, options?: {
download(video_id: string, options?: {
quality?: string;

@@ -577,3 +599,5 @@ type?: string;

}
import EventEmitter = require("events");
import Request = require("./utils/Request");
import Actions = require("./core/Actions");
import Stream = require("stream");

@@ -20,9 +20,11 @@ export class InnertubeError extends Error {

*
* @param {object} obj - The object.
* @param {string} key - Key of the property being accessed.
* @param {string} target - Anything that might be inside of the property.
* @param {number} depth - Maximum number of nested objects to flatten.
* @param {boolean} safe - If set to true arrays will be preserved.
* @param {object} obj - the object.
* @param {string} key - key of the property being accessed.
* @param {string} target - anything that might be inside of the property.
* @param {number} depth - maximum number of nested objects to flatten.
* @param {boolean} safe - if set to true arrays will be preserved.
*
* @returns {object|Array.<any>}
*/
export function findNode(obj: object, key: string, target: string, depth: number, safe?: boolean): any;
export function findNode(obj: object, key: string, target: string, depth: number, safe?: boolean): object | Array<any>;
/**

@@ -42,10 +44,18 @@ * Returns a random user agent.

export function generateSidAuth(sid: string): string;
export function generateRandomString(length: any): string;
/**
* Gets a string between two delimiters.
* Generates a random string with a given length.
*
* @param {string} data - The data.
* @param {string} start_string - Start string.
* @param {string} end_string - End string.
* @param {number} length
* @returns {string}
*/
export function generateRandomString(length: number): string;
/**
* Finds a string between two delimiters.
*
* @param {string} data - the data.
* @param {string} start_string - start string.
* @param {string} end_string - end string.
*
* @returns {string}
*/
export function getStringBetweenStrings(data: string, start_string: string, end_string: string): string;

@@ -60,2 +70,16 @@ /**

/**
* Checks if a given client is valid.
*
* @param {string} client
* @returns {boolean}
*/
export function isValidClient(client: string): boolean;
/**
* Throws an error if given parameters are undefined.
*
* @param {object} params
* @returns
*/
export function throwIfMissing(params: object): void;
/**
* Converts time (h:m:s) to seconds.

@@ -62,0 +86,0 @@ *

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc