local API: Fix playlists and podcasts not appearing in search results (#6196)

This commit is contained in:
absidue 2024-11-20 02:08:08 +01:00 committed by GitHub
parent be02c9fe9c
commit 80b4036757
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,4 +1,4 @@
import { ClientType, Endpoints, Innertube, Misc, Parser, UniversalCache, Utils, YT } from 'youtubei.js'
import { ClientType, Endpoints, Innertube, Misc, Parser, UniversalCache, Utils, YT, YTNodes } from 'youtubei.js'
import Autolinker from 'autolinker'
import { SEARCH_CHAR_LIMIT } from '../../../constants'
@ -770,23 +770,7 @@ export function parseLocalChannelShorts(shorts, channelId, channelName) {
*/
export function parseLocalListPlaylist(playlist, channelId = undefined, channelName = undefined) {
if (playlist.type === 'LockupView') {
/** @type {import('youtubei.js').YTNodes.LockupView} */
const lockupView = playlist
/** @type {import('youtubei.js').YTNodes.ThumbnailOverlayBadgeView} */
const thumbnailOverlayBadgeView = lockupView.content_image.primary_thumbnail.overlays
.find(overlay => overlay.type === 'ThumbnailOverlayBadgeView')
return {
type: 'playlist',
dataSource: 'local',
title: lockupView.metadata.title.text,
thumbnail: lockupView.content_image.primary_thumbnail.image[0].url,
channelName,
channelId,
playlistId: lockupView.content_id,
videoCount: extractNumberFromString(thumbnailOverlayBadgeView.badges[0].text)
}
return parseLockupView(playlist, channelId, channelName)
} else {
let internalChannelName
let internalChannelId = null
@ -858,7 +842,7 @@ function handleSearchResponse(response) {
const results = response.results
.filter((item) => {
return item.type === 'Video' || item.type === 'Channel' || item.type === 'Playlist' || item.type === 'HashtagTile' || item.type === 'Movie'
return item.type === 'Video' || item.type === 'Channel' || item.type === 'Playlist' || item.type === 'HashtagTile' || item.type === 'Movie' || item.type === 'LockupView'
})
.map((item) => parseListItem(item))
@ -1050,6 +1034,41 @@ export function parseLocalListVideo(item) {
}
}
/**
* @param {import('youtubei.js').YTNodes.LockupView} lockupView
* @param {string | undefined} channelId
* @param {string | undefined} channelName
*/
function parseLockupView(lockupView, channelId = undefined, channelName = undefined) {
switch (lockupView.content_type) {
case 'PLAYLIST':
case 'PODCAST': {
const thumbnailOverlayBadgeView = lockupView.content_image.primary_thumbnail.overlays
.find(overlay => overlay.is(YTNodes.ThumbnailOverlayBadgeView))
const maybeChannelText = lockupView.metadata?.metadata?.metadata_rows?.[0]?.metadata_parts?.[0]?.text
if (maybeChannelText && maybeChannelText.endpoint?.metadata.page_type === 'WEB_PAGE_TYPE_CHANNEL') {
channelName = maybeChannelText.text
channelId = maybeChannelText.endpoint.payload.browseId
}
return {
type: 'playlist',
dataSource: 'local',
playlistId: lockupView.content_id,
title: lockupView.metadata.title.text,
thumbnail: lockupView.content_image.primary_thumbnail.image[0].url,
channelName,
channelId,
videoCount: extractNumberFromString(thumbnailOverlayBadgeView.badges[0].text)
}
}
default:
console.warn(`Unknown lockup content type: ${lockupView.content_type}`, lockupView)
}
}
/**
* @param {import('youtubei.js').Helpers.YTNode} item
*/
@ -1109,6 +1128,8 @@ function parseListItem(item) {
case 'Playlist': {
return parseLocalListPlaylist(item)
}
case 'LockupView':
return parseLockupView(item)
}
}