UNPKG

youtubei

Version:

Simple package to get information from youtube such as videos, playlists, channels, video information & comments, related videos, up next video, and more!

244 lines (243 loc) 12.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MusicSearchResultParser = void 0; const common_1 = require("../../common"); const MusicAlbumCompact_1 = require("../MusicAlbumCompact"); const MusicArtistCompact_1 = require("../MusicArtistCompact"); const MusicBaseArtist_1 = require("../MusicBaseArtist"); const MusicBaseChannel_1 = require("../MusicBaseChannel"); const MusicPlaylistCompact_1 = require("../MusicPlaylistCompact"); const MusicSongCompact_1 = require("../MusicSongCompact"); const MusicVideoCompact_1 = require("../MusicVideoCompact"); class MusicSearchResultParser { static parseInitialSearchResult(data, client) { var _a, _b; const sectionContents = data.contents.tabbedSearchResultsRenderer.tabs[0].tabRenderer.content .sectionListRenderer.contents; const resultContents = sectionContents.find((c) => "musicShelfRenderer" in c); if (!resultContents) { // no results return { data: [], continuation: undefined, }; } const { contents, continuations } = resultContents.musicShelfRenderer; const result = MusicSearchResultParser.parseSearchResult(contents, client); return { data: result, continuation: (_b = (_a = continuations === null || continuations === void 0 ? void 0 : continuations[0]) === null || _a === void 0 ? void 0 : _a.nextContinuationData) === null || _b === void 0 ? void 0 : _b.continuation, }; } static parseContinuationSearchResult(data, client) { const shelf = data.continuationContents.musicShelfContinuation; return { data: MusicSearchResultParser.parseSearchResult(shelf.contents, client), continuation: shelf.continuations[0].nextContinuationData.continuation, }; } static parseTopResult(data, client) { const sectionContents = data.contents.tabbedSearchResultsRenderer.tabs[0].tabRenderer.content .sectionListRenderer.contents; const topContent = sectionContents.find((c) => "musicCardShelfRenderer" in c); const top = topContent === null || topContent === void 0 ? void 0 : topContent.musicCardShelfRenderer; if (!top) return null; const { browseEndpoint, watchEndpoint } = top.title.runs[0].navigationEndpoint; const id = (watchEndpoint === null || watchEndpoint === void 0 ? void 0 : watchEndpoint.videoId) || (browseEndpoint === null || browseEndpoint === void 0 ? void 0 : browseEndpoint.browseId); const type = (watchEndpoint === null || watchEndpoint === void 0 ? void 0 : watchEndpoint.watchEndpointMusicSupportedConfigs.watchEndpointMusicConfig.musicVideoType) || (browseEndpoint === null || browseEndpoint === void 0 ? void 0 : browseEndpoint.browseEndpointContextSupportedConfigs.browseEndpointContextMusicConfig.pageType); const title = top.title.runs[0].text; const thumbnail = top.thumbnail.musicThumbnailRenderer.thumbnail.thumbnails; let topResult; if (type === "MUSIC_VIDEO_TYPE_ATV") { topResult = new MusicSongCompact_1.MusicSongCompact({ client, id, title, duration: common_1.getDuration(top.subtitle.runs.at(-1).text), artists: this.parseArtists(top.subtitle.runs, client), album: this.parseAlbum(top.subtitle.runs, client), thumbnails: new common_1.Thumbnails().load(thumbnail), }); } else if (type === "MUSIC_VIDEO_TYPE_UGC" || type === "MUSIC_VIDEO_TYPE_OMV") { topResult = new MusicVideoCompact_1.MusicVideoCompact({ client, id, title, duration: common_1.getDuration(top.subtitle.runs.at(-1).text), artists: this.parseArtists(top.subtitle.runs, client), thumbnails: new common_1.Thumbnails().load(thumbnail), }); } else if (type === "MUSIC_PAGE_TYPE_ALBUM") { topResult = new MusicAlbumCompact_1.MusicAlbumCompact({ client, id, title, artists: this.parseArtists(top.subtitle.runs, client), thumbnails: new common_1.Thumbnails().load(thumbnail), }); } else if (type === "MUSIC_PAGE_TYPE_ARTIST") { topResult = new MusicArtistCompact_1.MusicArtistCompact({ client, id, name: title, thumbnails: new common_1.Thumbnails().load(thumbnail), }); } else if (type === "MUSIC_PAGE_TYPE_PLAYLIST") { topResult = new MusicPlaylistCompact_1.MusicPlaylistCompact({ client, id, title, channel: this.parseChannel(top.subtitle.runs, client), thumbnails: new common_1.Thumbnails().load(thumbnail), }); } if (!topResult) return null; let more = []; if (top.contents) { more = top.contents .filter((c) => c.musicResponsiveListItemRenderer) .map((c) => this.parseSearchItem(c, client)); } return { item: topResult, more, }; } static parseSearchResult(shelfContents, client) { const rawContents = shelfContents.filter((c) => "musicResponsiveListItemRenderer" in c); const contents = []; for (const c of rawContents) { const parsed = this.parseSearchItem(c, client); if (parsed) contents.push(parsed); } return contents; } static parseSearchItem(content, client) { var _a; const item = content.musicResponsiveListItemRenderer; const playEndpoint = (_a = item.overlay) === null || _a === void 0 ? void 0 : _a.musicItemThumbnailOverlayRenderer.content.musicPlayButtonRenderer.playNavigationEndpoint; if (playEndpoint === null || playEndpoint === void 0 ? void 0 : playEndpoint.watchEndpoint) { const pageType = playEndpoint.watchEndpoint.watchEndpointMusicSupportedConfigs .watchEndpointMusicConfig.musicVideoType; return this.parseVideoItem(item, pageType, client); } else if (playEndpoint === null || playEndpoint === void 0 ? void 0 : playEndpoint.watchPlaylistEndpoint.params) { return this.parsePlaylistItem(item, client); } else if (playEndpoint === null || playEndpoint === void 0 ? void 0 : playEndpoint.watchPlaylistEndpoint) { // TODO add podcast support, id starts with PL if (playEndpoint.watchPlaylistEndpoint.playlistId.startsWith("OL")) { return this.parseAlbumItem(item, client); } } else { return this.parseArtistItem(item, client); } } static parseVideoItem(item, pageType, client) { // TODO support other types if (!["MUSIC_VIDEO_TYPE_ATV", "MUSIC_VIDEO_TYPE_UGC", "MUSIC_VIDEO_TYPE_OMV"].includes(pageType)) { return; } const [topColumn, bottomColumn] = item.flexColumns.map((c) => c.musicResponsiveListItemFlexColumnRenderer.text.runs); const id = topColumn[0].navigationEndpoint.watchEndpoint.videoId; const title = topColumn[0].text; const duration = common_1.getDuration(bottomColumn.at(-1).text) || undefined; const thumbnails = new common_1.Thumbnails().load(item.thumbnail.musicThumbnailRenderer.thumbnail.thumbnails); const artists = this.parseArtists(bottomColumn, client); if (pageType === "MUSIC_VIDEO_TYPE_ATV") { return new MusicSongCompact_1.MusicSongCompact({ client, id, album: this.parseAlbum(bottomColumn, client), title, artists, thumbnails, duration, }); } else if (pageType === "MUSIC_VIDEO_TYPE_UGC" || pageType === "MUSIC_VIDEO_TYPE_OMV") { return new MusicVideoCompact_1.MusicVideoCompact({ client, id, title, artists, thumbnails, duration }); } } static parsePlaylistItem(item, client) { const [topColumn, bottomColumn] = item.flexColumns.map((c) => c.musicResponsiveListItemFlexColumnRenderer.text.runs); const id = item.overlay.musicItemThumbnailOverlayRenderer.content.musicPlayButtonRenderer .playNavigationEndpoint.watchPlaylistEndpoint.playlistId; const title = topColumn[0].text; const songCount = common_1.stripToInt(bottomColumn.at(-1).text) || undefined; const thumbnails = new common_1.Thumbnails().load(item.thumbnail.musicThumbnailRenderer.thumbnail.thumbnails); const channel = this.parseChannel(bottomColumn, client); return new MusicPlaylistCompact_1.MusicPlaylistCompact({ client, id, title, thumbnails, songCount, channel }); } static parseAlbumItem(item, client) { const [topColumn, bottomColumn] = item.flexColumns.map((c) => c.musicResponsiveListItemFlexColumnRenderer.text.runs); const id = item.overlay.musicItemThumbnailOverlayRenderer.content.musicPlayButtonRenderer .playNavigationEndpoint.watchPlaylistEndpoint.playlistId; const title = topColumn[0].text; const year = common_1.stripToInt(bottomColumn.at(-1).text) || undefined; const thumbnails = new common_1.Thumbnails().load(item.thumbnail.musicThumbnailRenderer.thumbnail.thumbnails); const artists = this.parseArtists(bottomColumn, client); return new MusicAlbumCompact_1.MusicAlbumCompact({ client, id, title, thumbnails, artists, year }); } static parseArtistItem(item, client) { const [topColumn] = item.flexColumns.map((c) => c.musicResponsiveListItemFlexColumnRenderer.text.runs); const id = item.navigationEndpoint.browseEndpoint.browseId; const name = topColumn[0].text; const thumbnails = new common_1.Thumbnails().load(item.thumbnail.musicThumbnailRenderer.thumbnail.thumbnails); return new MusicArtistCompact_1.MusicArtistCompact({ client, id, name, thumbnails }); } static parseAlbum(items, client) { var _a; const albumRaw = items.find((r) => { var _a; const pageType = (_a = r.navigationEndpoint) === null || _a === void 0 ? void 0 : _a.browseEndpoint.browseEndpointContextSupportedConfigs.browseEndpointContextMusicConfig.pageType; return pageType === "MUSIC_PAGE_TYPE_ALBUM"; }); if (!albumRaw) return; const album = new MusicAlbumCompact_1.MusicAlbumCompact({ client, title: albumRaw.text, id: (_a = albumRaw.navigationEndpoint) === null || _a === void 0 ? void 0 : _a.browseEndpoint.browseId, }); return album; } static parseArtists(items, client) { return this.parseArtistsOrChannel(items).map((r) => { var _a; return new MusicBaseArtist_1.MusicBaseArtist({ client, name: r.text, id: (_a = r.navigationEndpoint) === null || _a === void 0 ? void 0 : _a.browseEndpoint.browseId, }); }); } static parseChannel(items, client) { var _a; const [channelRaw] = this.parseArtistsOrChannel(items); if (!channelRaw) return; const channel = new MusicBaseChannel_1.MusicBaseChannel({ client, name: channelRaw.text, id: (_a = channelRaw.navigationEndpoint) === null || _a === void 0 ? void 0 : _a.browseEndpoint.browseId, }); return channel; } static parseArtistsOrChannel(items) { return items.filter((i) => { var _a; const pageType = (_a = i.navigationEndpoint) === null || _a === void 0 ? void 0 : _a.browseEndpoint.browseEndpointContextSupportedConfigs.browseEndpointContextMusicConfig.pageType; return (pageType === "MUSIC_PAGE_TYPE_ARTIST" || pageType == "MUSIC_PAGE_TYPE_USER_CHANNEL"); }); } } exports.MusicSearchResultParser = MusicSearchResultParser;