Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: extend music getInfo to allow MusicResponsiveListItem and Nav Endpoints #751

Merged
merged 5 commits into from
Sep 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 12 additions & 9 deletions src/core/clients/Music.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import Message from '../../parser/classes/Message.js';
import MusicDescriptionShelf from '../../parser/classes/MusicDescriptionShelf.js';
import MusicQueue from '../../parser/classes/MusicQueue.js';
import MusicTwoRowItem from '../../parser/classes/MusicTwoRowItem.js';
import MusicResponsiveListItem from '../../parser/classes/MusicResponsiveListItem.js';
import NavigationEndpoint from '../../parser/classes/NavigationEndpoint.js';
import PlaylistPanel from '../../parser/classes/PlaylistPanel.js';
import SearchSuggestionsSection from '../../parser/classes/SearchSuggestionsSection.js';
import SectionList from '../../parser/classes/SectionList.js';
Expand Down Expand Up @@ -44,9 +46,13 @@ export default class Music {
* Retrieves track info. Passing a list item of type MusicTwoRowItem automatically starts a radio.
* @param target - Video id or a list item.
*/
getInfo(target: string | MusicTwoRowItem): Promise<TrackInfo> {
getInfo(target: string | MusicTwoRowItem | MusicResponsiveListItem | NavigationEndpoint): Promise<TrackInfo> {
if (target instanceof MusicTwoRowItem) {
return this.#fetchInfoFromListItem(target);
return this.#fetchInfoFromEndpoint(target.endpoint);
} else if (target instanceof MusicResponsiveListItem) {
return this.#fetchInfoFromEndpoint(target.overlay?.content?.endpoint ?? target.endpoint);
} else if (target instanceof NavigationEndpoint) {
return this.#fetchInfoFromEndpoint(target);
} else if (typeof target === 'string') {
return this.#fetchInfoFromVideoId(target);
}
Expand Down Expand Up @@ -75,14 +81,11 @@ export default class Music {
return new TrackInfo(response, this.#actions, cpn);
}

async #fetchInfoFromListItem(list_item: MusicTwoRowItem | undefined): Promise<TrackInfo> {
if (!list_item)
throw new InnertubeError('List item cannot be undefined');

if (!list_item.endpoint)
async #fetchInfoFromEndpoint(endpoint?: NavigationEndpoint): Promise<TrackInfo> {
if (!endpoint)
throw new Error('This item does not have an endpoint.');

const player_response = list_item.endpoint.call(this.#actions, {
const player_response = endpoint.call(this.#actions, {
client: 'YTMUSIC',
playbackContext: {
contentPlaybackContext: {
Expand All @@ -93,7 +96,7 @@ export default class Music {
}
});

const next_response = list_item.endpoint.call(this.#actions, {
const next_response = endpoint.call(this.#actions, {
client: 'YTMUSIC',
enablePersistentPlaylistPanel: true,
override_endpoint: '/next'
Expand Down
27 changes: 27 additions & 0 deletions test/main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,33 @@ describe('YouTube.js Tests', () => {
// expect(info.basic_info.id).toBe('WSeNSzJ2-Jw');
// });

test('Innertube#music.getInfo.MusicResponsiveListItem', async () => {
const playlist = await innertube.music.getPlaylist('PLQxo8OvVvJ1WI_Bp67F2wdIl_R2Rc_1-u');
expect(playlist).toBeDefined();
expect(playlist.header).toBeDefined();
expect(playlist.contents).toBeDefined();
expect(playlist.contents?.length).toBeGreaterThan(0);

const info = await innertube.music.getInfo(playlist.contents!.first())
expect(info).toBeDefined();
});

test('Innertube#music.getInfo.NavEndpoint', async () => {
const playlist = await innertube.music.getPlaylist('PLQxo8OvVvJ1WI_Bp67F2wdIl_R2Rc_1-u');
expect(playlist).toBeDefined();
expect(playlist.header).toBeDefined();
expect(playlist.contents).toBeDefined();
expect(playlist.contents?.length).toBeGreaterThan(0);

const playlistPlayEndpoint = playlist.header!.as(YTNodes.MusicResponsiveHeader).buttons.firstOfType(YTNodes.MusicPlayButton)!.endpoint

const info = await innertube.music.getInfo(playlistPlayEndpoint)
expect(info).toBeDefined();

const upNext = await info.getUpNext();
expect(upNext.playlist_id).toBe("PLQxo8OvVvJ1WI_Bp67F2wdIl_R2Rc_1-u");
});

describe('Innertube#music.search', () => {
let search: YTMusic.Search;

Expand Down
Loading