Song and Video data fetching works
This commit is contained in:
		
							parent
							
								
									7471f1e70c
								
							
						
					
					
						commit
						9479811d4c
					
				|  | @ -1,7 +1,6 @@ | |||
| import AlbumParser from "./parsers/AlbumParser" | ||||
| import ArtistParser from "./parsers/ArtistParser" | ||||
| import axios, { AxiosInstance } from "axios" | ||||
| import fs from "fs" | ||||
| import PlaylistParser from "./parsers/PlaylistParser" | ||||
| import SearchParser from "./parsers/SearchParser" | ||||
| import SongParser from "./parsers/SongParser" | ||||
|  | @ -237,16 +236,28 @@ export default class YTMusic { | |||
| 		) | ||||
| 	} | ||||
| 
 | ||||
| 	public async getSong(videoId: string) { | ||||
| 	/** | ||||
| 	 * Get all possible information of a Song | ||||
| 	 * | ||||
| 	 * @param videoId Video ID | ||||
| 	 * @returns Song Data | ||||
| 	 */ | ||||
| 	public async getSong(videoId: string): Promise<YTMusic.SongFull> { | ||||
| 		const data = await this.constructRequest("player", { videoId }) | ||||
| 
 | ||||
| 		fs.writeFileSync("data.json", JSON.stringify(data)) | ||||
| 		return SongParser.parse(data) | ||||
| 	} | ||||
| 
 | ||||
| 	public async getVideo(videoId: string) { | ||||
| 	/** | ||||
| 	 * Get all possible information of a Video | ||||
| 	 * | ||||
| 	 * @param videoId Video ID | ||||
| 	 * @returns Video Data | ||||
| 	 */ | ||||
| 	public async getVideo(videoId: string): Promise<YTMusic.VideoFull> { | ||||
| 		const data = await this.constructRequest("player", { videoId }) | ||||
| 
 | ||||
| 		fs.writeFileSync("data.json", JSON.stringify(data)) | ||||
| 		return VideoParser.parse(data) | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
|  |  | |||
							
								
								
									
										10
									
								
								src/index.ts
								
								
								
								
							
							
						
						
									
										10
									
								
								src/index.ts
								
								
								
								
							|  | @ -1,10 +0,0 @@ | |||
| import YTMusic from "./YTMusic" | ||||
| 
 | ||||
| const ytmusic = new YTMusic() | ||||
| ytmusic.initialize().then(() => { | ||||
| 	ytmusic.search("Lilac", "PLAYLIST").then(res => { | ||||
| 		ytmusic.getPlaylist(res[0].playlistId).then(res => { | ||||
| 			console.log(res) | ||||
| 		}) | ||||
| 	}) | ||||
| }) | ||||
|  | @ -2,6 +2,25 @@ import Parser from "./Parser" | |||
| import traverse from "../utils/traverse" | ||||
| 
 | ||||
| export default class SongParser { | ||||
| 	public static parse(data: any): YTMusic.SongFull { | ||||
| 		return { | ||||
| 			type: "SONG", | ||||
| 			videoId: traverse(data, "videoDetails", "videoId"), | ||||
| 			name: traverse(data, "videoDetails", "title"), | ||||
| 			artists: [ | ||||
| 				{ | ||||
| 					artistId: traverse(data, "videoDetails", "channelId"), | ||||
| 					name: traverse(data, "author") | ||||
| 				} | ||||
| 			], | ||||
| 			duration: +traverse(data, "videoDetails", "lengthSeconds"), | ||||
| 			thumbnails: [traverse(data, "videoDetails", "thumbnails")].flat(), | ||||
| 			description: traverse(data, "description"), | ||||
| 			formats: traverse(data, "streamingData", "formats"), | ||||
| 			adaptiveFormats: traverse(data, "streamingData", "adaptiveFormats") | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public static parseSearchResult(item: any): YTMusic.SongDetailed { | ||||
| 		const flexColumns = traverse(item, "flexColumns") | ||||
| 		const videoId = traverse(item, "playlistItemData", "videoId") | ||||
|  |  | |||
|  | @ -2,6 +2,28 @@ import Parser from "./Parser" | |||
| import traverse from "../utils/traverse" | ||||
| 
 | ||||
| export default class VideoParser { | ||||
| 	public static parse(data: any): YTMusic.VideoFull { | ||||
| 		return { | ||||
| 			type: "VIDEO", | ||||
| 			videoId: traverse(data, "videoDetails", "videoId"), | ||||
| 			name: traverse(data, "videoDetails", "title"), | ||||
| 			artists: [ | ||||
| 				{ | ||||
| 					artistId: traverse(data, "videoDetails", "channelId"), | ||||
| 					name: traverse(data, "author") | ||||
| 				} | ||||
| 			], | ||||
| 			views: +traverse(data, "videoDetails", "viewCount"), | ||||
| 			duration: +traverse(data, "videoDetails", "lengthSeconds"), | ||||
| 			thumbnails: [traverse(data, "videoDetails", "thumbnails")].flat(), | ||||
| 			description: traverse(data, "description"), | ||||
| 			unlisted: traverse(data, "unlisted"), | ||||
| 			familySafe: traverse(data, "familySafe"), | ||||
| 			paid: traverse(data, "paid"), | ||||
| 			tags: traverse(data, "tags") | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public static parseSearchResult(item: any): YTMusic.VideoDetailed { | ||||
| 		const flexColumns = traverse(item, "flexColumns") | ||||
| 		const videoId = traverse(item, "playNavigationEndpoint", "videoId") | ||||
|  |  | |||
|  | @ -8,7 +8,9 @@ import { | |||
| 	PLAYLIST_DETAILED, | ||||
| 	PLAYLIST_VIDEO, | ||||
| 	SONG_DETAILED, | ||||
| 	VIDEO_DETAILED | ||||
| 	SONG_FULL, | ||||
| 	VIDEO_DETAILED, | ||||
| 	VIDEO_FULL | ||||
| } from "./interfaces" | ||||
| import { LIST, validate } from "validate-any" | ||||
| 
 | ||||
|  | @ -26,10 +28,10 @@ ytmusic.initialize().then(() => | |||
| 			ytmusic.search(query) | ||||
| 		]) | ||||
| 
 | ||||
| 		const [artist, artistSongs, artistAlbums, album, playlist, playlistVideos] = | ||||
| 		const [song, video, artist, artistSongs, artistAlbums, album, playlist, playlistVideos] = | ||||
| 			await Promise.all([ | ||||
| 				// ytmusic.getSong(songs[0].videoId),
 | ||||
| 				// ytmusic.getVideo(videos[0].videoId),
 | ||||
| 				ytmusic.getSong(songs[0].videoId!), | ||||
| 				ytmusic.getVideo(videos[0].videoId!), | ||||
| 				ytmusic.getArtist(artists[0].artistId), | ||||
| 				ytmusic.getArtistSongs(artists[0].artistId), | ||||
| 				ytmusic.getArtistAlbums(artists[0].artistId), | ||||
|  | @ -54,8 +56,8 @@ ytmusic.initialize().then(() => | |||
| 					VIDEO_DETAILED | ||||
| 				) | ||||
| 			], | ||||
| 			// [song, SONG_DETAILED],
 | ||||
| 			// [video, VIDEO_DETAILED],
 | ||||
| 			[song, SONG_FULL], | ||||
| 			[video, VIDEO_FULL], | ||||
| 			[artist, ARTIST_FULL], | ||||
| 			[artistSongs, LIST(SONG_DETAILED)], | ||||
| 			[artistAlbums, LIST(ALBUM_DETAILED)], | ||||
|  | @ -1,5 +1,5 @@ | |||
| import ObjectValidator from "validate-any/build/validators/ObjectValidator" | ||||
| import { LIST, NULL, NUMBER, OBJECT, OR, STRING } from "validate-any" | ||||
| import { BOOLEAN, LIST, NULL, NUMBER, OBJECT, OR, STRING } from "validate-any" | ||||
| 
 | ||||
| export const THUMBNAIL_FULL: ObjectValidator<YTMusic.ThumbnailFull> = OBJECT({ | ||||
| 	url: STRING(), | ||||
|  | @ -54,6 +54,33 @@ export const ALBUM_DETAILED: ObjectValidator<YTMusic.AlbumDetailed> = OBJECT({ | |||
| 	thumbnails: LIST(THUMBNAIL_FULL) | ||||
| }) | ||||
| 
 | ||||
| export const SONG_FULL: ObjectValidator<YTMusic.SongFull> = OBJECT({ | ||||
| 	type: STRING("SONG"), | ||||
| 	videoId: OR(STRING(), NULL()), | ||||
| 	name: STRING(), | ||||
| 	artists: LIST(ARTIST_BASIC), | ||||
| 	duration: NUMBER(), | ||||
| 	thumbnails: LIST(THUMBNAIL_FULL), | ||||
| 	description: STRING(), | ||||
| 	formats: LIST(OBJECT()), | ||||
| 	adaptiveFormats: LIST(OBJECT()) | ||||
| }) | ||||
| 
 | ||||
| export const VIDEO_FULL: ObjectValidator<YTMusic.VideoFull> = OBJECT({ | ||||
| 	type: STRING("VIDEO"), | ||||
| 	videoId: OR(STRING(), NULL()), | ||||
| 	name: STRING(), | ||||
| 	artists: LIST(ARTIST_BASIC), | ||||
| 	views: NUMBER(), | ||||
| 	duration: NUMBER(), | ||||
| 	thumbnails: LIST(THUMBNAIL_FULL), | ||||
| 	description: STRING(), | ||||
| 	unlisted: BOOLEAN(), | ||||
| 	familySafe: BOOLEAN(), | ||||
| 	paid: BOOLEAN(), | ||||
| 	tags: LIST(STRING()) | ||||
| }) | ||||
| 
 | ||||
| export const ARTIST_FULL: ObjectValidator<YTMusic.ArtistFull> = OBJECT({ | ||||
| 	artistId: STRING(), | ||||
| 	name: STRING(), | ||||
|  |  | |||
|  | @ -0,0 +1,10 @@ | |||
| import YTMusic from "../YTMusic" | ||||
| 
 | ||||
| const ytmusic = new YTMusic() | ||||
| ytmusic.initialize().then(() => { | ||||
| 	ytmusic.search("Lilac", "SONG").then(res => { | ||||
| 		ytmusic.getSong(res.find(r => !!r.videoId)!.videoId!).then(res => { | ||||
| 			console.log(res) | ||||
| 		}) | ||||
| 	}) | ||||
| }) | ||||
|  | @ -15,6 +15,12 @@ declare namespace YTMusic { | |||
| 		thumbnails: ThumbnailFull[] | ||||
| 	} | ||||
| 
 | ||||
| 	interface SongFull extends Omit<SongDetailed, "album"> { | ||||
| 		description: string | ||||
| 		formats: any[] | ||||
| 		adaptiveFormats: any[] | ||||
| 	} | ||||
| 
 | ||||
| 	interface VideoDetailed { | ||||
| 		type: "VIDEO" | ||||
| 		videoId: string | null | ||||
|  | @ -25,6 +31,14 @@ declare namespace YTMusic { | |||
| 		thumbnails: ThumbnailFull[] | ||||
| 	} | ||||
| 
 | ||||
| 	interface VideoFull extends VideoDetailed { | ||||
| 		description: string | ||||
| 		unlisted: boolean | ||||
| 		familySafe: boolean | ||||
| 		paid: boolean | ||||
| 		tags: string[] | ||||
| 	} | ||||
| 
 | ||||
| 	interface ArtistBasic { | ||||
| 		artistId: string | null | ||||
| 		name: string | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue