diff --git a/docs/README.md b/docs/README.md index 8d9e790..5f0fc0c 100644 --- a/docs/README.md +++ b/docs/README.md @@ -40,14 +40,43 @@ _This creates basic spotify / soundcloud data to be stored locally._ authorization() //After then you will be asked about type of data you want to create and then follow the steps properly. ``` +### Search + +#### SearchOptions : + +- limit : `number` :- Sets total amount of results you want. +- source : { + + youtube: `video` | `playlist` | `channel` ; + + spotify: `album` | `playlist` | `track` ; + + soundcloud: `tracks` | `playlists` | `albums` ; + + } + +#### search(query : `string`, options? : [`SearchOptions`]()) + +_This is basic to search with any source._ + +**NOTE :-** If no options.source is not specified, then it will default to youtube video search. + +```js +let data = await search('Rick Roll', { limit : 1, source { youtube : "video" } }) // Searches for youtube video + +let data = await search('Rick Roll', { limit: 1, source { soundcloud : "track" } }) // Searches for spotify track. + +let data = await search('Rick Roll', { limit: 1, source { spotify : "tracks" } }) // Searches for soundcloud track. +``` + ### Stream -### StreamOptions : +#### StreamOptions : - quality : `number` :- Sets quality of stream [ 0 = Lowest, 1 = Medium ]. Leave this empty to get highest audio quality. -- cookie : `string` :- **[Cookies](https://github.com/play-dl/play-dl/discussions/34) are optional and are required for playing age restricted videos.** +- cookie : `string` :- **[Cookies](https://github.com/play-dl/play-dl/discussions/34)** are optional and are required for playing age restricted videos. -#### stream(url : `string`, options? : `StreamOptions`) +#### stream(url : `string`, options? : [`StreamOptions`]()) _This is basic to create a stream from a youtube or soundcloud url._ @@ -59,7 +88,7 @@ let resource = createAudioResource(source.stream, { }) // This creates resource for playing ``` -#### stream_from_info(info : `infoData`, options? : `StreamOptions`) +#### stream_from_info(info : `infoData`, options? : [`StreamOptions`]()) _This is basic to create a stream from a info [ from [video_info](https://github.com/play-dl/play-dl#video_infourl--string) function or [soundcloud]() function [**Only SoundCloudTrack class is allowed**] ]._ diff --git a/docs/YouTube/README.md b/docs/YouTube/README.md index f22a589..d054fd3 100644 --- a/docs/YouTube/README.md +++ b/docs/YouTube/README.md @@ -41,24 +41,6 @@ _This will return videoID or playlistID from a url_ let id = extractID(url) ``` -## Search - -### search(url : `string`, options? : [SearchOptions](https://github.com/play-dl/play-dl/tree/main/play-dl/YouTube#searchoptions)) - -_This enables all searching mechanism (video, channel, playlist)_ - -```js -const options = { - limit : 1 -} -const results = await youtube.search('never gonna give you up', options); -console.log(results[0].url); -``` - -- #### SearchOptions - - _type_ : `video` | `channel` | `playlist` - - _limit_ : `integer` - ## Video ### video_basic_info(url : `string`, cookie? : `string`) diff --git a/play-dl/SoundCloud/index.ts b/play-dl/SoundCloud/index.ts index 776ff8c..18de69b 100644 --- a/play-dl/SoundCloud/index.ts +++ b/play-dl/SoundCloud/index.ts @@ -33,6 +33,23 @@ export async function soundcloud(url: string): Promise { + const response = await request( + `https://api-v2.soundcloud.com/search/${type}?q=${query}&client_id=${soundData.client_id}&limit=${limit}` + ); + const results: (SoundCloudPlaylist | SoundCloudTrack)[] = []; + const json_data = JSON.parse(response); + json_data.collection.forEach((x: any) => { + if (type === 'tracks') results.push(new SoundCloudTrack(x)); + else results.push(new SoundCloudPlaylist(x, soundData.client_id)); + }); + return results; +} + export async function stream(url: string, quality?: number): Promise { const data = await soundcloud(url); diff --git a/play-dl/Spotify/index.ts b/play-dl/Spotify/index.ts index 0842462..df5b02a 100644 --- a/play-dl/Spotify/index.ts +++ b/play-dl/Spotify/index.ts @@ -110,6 +110,45 @@ export function is_expired(): boolean { else return false; } +export async function sp_search( + query: string, + type: 'album' | 'playlist' | 'track', + limit: number = 10 +): Promise<(SpotifyAlbum | SpotifyPlaylist | SpotifyVideo)[]> { + const results: (SpotifyAlbum | SpotifyPlaylist | SpotifyVideo)[] = []; + if (!spotifyData) throw new Error('Spotify Data is missing\nDid you forgot to do authorization ?'); + if (query.length === 0) throw new Error('Pass some query to search.'); + if (limit > 50 || limit < 0) throw new Error(`You crossed limit range of Spotify [ 0 - 50 ]`); + const response = await request( + `https://api.spotify.com/v1/search?type=${type}&q=${query.replaceAll(' ', '+')}&limit=${limit}&market=${ + spotifyData.market + }`, + { + headers: { + Authorization: `${spotifyData.token_type} ${spotifyData.access_token}` + } + } + ).catch((err: Error) => { + return err; + }); + if (response instanceof Error) throw response; + const json_data = JSON.parse(response); + if (type === 'track') { + json_data.tracks.items.forEach((track: any) => { + results.push(new SpotifyVideo(track)); + }); + } else if (type === 'album') { + json_data.albums.items.forEach((album: any) => { + results.push(new SpotifyAlbum(album, spotifyData)); + }); + } else if (type === 'playlist') { + json_data.playlists.items.forEach((playlist: any) => { + results.push(new SpotifyPlaylist(playlist, spotifyData)); + }); + } + return results; +} + export async function refreshToken(): Promise { const response = await request(`https://accounts.spotify.com/api/token`, { headers: { diff --git a/play-dl/YouTube/index.ts b/play-dl/YouTube/index.ts index a268c62..8ca7478 100644 --- a/play-dl/YouTube/index.ts +++ b/play-dl/YouTube/index.ts @@ -1,3 +1,2 @@ -export { search } from './search'; export { stream, stream_from_info } from './stream'; export * from './utils'; diff --git a/play-dl/YouTube/search.ts b/play-dl/YouTube/search.ts index f83cdc9..45cc9c4 100644 --- a/play-dl/YouTube/search.ts +++ b/play-dl/YouTube/search.ts @@ -10,7 +10,7 @@ enum SearchType { Channel = 'EgIQAg%253D%253D' } -export async function search( +export async function yt_search( search: string, options: ParseSearchInterface = {} ): Promise<(Video | Channel | PlayList)[]> { diff --git a/play-dl/index.ts b/play-dl/index.ts index 87b1c57..d98e9e8 100644 --- a/play-dl/index.ts +++ b/play-dl/index.ts @@ -1,15 +1,25 @@ -export { playlist_info, video_basic_info, video_info, search, yt_validate, extractID } from './YouTube'; +export { playlist_info, video_basic_info, video_info, yt_validate, extractID } from './YouTube'; export { spotify, sp_validate, refreshToken, is_expired } from './Spotify'; export { soundcloud, so_validate } from './SoundCloud'; +interface SearchOptions { + limit?: number; + source?: { + youtube?: 'video' | 'playlist' | 'channel'; + spotify?: 'album' | 'playlist' | 'track'; + soundcloud?: 'tracks' | 'playlists' | 'albums'; + }; +} + import readline from 'readline'; import fs from 'fs'; import { sp_validate, yt_validate, so_validate } from '.'; -import { SpotifyAuthorize } from './Spotify'; -import { check_id, stream as so_stream, stream_from_info as so_stream_info } from './SoundCloud'; +import { SpotifyAuthorize, sp_search } from './Spotify'; +import { check_id, so_search, stream as so_stream, stream_from_info as so_stream_info } from './SoundCloud'; import { InfoData, stream as yt_stream, StreamOptions, stream_from_info as yt_stream_info } from './YouTube/stream'; import { SoundCloudTrack, Stream as SoStream } from './SoundCloud/classes'; import { LiveStreaming, Stream as YTStream } from './YouTube/classes/LiveStream'; +import { yt_search } from './YouTube/search'; export async function stream(url: string, options: StreamOptions = {}): Promise { if (url.length === 0) throw new Error('Stream URL has a length of 0. Check your url again.'); @@ -17,6 +27,14 @@ export async function stream(url: string, options: StreamOptions = {}): Promise< else return await yt_stream(url, { cookie: options.cookie }); } +export async function search(query: string, options: SearchOptions = {}) { + if (!options.source) options.source = { youtube: 'video' }; + + if (options.source.youtube) return await yt_search(query, { limit: options.limit, type: options.source.youtube }); + else if (options.source.spotify) return await sp_search(query, options.source.spotify, options.limit); + else if (options.source.soundcloud) return await so_search(query, options.source.soundcloud, options.limit); +} + export async function stream_from_info( info: InfoData | SoundCloudTrack, options: StreamOptions = {}