diff --git a/src/Player.ts b/src/Player.ts index 61e3de4..607e097 100644 --- a/src/Player.ts +++ b/src/Player.ts @@ -144,7 +144,7 @@ export class Player extends EventEmitter { * @returns {Promise} * @private */ - private _searchTracks(message: Message, query: string, firstResult?: boolean): Promise { + private _searchTracks(message: Message, query: string, firstResult?: boolean, startFromIndex?: number = 0): Promise { return new Promise(async (resolve) => { let tracks: Track[] = []; const queryType = Util.getQueryType(query); @@ -302,17 +302,21 @@ export class Player extends EventEmitter { }; this.emit(PlayerEvents.PLAYLIST_PARSE_END, pl, message); + if (startFromIndex < 0) startFromIndex = 0; + if (startFromIndex > tracks.length - 1) startFromIndex = tracks.length - 1; if (this.isPlaying(message)) { + const prioritisedTrack = tracks.splice(startFromIndex, 1); + tracks.unshift(prioritisedTrack); const queue = this._addTracksToQueue(message, tracks); - this.emit(PlayerEvents.PLAYLIST_ADD, message, queue, pl); + this.emit(PlayerEvents.PLAYLIST_ADD, message, queue, playlist); } else { - const track = tracks[0]; - const queue = (await this._createQueue(message, track).catch((e) => void this.emit(PlayerEvents.ERROR, e, message))) as Queue; + const track = tracks[startFromIndex]; + const queue = (await this._createQueue(message, track).catch((e) => void this.emit(PlayerEvents.ERROR, e, message))) as Queue; this.emit(PlayerEvents.PLAYLIST_ADD, message, queue, pl); + tracks.splice(startFromIndex, 1); + this._addTracksToQueue(message, tracks); this.emit(PlayerEvents.TRACK_START, message, queue.tracks[0], queue); - tracks.shift(); - this._addTracksToQueue(message, tracks); } return; @@ -357,17 +361,21 @@ export class Player extends EventEmitter { // @ts-ignore // tslint:disable-next-line:no-shadowed-variable const tracks = playlist.videos as Track[]; + if (startFromIndex < 0) startFromIndex = 0; + if (startFromIndex > tracks.length - 1) startFromIndex = tracks.length - 1; if (this.isPlaying(message)) { + const prioritisedTrack = tracks.splice(startFromIndex, 1); + tracks.unshift(prioritisedTrack); const queue = this._addTracksToQueue(message, tracks); this.emit(PlayerEvents.PLAYLIST_ADD, message, queue, playlist); } else { - const track = tracks[0]; - const queue = (await this._createQueue(message, track).catch((e) => void this.emit(PlayerEvents.ERROR, e, message))) as Queue; - this.emit(PlayerEvents.PLAYLIST_ADD, message, queue, playlist); + const track = tracks[startFromIndex]; + const queue = (await this._createQueue(message, track).catch((e) => void this.emit(PlayerEvents.ERROR, e, message))) as Queue; + this.emit(PlayerEvents.PLAYLIST_ADD, message, queue, pl); + tracks.splice(startFromIndex, 1); + this._addTracksToQueue(message, tracks); this.emit(PlayerEvents.TRACK_START, message, queue.tracks[0], queue); - tracks[0]; - this._addTracksToQueue(message, tracks); } return; @@ -410,17 +418,20 @@ export class Player extends EventEmitter { res.duration = res.tracks.reduce((a, c) => a + c.durationMS, 0); this.emit(PlayerEvents.PLAYLIST_PARSE_END, res, message); + if (startFromIndex < 0) res.startFromIndex = 0; + if (startFromIndex > tracks.length - 1) startFromIndex = res.tracks.length - 1; if (this.isPlaying(message)) { - const queue = this._addTracksToQueue(message, res.tracks); + const prioritisedTrack = res.tracks.splice(startFromIndex, 1); + res.tracks.unshift(prioritisedTrack); this.emit(PlayerEvents.PLAYLIST_ADD, message, queue, res); } else { - const track = res.tracks[0]; + const track = res.tracks[startFromIndex ? startFromIndex - 1 : 0]; const queue = (await this._createQueue(message, track).catch((e) => void this.emit(PlayerEvents.ERROR, e, message))) as Queue; this.emit(PlayerEvents.PLAYLIST_ADD, message, queue, res); - this.emit(PlayerEvents.TRACK_START, message, queue.tracks[0], queue); - res.tracks.shift(); + res.tracks.splice(startFromIndex ? startFromIndex - 1 : 0, 1); this._addTracksToQueue(message, res.tracks); + this.emit(PlayerEvents.TRACK_START, message, queue.tracks[0], queue); } return; @@ -459,7 +470,6 @@ export class Player extends EventEmitter { this.emit(PlayerEvents.SEARCH_INVALID_RESPONSE, message, query, tracks, content, collector); } }); - collector.on('end', (_, reason) => { if (reason === 'time') { this.emit(PlayerEvents.SEARCH_CANCEL, message, query, tracks); @@ -476,7 +486,7 @@ export class Player extends EventEmitter { * @example await player.play(message, "never gonna give you up", true) * @returns {Promise} */ - async play(message: Message, query: string | Track, firstResult?: boolean): Promise { + async play(message: Message, query: string | Track, firstResult?: boolean, startFromIndex?: number = 0): Promise { if (!message) throw new PlayerError('Play function needs message'); if (!query) throw new PlayerError('Play function needs search query as a string or Player.Track object'); @@ -533,7 +543,7 @@ export class Player extends EventEmitter { } } - if (!track) track = await this._searchTracks(message, query, firstResult); + if (!track) track = await this._searchTracks(message, query, firstResult, startFromIndex); } }