ytdl-core
Advanced tools
Comparing version 4.1.3 to 4.1.4
@@ -112,3 +112,3 @@ const utils = require('./utils'); | ||
let videoDetails = info.player_response.microformat && info.player_response.microformat.playerMicroformatRenderer; | ||
let id = videoDetails ? videoDetails.channelId : channelId; | ||
let id = (videoDetails && videoDetails.channelId) || channelId || info.player_response.videoDetails.channelId; | ||
let author = { | ||
@@ -125,3 +125,5 @@ id: id, | ||
}; | ||
utils.deprecate(author, 'avatar', author.thumbnails[0].url, 'author.avatar', 'author.thumbnails[0].url'); | ||
if (thumbnails.length) { | ||
utils.deprecate(author, 'avatar', author.thumbnails[0].url, 'author.avatar', 'author.thumbnails[0].url'); | ||
} | ||
return author; | ||
@@ -128,0 +130,0 @@ } catch (err) { |
@@ -50,3 +50,3 @@ const urllib = require('url'); | ||
} | ||
return info && ( | ||
return info && info.player_response && ( | ||
info.player_response.streamingData || isRental(info.player_response) || isNotYetBroadcasted(info.player_response) | ||
@@ -56,4 +56,4 @@ ); | ||
let info = await pipeline([id, options], validate, retryOptions, [ | ||
getJSONWatchPage, | ||
getEmbedPage, | ||
getWatchJSONPage, | ||
getWatchHTMLPage, | ||
getVideoInfoPage, | ||
@@ -81,4 +81,5 @@ ]); | ||
info.videoDetails = Object.assign({}, | ||
info.player_response && info.player_response.microformat && | ||
info.player_response.microformat.playerMicroformatRenderer, | ||
info.player_response.videoDetails, additional); | ||
info.player_response && info.player_response.videoDetails, additional); | ||
@@ -153,6 +154,8 @@ return info; | ||
const newInfo = await retryFunc(func, args.concat([info]), retryOptions); | ||
newInfo.player_response.videoDetails = assign( | ||
info && info.player_response && info.player_response.videoDetails, | ||
newInfo.player_response.videoDetails); | ||
newInfo.player_response = assign(info && info.player_response, newInfo.player_response); | ||
if (newInfo.player_response) { | ||
newInfo.player_response.videoDetails = assign( | ||
info && info.player_response && info.player_response.videoDetails, | ||
newInfo.player_response.videoDetails); | ||
newInfo.player_response = assign(info && info.player_response, newInfo.player_response); | ||
} | ||
info = assign(info, newInfo); | ||
@@ -224,3 +227,3 @@ if (validate(info, false)) { | ||
const jsonClosingChars = /^[)\]}'\s]+/; | ||
const parseJSON = (source, json) => { | ||
const parseJSON = (source, varName, json) => { | ||
if (!json || typeof json === 'object') { | ||
@@ -233,3 +236,3 @@ return json; | ||
} catch (err) { | ||
throw Error(`Error parsing ${source}: ${err.message}`); | ||
throw Error(`Error parsing ${varName} in ${source}: ${err.message}`); | ||
} | ||
@@ -240,7 +243,16 @@ } | ||
const findJSON = (source, varName, body, left, right, prependJSON = '') => { | ||
let jsonStr = utils.between(body, left, right); | ||
if (!jsonStr) { | ||
throw Error(`Could not find ${varName} in ${source}`); | ||
} | ||
return parseJSON(source, varName, utils.cutAfterJSON(`${prependJSON}${jsonStr}`)); | ||
}; | ||
const findPlayerResponse = (source, info) => { | ||
const player_response = info && ( | ||
(info.player && info.player.args && info.player.args.player_response) || | ||
(info.args && info.args.player_response) || | ||
info.player_response || info.playerResponse || info.embedded_player_response); | ||
return parseJSON(source, player_response); | ||
return parseJSON(source, 'player_response', player_response); | ||
}; | ||
@@ -250,3 +262,3 @@ | ||
const getWatchJSONURL = (id, options) => `${getHTMLWatchURL(id, options)}&pbj=1`; | ||
const getJSONWatchPage = async(id, options) => { | ||
const getWatchJSONPage = async(id, options) => { | ||
const reqOptions = Object.assign({ headers: {} }, options.requestOptions); | ||
@@ -271,4 +283,3 @@ let cookie = reqOptions.headers.Cookie || reqOptions.headers.cookie; | ||
let body = await miniget(jsonUrl, reqOptions).text(); | ||
let parsedBody; | ||
parsedBody = parseJSON('watch.json', body); | ||
let parsedBody = parseJSON('watch.json', 'body', body); | ||
if (parsedBody.reload === 'now') { | ||
@@ -281,3 +292,3 @@ await setIdentityToken('browser', false); | ||
let info = parsedBody.reduce((part, curr) => Object.assign(curr, part), {}); | ||
info.player_response = findPlayerResponse('watch.json `player_response`', info); | ||
info.player_response = findPlayerResponse('watch.json', info); | ||
info.html5player = info.player && info.player.assets && info.player.assets.js; | ||
@@ -289,22 +300,13 @@ | ||
/** | ||
* If the video page doesn't work, maybe because it has mature content. | ||
* and requires an account logged in to view, try the embed page. | ||
* | ||
* @param {string} id | ||
* @param {Object} options | ||
* @returns {string} | ||
*/ | ||
const EMBED_URL = 'https://www.youtube.com/embed/'; | ||
const getEmbedURL = (id, options) => `${EMBED_URL + id}?hl=${options.lang || 'en'}`; | ||
const getEmbedPage = async(id, options) => { | ||
const embedUrl = getEmbedURL(id, options); | ||
let body = await miniget(embedUrl, options.requestOptions).text(); | ||
let configJson = utils.between(body, /(['"])PLAYER_(CONFIG|VARS)\1:\s?/, '</script>'); | ||
if (!configJson) { | ||
throw Error('Could not find player config in embed.html'); | ||
const getWatchHTMLPage = async(id, options) => { | ||
let body = await getHTMLWatchPageBody(id, options); | ||
let info = { page: 'watch' }; | ||
try { | ||
info.player_response = findJSON('watch.html', 'player_response', | ||
body, /\bytInitialPlayerResponse\s*=\s*\{/i, '\n', '{'); | ||
} catch (err) { | ||
let args = findJSON('watch.html', 'player_response', body, /\bytplayer\.config\s*=\s*{/, '</script>', '{'); | ||
info.player_response = findPlayerResponse('watch.html', args); | ||
} | ||
let config = parseJSON('embed config', utils.cutAfterJSON(configJson)); | ||
let info = config.args || config; | ||
info.player_response = findPlayerResponse('embed `player_response`', info); | ||
info.response = findJSON('watch.html', 'response', body, /\bytInitialData("\])?\s*=\s*\{/i, '\n', '{'); | ||
info.html5player = getHTML5player(body); | ||
@@ -333,3 +335,3 @@ return info; | ||
let info = querystring.parse(body); | ||
info.player_response = findPlayerResponse('get_video_info `player_response`', info); | ||
info.player_response = findPlayerResponse('get_video_info', info); | ||
return info; | ||
@@ -345,3 +347,3 @@ }; | ||
let formats = []; | ||
if (player_response.streamingData) { | ||
if (player_response && player_response.streamingData) { | ||
formats = formats | ||
@@ -348,0 +350,0 @@ .concat(player_response.streamingData.formats || []) |
@@ -9,3 +9,3 @@ { | ||
], | ||
"version": "4.1.3", | ||
"version": "4.1.4", | ||
"repository": { | ||
@@ -12,0 +12,0 @@ "type": "git", |
@@ -149,3 +149,3 @@ declare module 'ytdl-core' { | ||
avatar: string; // to remove later | ||
thumbnails: thumbnail[]; | ||
thumbnails?: thumbnail[]; | ||
verified: boolean; | ||
@@ -156,3 +156,3 @@ user?: string; | ||
user_url?: string; | ||
subscriber_count: number; | ||
subscriber_count?: number; | ||
} | ||
@@ -159,0 +159,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
86254
2313