Proposal changes based on #477
This fixes the problem where the first track of parsed youtube playlist gets played twice; Changed code order so initial `trackStart` event can now see the queue; Added a new parameter to `Player#play` and `Player_searchTracks`: `startFromIndex (number)`: This parameter lets the user priorities the track with corresponding index (array index, starts from 0), `0` by default. If one is specified and there is no queue, the specified track will be played first; Otherwise if it's already playing then the specified track will be put on the first index of the added playlist.
This commit is contained in:
parent
8e876fbfac
commit
6d9997dd4f
1 changed files with 28 additions and 18 deletions
|
@ -144,7 +144,7 @@ export class Player extends EventEmitter {
|
||||||
* @returns {Promise<Track>}
|
* @returns {Promise<Track>}
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
private _searchTracks(message: Message, query: string, firstResult?: boolean): Promise<Track> {
|
private _searchTracks(message: Message, query: string, firstResult?: boolean, startFromIndex?: number = 0): Promise<Track> {
|
||||||
return new Promise(async (resolve) => {
|
return new Promise(async (resolve) => {
|
||||||
let tracks: Track[] = [];
|
let tracks: Track[] = [];
|
||||||
const queryType = Util.getQueryType(query);
|
const queryType = Util.getQueryType(query);
|
||||||
|
@ -302,17 +302,21 @@ export class Player extends EventEmitter {
|
||||||
};
|
};
|
||||||
|
|
||||||
this.emit(PlayerEvents.PLAYLIST_PARSE_END, pl, message);
|
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)) {
|
if (this.isPlaying(message)) {
|
||||||
|
const prioritisedTrack = tracks.splice(startFromIndex, 1);
|
||||||
|
tracks.unshift(prioritisedTrack);
|
||||||
const queue = this._addTracksToQueue(message, tracks);
|
const queue = this._addTracksToQueue(message, tracks);
|
||||||
this.emit(PlayerEvents.PLAYLIST_ADD, message, queue, pl);
|
this.emit(PlayerEvents.PLAYLIST_ADD, message, queue, playlist);
|
||||||
} else {
|
} else {
|
||||||
const track = tracks[0];
|
const track = tracks[startFromIndex];
|
||||||
const queue = (await this._createQueue(message, track).catch((e) => void this.emit(PlayerEvents.ERROR, e, message))) as Queue;
|
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);
|
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);
|
this.emit(PlayerEvents.TRACK_START, message, queue.tracks[0], queue);
|
||||||
tracks.shift();
|
|
||||||
this._addTracksToQueue(message, tracks);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -357,17 +361,21 @@ export class Player extends EventEmitter {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
// tslint:disable-next-line:no-shadowed-variable
|
// tslint:disable-next-line:no-shadowed-variable
|
||||||
const tracks = playlist.videos as Track[];
|
const tracks = playlist.videos as Track[];
|
||||||
|
if (startFromIndex < 0) startFromIndex = 0;
|
||||||
|
if (startFromIndex > tracks.length - 1) startFromIndex = tracks.length - 1;
|
||||||
|
|
||||||
if (this.isPlaying(message)) {
|
if (this.isPlaying(message)) {
|
||||||
|
const prioritisedTrack = tracks.splice(startFromIndex, 1);
|
||||||
|
tracks.unshift(prioritisedTrack);
|
||||||
const queue = this._addTracksToQueue(message, tracks);
|
const queue = this._addTracksToQueue(message, tracks);
|
||||||
this.emit(PlayerEvents.PLAYLIST_ADD, message, queue, playlist);
|
this.emit(PlayerEvents.PLAYLIST_ADD, message, queue, playlist);
|
||||||
} else {
|
} else {
|
||||||
const track = tracks[0];
|
const track = tracks[startFromIndex];
|
||||||
const queue = (await this._createQueue(message, track).catch((e) => void this.emit(PlayerEvents.ERROR, e, message))) as Queue;
|
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);
|
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);
|
this.emit(PlayerEvents.TRACK_START, message, queue.tracks[0], queue);
|
||||||
tracks[0];
|
|
||||||
this._addTracksToQueue(message, tracks);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -410,17 +418,20 @@ export class Player extends EventEmitter {
|
||||||
res.duration = res.tracks.reduce((a, c) => a + c.durationMS, 0);
|
res.duration = res.tracks.reduce((a, c) => a + c.durationMS, 0);
|
||||||
|
|
||||||
this.emit(PlayerEvents.PLAYLIST_PARSE_END, res, message);
|
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)) {
|
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);
|
this.emit(PlayerEvents.PLAYLIST_ADD, message, queue, res);
|
||||||
} else {
|
} 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;
|
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.PLAYLIST_ADD, message, queue, res);
|
||||||
this.emit(PlayerEvents.TRACK_START, message, queue.tracks[0], queue);
|
res.tracks.splice(startFromIndex ? startFromIndex - 1 : 0, 1);
|
||||||
res.tracks.shift();
|
|
||||||
this._addTracksToQueue(message, res.tracks);
|
this._addTracksToQueue(message, res.tracks);
|
||||||
|
this.emit(PlayerEvents.TRACK_START, message, queue.tracks[0], queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -459,7 +470,6 @@ export class Player extends EventEmitter {
|
||||||
this.emit(PlayerEvents.SEARCH_INVALID_RESPONSE, message, query, tracks, content, collector);
|
this.emit(PlayerEvents.SEARCH_INVALID_RESPONSE, message, query, tracks, content, collector);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
collector.on('end', (_, reason) => {
|
collector.on('end', (_, reason) => {
|
||||||
if (reason === 'time') {
|
if (reason === 'time') {
|
||||||
this.emit(PlayerEvents.SEARCH_CANCEL, message, query, tracks);
|
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)
|
* @example await player.play(message, "never gonna give you up", true)
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
*/
|
*/
|
||||||
async play(message: Message, query: string | Track, firstResult?: boolean): Promise<void> {
|
async play(message: Message, query: string | Track, firstResult?: boolean, startFromIndex?: number = 0): Promise<void> {
|
||||||
if (!message) throw new PlayerError('Play function needs message');
|
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');
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue