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

ytdl-core

Package Overview
Dependencies
Maintainers
1
Versions
186
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ytdl-core - npm Package Compare versions

Comparing version 2.1.5 to 3.0.0

10

lib/index.js

@@ -17,11 +17,5 @@ const PassThrough = require('stream').PassThrough;

const stream = createStream(options);
ytdl.getInfo(link, options, (err, info) => {
if (err) {
stream.emit('error', err);
return;
}
ytdl.getInfo(link, options).then(info => {
downloadFromInfoCallback(stream, info, options);
});
}, stream.emit.bind(stream, 'error'));
return stream;

@@ -28,0 +22,0 @@ };

@@ -44,8 +44,2 @@ const util = require('./util');

let contents = row.richMetadataRowRenderer.contents;
for (let content of contents) {
let meta = content.richMetadataRenderer;
media.thumbnails = meta.thumbnail.thumbnails;
// TODO: Added for backwards compatibility. Remove later.
media.image = urllib.resolve(VIDEO_URL, media.thumbnails[0].url);
}
let richMeta = contents

@@ -60,2 +54,6 @@ .filter(meta => meta.richMetadataRenderer.style === 'RICH_METADATA_RENDERER_STYLE_BOX_ART');

meta.endpoint.commandMetadata.webCommandMetadata.url);
media.thumbnails = meta.thumbnail.thumbnails;
// TODO: Added for backwards compatibility. Remove later.
util.deprecate(media, 'image', urllib.resolve(VIDEO_URL, media.thumbnails[0].url),
'info.videoDetails.media.image', 'info.videoDetails.media.thumbnails');
}

@@ -62,0 +60,0 @@ }

113

lib/info.js

@@ -38,3 +38,3 @@ const urllib = require('url');

let [, body] = await miniget.promise(url, reqOptions);
let body = await miniget(url, reqOptions).text();
let info;

@@ -56,3 +56,3 @@ try {

let embedUrl = `${EMBED_URL + id}?${params}`;
[, body] = await miniget.promise(embedUrl, options.requestOptions);
body = await miniget(embedUrl, options.requestOptions).text();
let jsonStr = util.between(body, 't.setConfig({\'PLAYER_CONFIG\': ', '</script>');

@@ -104,25 +104,25 @@ let config;

const gotConfig = async(id, options, info, body) => {
const url = urllib.format({
protocol: 'https',
host: INFO_HOST,
pathname: INFO_PATH,
query: {
video_id: id,
eurl: VIDEO_EURL + id,
ps: 'default',
gl: 'US',
hl: options.lang || 'en',
sts: info.sts,
},
});
let [, morebody] = await miniget.promise(url, options.requestOptions);
let moreinfo = querystring.parse(morebody);
const player_response =
(info.player && info.player.args && info.player.args.player_response) ||
moreinfo.player_response ||
info.playerResponse;
let player_response =
info.player && info.player.args && info.player.args.player_response;
if (moreinfo.status === 'fail') {
throw Error(`Code ${moreinfo.errorcode}: ${util.stripHTML(moreinfo.reason)}`);
} else if (typeof player_response === 'object') {
if (!player_response) {
const url = urllib.format({
protocol: 'https',
host: INFO_HOST,
pathname: INFO_PATH,
query: {
video_id: id,
eurl: VIDEO_EURL + id,
ps: 'default',
gl: 'US',
hl: options.lang || 'en',
sts: info.sts,
},
});
let morebody = await miniget(url, options.requestOptions).text();
let moreinfo = querystring.parse(morebody);
player_response = moreinfo.player_response || info.playerResponse;
}
if (typeof player_response === 'object') {
info.player_response = player_response;

@@ -140,40 +140,36 @@ } else {

// Add additional properties to info.
// TODO: Clean up some of these properties that would be better accessed
// directly through `videoDetails`.
let videoDetails = info.player_response.videoDetails;
Object.assign(info, {
// Get the author/uploader.
let additional = {
author: extras.getAuthor(info),
// Get the day the vid was published.
published: Date.parse(
info.player_response.microformat.playerMicroformatRenderer.publishDate,
),
// Get description.
description: videoDetails.shortDescription,
// Get media info.
media: extras.getMedia(body),
// Get related videos.
related_videos: extras.getRelatedVideos(info),
// Get likes.
likes: extras.getLikes(body),
// Get dislikes.
dislikes: extras.getDislikes(body),
age_restricted: !!(info.player.args && info.player.args.is_embed),
video_id: videoDetails.videoId,
// Give the standard link to the video.
video_url: VIDEO_URL + videoDetails.videoId,
video_url: VIDEO_URL + id,
};
title: videoDetails.title,
length_seconds: videoDetails.lengthSeconds,
info.videoDetails = Object.assign({},
info.player_response.microformat.playerMicroformatRenderer,
info.player_response.videoDetails, additional);
info.related_videos = extras.getRelatedVideos(info);
info.html5player = info.player && info.player.assets && info.player.assets.js;
age_restricted: !!(info.player.args && info.player.args.is_embed),
html5player: info.player && info.player.assets && info.player.assets.js,
});
// TODO: Remove these warnings later and remove the properties.
// Remember to remove from typings too.
for (let [prop, value] of Object.entries(additional)) {
util.deprecate(info, prop, value, `info.${prop}`, `info.videoDetails.${prop}`);
}
util.deprecate(info, 'published', info.player_response.microformat.playerMicroformatRenderer.publishDate,
'info.published', 'info.videoDetails.publishDate');
let props = {
description: 'shortDescription',
video_id: 'videoId',
title: 'title',
length_seconds: 'lengthSeconds',
};
for (let [oldProp, newProp] of Object.entries(props)) {
util.deprecate(info, oldProp, info.videoDetails[newProp],
`info.${oldProp}`, `info.videoDetails.${newProp}`);
}

@@ -256,3 +252,3 @@ return info;

url = urllib.resolve(VIDEO_URL, url);
let [, body] = await miniget.promise(url, options.requestOptions);
let body = await miniget(url, options.requestOptions).text();
let formats = {};

@@ -281,3 +277,3 @@ body

* @param {Function(Error, Object)} callback
* @returns {Object}
* @returns {Promise<Object>}
*/

@@ -294,2 +290,7 @@ const fn = exports[fnName];

if (callback) {
// TODO: Fully remove callback support in a future release.
// eslint-disable-next-line no-console
console.warn(
`Calling \`ytdl.${fnName}\` with a callback will be removed in a near future release. ` +
`Use async/await.`);
return exports[fnName](link, options)

@@ -296,0 +297,0 @@ .then(info => callback(null, info), callback);

@@ -22,3 +22,3 @@ const url = require('url');

} else {
let [, body] = await miniget.promise(html5playerfile, options.requestOptions);
let body = await miniget(html5playerfile, options.requestOptions).text();
const tokens = exports.extractActions(body);

@@ -199,5 +199,4 @@ if (!tokens || !tokens.length) {

* @param {string} sig
* @param {boolean} debug
*/
exports.setDownloadURL = (format, sig, debug) => {
exports.setDownloadURL = (format, sig) => {
let decodedUrl;

@@ -207,5 +206,2 @@ if (format.url) {

} else {
if (debug) {
console.warn(`Download url not found for itag ${format.itag}`); // eslint-disable-line no-console
}
return;

@@ -217,5 +213,2 @@ }

} catch (err) {
if (debug) {
console.warn(`Could not decode url: ${err.message}`); // eslint-disable-line no-console
}
return;

@@ -265,3 +258,3 @@ }

const sig = tokens && format.s ? exports.decipher(tokens, format.s) : null;
exports.setDownloadURL(format, sig, options.debug);
exports.setDownloadURL(format, sig);
decipheredFormats[format.itag] = format;

@@ -268,0 +261,0 @@ });

@@ -441,1 +441,23 @@ const url = require('url');

};
/**
* Temporary helper to help deprecating a few properties.
*
* @param {Object} obj
* @param {string} prop
* @param {Object} value
* @param {string} oldPath
* @param {string} newPath
*/
exports.deprecate = (obj, prop, value, oldPath, newPath) => {
Object.defineProperty(obj, prop, {
get: () => {
// eslint-disable-next-line no-console
console.warn(
`\`${oldPath}\` will be removed in a near future release, ` +
`use \`${newPath}\` instead.`);
return value;
},
});
};

@@ -9,3 +9,3 @@ {

],
"version": "2.1.5",
"version": "3.0.0",
"repository": {

@@ -39,3 +39,3 @@ "type": "git",

"m3u8stream": "^0.7.1",
"miniget": "^1.7.2",
"miniget": "^2.0.0",
"sax": "^1.1.3"

@@ -42,0 +42,0 @@ },

@@ -84,9 +84,9 @@ # node-ytdl-core

### ytdl.getBasicInfo(url, [options], [callback(err, info)])
### async ytdl.getBasicInfo(url, [options])
Use this if you only want to get metainfo from a video. If `callback` isn't given, returns a promise.
Use this if you only want to get metainfo from a video.
### ytdl.getInfo(url, [options], [callback(err, info)])
### async ytdl.getInfo(url, [options])
Gets metainfo from a video. Includes additional formats, and ready to download deciphered URL. This is what the `ytdl()` function uses internally. If `callback` isn't given, returns a promise.
Gets metainfo from a video. Includes additional formats, and ready to download deciphered URL. This is what the `ytdl()` function uses internally.

@@ -104,9 +104,5 @@ ### ytdl.downloadFromInfo(info, options)

// Example of choosing a video format.
ytdl.getInfo(videoID, (err, info) => {
if (err) throw err;
let format = ytdl.chooseFormat(info.formats, { quality: '134' });
if (format) {
console.log('Format found!');
}
});
let info = await ytdl.getInfo(videoID);
let format = ytdl.chooseFormat(info.formats, { quality: '134' });
console.log('Format found!', format);
```

@@ -120,7 +116,5 @@

// Example of filtering the formats to audio only.
ytdl.getInfo(videoID, (err, info) => {
if (err) throw err;
let audioFormats = ytdl.filterFormats(info.formats, 'audioonly');
console.log('Formats with only audio: ' + audioFormats.length);
});
let info = await ytdl.getInfo(videoID);
let audioFormats = ytdl.filterFormats(info.formats, 'audioonly');
console.log('Formats with only audio: ' + audioFormats.length);
```

@@ -165,3 +159,3 @@

If you'd like to help fix the issue, look at the type of error first. The most common one is
If you'd like to help fix the issue, look at the type of error first. If you're getting the following error

@@ -174,3 +168,3 @@ Could not extract signature deciphering actions

These tests are not mocked, and they actually try to start downloading a few videos. If these fail, then it's time to debug.
These tests are not mocked, and they try to start downloading a few videos. If these fail, then it's time to debug.

@@ -177,0 +171,0 @@ For getting started with that, you can look at the `extractActions()` function in [`/lib/sig.js`](https://github.com/fent/node-ytdl-core/blob/master/lib/sig.js).

@@ -77,2 +77,94 @@ declare module 'ytdl-core' {

interface VideoDetails {
videoId: string;
title: string;
shortDescription: string;
lengthSeconds: string;
keywords: string[];
channelId: string;
isCrawlable: boolean;
thumbnail: {
thumbnails: thumbnail[];
};
averageRating: number;
allowRatings: boolean;
viewCount: string;
author: string;
isPrivate: boolean;
isUnpluggedCorpus: boolean
isLiveContent: boolean;
}
interface Media {
image?: string;
category: string;
category_url: string;
game?: string;
game_url?: string;
year?: number;
song?: string;
artist?: string;
artist_url?: string;
writers?: string;
licensed_by?: string;
}
interface Author {
id: string;
name: string;
avatar: string;
verified: boolean;
user: string;
channel_url: string;
external_channel_url: string;
user_url: string;
subscriber_count: number;
}
interface MicroformatRenderer {
thumbnail: {
thumbnails: thumbnail[];
};
embed: {
iframeUrl: string;
flashUrl: string;
width: number;
height: number;
flashSecureUrl: string;
};
title: {
simpleText: string;
};
description: {
simpleText: string;
};
lengthSeconds: string;
ownerProfileUrl: string;
ownerGplusProfileUrl: string;
externalChannelId: string;
isFamilySafe: boolean;
availableCountries: string[];
isUnlisted: boolean;
hasYpcMetadata: boolean;
viewCount: string;
category: string;
publishDate: string;
ownerChannelName: string;
liveBroadcastDetails?: {
isLiveNow: boolean;
startTimestamp: string;
}
uploadDate: string;
}
interface MoreVideoDetails extends Omit<VideoDetails, 'author'>, Omit<MicroformatRenderer, 'title' | 'description'> {
published: number;
video_url: string;
age_restricted: boolean;
likes?: number;
dislikes?: number;
media: Media;
author: Author;
}
type videoInfo = {

@@ -115,26 +207,4 @@ iv_load_policy?: string;

pltype: string;
media: {
image?: string;
category: string;
category_url: string;
game?: string;
game_url?: string;
year?: number;
song?: string;
artist?: string;
artist_url?: string;
writers?: string;
licensed_by?: string;
};
author: {
id: string;
name: string;
avatar: string;
verified: boolean;
user: string;
channel_url: string;
external_channel_url: string;
user_url: string;
subscriber_count: number;
};
media: Media;
author: Author;
enabled_engage_types: string;

@@ -241,49 +311,7 @@ hl: string;

microformat: {
playerMicroformatRenderer: {
thumbnail: {
thumbnails: thumbnail[];
};
embed: {
iframeUrl: string;
flashUrl: string;
width: number;
height: number;
flashSecureUrl: string;
};
title: {
simpleText: string;
};
description: {
simpleText: string;
};
lengthSeconds: string;
ownerProfileUrl: string;
ownerGplusProfileUrl: string;
externalChannelId: string;
isFamilySafe: boolean;
availableCountries: string[];
isUnlisted: boolean;
hasYpcMetadata: boolean;
viewCount: string;
category: string;
publishDate: string;
ownerChannelName: string;
uploadDate: string;
};
playerMicroformatRenderer: MicroformatRenderer;
};
videoDetails: {
videoId: string;
title: string;
lengthSeconds: number;
keywords: string[];
channelId: string;
isCrawlable: boolean;
thumbnail: {
thumbnails: thumbnail[];
};
viewCount: number;
author: string;
isLiveContent: boolean;
};
videoDetails: VideoDetails;
};
videoDetails: MoreVideoDetails;
}

@@ -310,6 +338,6 @@

function getBasicInfo(url: string, callback?: (err: Error, info: videoInfo) => void): Promise<videoInfo>;
function getBasicInfo(url: string, options?: downloadOptions, callback?: (err: Error, info: videoInfo) => void): Promise<videoInfo>;
function getInfo(url: string, callback?: (err: Error, info: videoInfo) => void): Promise<videoInfo>;
function getInfo(url: string, options?: downloadOptions, callback?: (err: Error, info: videoInfo) => void): Promise<videoInfo>;
function getBasicInfo(url: string): Promise<videoInfo>;
function getBasicInfo(url: string, options?: downloadOptions): Promise<videoInfo>;
function getInfo(url: string): Promise<videoInfo>;
function getInfo(url: string, options?: downloadOptions): Promise<videoInfo>;
function downloadFromInfo(info: videoInfo, options?: downloadOptions): Readable;

@@ -316,0 +344,0 @@ function chooseFormat(format: videoFormat | videoFormat[], options?: downloadOptions): videoFormat | never;

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