ytdl-core
Advanced tools
Comparing version 4.4.1 to 4.4.2
@@ -133,2 +133,62 @@ const utils = require('./utils'); | ||
const parseRelatedVideo = (details, rvsParams) => { | ||
if (!details) return; | ||
try { | ||
let viewCount = getText(details.viewCountText); | ||
let shortViewCount = getText(details.shortViewCountText); | ||
let rvsDetails = rvsParams.find(elem => elem.id === details.videoId); | ||
if (!/^\d/.test(shortViewCount)) { | ||
shortViewCount = (rvsDetails && rvsDetails.short_view_count_text) || ''; | ||
} | ||
viewCount = (/^\d/.test(viewCount) ? viewCount : shortViewCount).split(' ')[0]; | ||
let browseEndpoint = details.shortBylineText.runs[0].navigationEndpoint.browseEndpoint; | ||
let channelId = browseEndpoint.browseId; | ||
let name = getText(details.shortBylineText); | ||
let user = (browseEndpoint.canonicalBaseUrl || '').split('/').slice(-1)[0]; | ||
let video = { | ||
id: details.videoId, | ||
title: getText(details.title), | ||
published: getText(details.publishedTimeText), | ||
author: { | ||
id: channelId, | ||
name, | ||
user, | ||
channel_url: `https://www.youtube.com/channel/${channelId}`, | ||
user_url: `https://www.youtube.com/user/${user}`, | ||
thumbnails: details.channelThumbnail.thumbnails.map(thumbnail => { | ||
thumbnail.url = urllib.resolve(VIDEO_URL, thumbnail.url); | ||
return thumbnail; | ||
}), | ||
verified: isVerified(details.ownerBadges), | ||
[Symbol.toPrimitive]() { | ||
console.warn(`\`relatedVideo.author\` will be removed in a near future release, ` + | ||
`use \`relatedVideo.author.name\` instead.`); | ||
return video.author.name; | ||
}, | ||
}, | ||
short_view_count_text: shortViewCount.split(' ')[0], | ||
view_count: viewCount.replace(/,/g, ''), | ||
length_seconds: details.lengthText ? | ||
Math.floor(parseTimestamp(getText(details.lengthText)) / 1000) : | ||
rvsParams && `${rvsParams.length_seconds}`, | ||
thumbnails: details.thumbnail.thumbnails, | ||
richThumbnails: | ||
details.richThumbnail ? | ||
details.richThumbnail.movingThumbnailRenderer.movingThumbnailDetails.thumbnails : [], | ||
isLive: !!(details.badges && details.badges.find(b => b.metadataBadgeRenderer.label === 'LIVE NOW')), | ||
}; | ||
utils.deprecate(video, 'author_thumbnail', video.author.thumbnails[0].url, | ||
'relatedVideo.author_thumbnail', 'relatedVideo.author.thumbnails[0].url'); | ||
utils.deprecate(video, 'ucid', video.author.id, 'relatedVideo.ucid', 'relatedVideo.author.id'); | ||
utils.deprecate(video, 'video_thumbnail', video.thumbnails[0].url, | ||
'relatedVideo.video_thumbnail', 'relatedVideo.thumbnails[0].url'); | ||
return video; | ||
} catch (err) { | ||
// Skip. | ||
} | ||
}; | ||
/** | ||
@@ -156,57 +216,10 @@ * Get related videos. | ||
if (details) { | ||
try { | ||
let viewCount = getText(details.viewCountText); | ||
let shortViewCount = getText(details.shortViewCountText); | ||
let rvsDetails = rvsParams.find(elem => elem.id === details.videoId); | ||
if (!/^\d/.test(shortViewCount)) { | ||
shortViewCount = (rvsDetails && rvsDetails.short_view_count_text) || ''; | ||
} | ||
viewCount = (/^\d/.test(viewCount) ? viewCount : shortViewCount).split(' ')[0]; | ||
let browseEndpoint = details.shortBylineText.runs[0].navigationEndpoint.browseEndpoint; | ||
let channelId = browseEndpoint.browseId; | ||
let name = getText(details.shortBylineText); | ||
let user = (browseEndpoint.canonicalBaseUrl || '').split('/').slice(-1)[0]; | ||
let video = { | ||
id: details.videoId, | ||
title: getText(details.title), | ||
published: getText(details.publishedTimeText), | ||
author: { | ||
id: channelId, | ||
name, | ||
user, | ||
channel_url: `https://www.youtube.com/channel/${channelId}`, | ||
user_url: `https://www.youtube.com/user/${user}`, | ||
thumbnails: details.channelThumbnail.thumbnails.map(thumbnail => { | ||
thumbnail.url = urllib.resolve(VIDEO_URL, thumbnail.url); | ||
return thumbnail; | ||
}), | ||
verified: isVerified(details.ownerBadges), | ||
[Symbol.toPrimitive]() { | ||
console.warn(`\`relatedVideo.author\` will be removed in a near future release, ` + | ||
`use \`relatedVideo.author.name\` instead.`); | ||
return video.author.name; | ||
}, | ||
}, | ||
short_view_count_text: shortViewCount.split(' ')[0], | ||
view_count: viewCount.replace(/,/g, ''), | ||
length_seconds: details.lengthText ? | ||
Math.floor(parseTimestamp(getText(details.lengthText)) / 1000) : | ||
rvsParams && `${rvsParams.length_seconds}`, | ||
thumbnails: details.thumbnail.thumbnails, | ||
richThumbnails: | ||
details.richThumbnail ? | ||
details.richThumbnail.movingThumbnailRenderer.movingThumbnailDetails.thumbnails : [], | ||
isLive: !!(details.badges && details.badges.find(b => b.metadataBadgeRenderer.label === 'LIVE NOW')), | ||
}; | ||
utils.deprecate(video, 'author_thumbnail', video.author.thumbnails[0].url, | ||
'relatedVideo.author_thumbnail', 'relatedVideo.author.thumbnails[0].url'); | ||
utils.deprecate(video, 'ucid', video.author.id, 'relatedVideo.ucid', 'relatedVideo.author.id'); | ||
utils.deprecate(video, 'video_thumbnail', video.thumbnails[0].url, | ||
'relatedVideo.video_thumbnail', 'relatedVideo.thumbnails[0].url'); | ||
videos.push(video); | ||
} catch (err) { | ||
// Skip. | ||
let video = parseRelatedVideo(details, rvsParams); | ||
if (video) videos.push(video); | ||
} else { | ||
let autoplay = result.compactAutoplayRenderer || result.itemSectionRenderer; | ||
if (!autoplay || !Array.isArray(autoplay.contents)) continue; | ||
for (let content of autoplay.contents) { | ||
let video = parseRelatedVideo(content.compactVideoRenderer, rvsParams); | ||
if (video) videos.push(video); | ||
} | ||
@@ -213,0 +226,0 @@ } |
@@ -9,3 +9,3 @@ { | ||
], | ||
"version": "4.4.1", | ||
"version": "4.4.2", | ||
"repository": { | ||
@@ -12,0 +12,0 @@ "type": "git", |
@@ -111,2 +111,11 @@ declare module 'ytdl-core' { | ||
interface audioTrack { | ||
captionTrackIndices: number[]; | ||
} | ||
interface translationLanguage { | ||
languageCode: captionTrack['languageCode']; | ||
languageName: captionTrack['name']; | ||
} | ||
interface VideoDetails { | ||
@@ -117,4 +126,5 @@ videoId: string; | ||
lengthSeconds: string; | ||
keywords: string[]; | ||
keywords?: string[]; | ||
channelId: string; | ||
isOwnerViewing: boolean; | ||
isCrawlable: boolean; | ||
@@ -179,3 +189,3 @@ thumbnail: { | ||
ownerProfileUrl: string; | ||
ownerGplusProfileUrl: string; | ||
ownerGplusProfileUrl?: string; | ||
externalChannelId: string; | ||
@@ -212,4 +222,4 @@ isFamilySafe: boolean; | ||
age_restricted: boolean; | ||
likes?: number; | ||
dislikes?: number; | ||
likes: number | null; | ||
dislikes: number | null; | ||
media: Media; | ||
@@ -219,2 +229,3 @@ author: Author; | ||
storyboards: storyboard[]; | ||
description: string | null; | ||
} | ||
@@ -339,2 +350,9 @@ | ||
status: string; | ||
playableInEmbed: boolean; | ||
miniplayer: { | ||
miniplayerRenderer: { | ||
playbackMode: string; | ||
}; | ||
}; | ||
contextParams: string; | ||
}; | ||
@@ -347,4 +365,11 @@ streamingData: { | ||
captions?: { | ||
playerCaptionsRenderer: { | ||
baseUrl: string; | ||
visibility: string; | ||
}; | ||
playerCaptionsTracklistRenderer: { | ||
captionTracks: captionTrack[]; | ||
audioTracks: audioTrack[]; | ||
translationLanguages: translationLanguage[]; | ||
defaultAudioTrackIndex: number; | ||
}; | ||
@@ -351,0 +376,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
91441
2448