Skip to content

Commit ffa35df

Browse files
committed
improve load and seek
1 parent 7667e60 commit ffa35df

File tree

1 file changed

+46
-33
lines changed

1 file changed

+46
-33
lines changed

src/library/core.ts

Lines changed: 46 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,12 @@ const PLAYER_MODE_FETCH = 'player_mode_fetch';
1212
const WHERE_IN_QUEUE_AT_START = 'prepend';
1313
const WHERE_IN_QUEUE_AT_END = 'append';
1414

15+
const AFTER_LOADING_SEEK = 'after_loading_seek';
16+
const AFTER_LOADING_PLAY = 'after_loading_play';
17+
1518
type typePlayerMode = typeof PLAYER_MODE_AUDIO | typeof PLAYER_MODE_AJAX | typeof PLAYER_MODE_FETCH;
1619
type typeWhereInQueue = typeof WHERE_IN_QUEUE_AT_START | typeof WHERE_IN_QUEUE_AT_END;
20+
type typeAfterLoadingAction = typeof AFTER_LOADING_SEEK | typeof AFTER_LOADING_PLAY;
1721

1822
export interface ICoreOptions {
1923
volume?: number;
@@ -82,6 +86,9 @@ export class PlayerCore {
8286
static readonly WHERE_IN_QUEUE_AT_END = 'append';
8387
static readonly WHERE_IN_QUEUE_AT_START = 'prepend';
8488

89+
static readonly AFTER_LOADING_SEEK = 'after_loading_seek';
90+
static readonly AFTER_LOADING_PLAY = 'after_loading_play';
91+
8592
static readonly PLAY_SOUND_NEXT = 'next';
8693
static readonly PLAY_SOUND_PREVIOUS = 'previous';
8794
static readonly PLAY_SOUND_FIRST = 'first';
@@ -293,7 +300,7 @@ export class PlayerCore {
293300

294301
// the user can set the sound duration manually but if he didn't the sound
295302
// needs to get loaded first, to be able to know the duration it has
296-
await this.loadSound(currentSound);
303+
await this.loadSound(currentSound, PlayerCore.AFTER_LOADING_SEEK);
297304

298305
} else {
299306

@@ -307,24 +314,24 @@ export class PlayerCore {
307314

308315
protected _setPosition(sound: ISound): void {
309316

310-
const currentSound = this._getSoundFromQueue({ whichSound: PlayerCore.CURRENT_SOUND });
311-
312-
if (currentSound !== null) {
313-
314-
const duration = currentSound.getDuration();
315-
316-
// calculate the position in seconds
317-
const soundPositionInSeconds = (duration / 100) * sound.seekPercentage;
317+
const duration = sound.getDuration();
318318

319-
this.setPositionInSeconds(soundPositionInSeconds);
319+
// calculate the position in seconds
320+
const soundPositionInSeconds = (duration / 100) * sound.seekPercentage;
320321

321-
}
322+
this.setPositionInSeconds(soundPositionInSeconds, sound);
322323

323324
}
324325

325-
public async setPositionInSeconds(soundPositionInSeconds: number): Promise<void> {
326+
public async setPositionInSeconds(soundPositionInSeconds: number, sound?: ISound): Promise<void> {
326327

327-
const currentSound = this._getSoundFromQueue({ whichSound: PlayerCore.CURRENT_SOUND });
328+
let currentSound: ISound = null;
329+
330+
if (typeof sound !== 'undefined') {
331+
currentSound = sound;
332+
} else {
333+
currentSound = this._getSoundFromQueue({ whichSound: PlayerCore.CURRENT_SOUND });
334+
}
328335

329336
if (currentSound !== null) {
330337

@@ -377,14 +384,14 @@ export class PlayerCore {
377384

378385
}
379386

380-
public async loadSound(sound: ISound): Promise<ISound> {
387+
public async loadSound(sound: ISound, afterLoadingAction?: typeAfterLoadingAction): Promise<ISound> {
381388

382389
switch (this._options.loadPlayerMode) {
383390
case PlayerCore.PLAYER_MODE_AUDIO:
384-
await this._loadSoundUsingAudioElement(sound);
391+
await this._loadSoundUsingAudioElement(sound, afterLoadingAction);
385392
break;
386393
case PlayerCore.PLAYER_MODE_AJAX:
387-
await this._loadSoundUsingRequest(sound);
394+
await this._loadSoundUsingRequest(sound, afterLoadingAction);
388395
break;
389396
case PlayerCore.PLAYER_MODE_FETCH:
390397
// TODO: implement fetch (?)
@@ -396,7 +403,7 @@ export class PlayerCore {
396403

397404
}
398405

399-
protected async _loadSoundUsingAudioElement(sound: ISound): Promise<void> {
406+
protected async _loadSoundUsingAudioElement(sound: ISound, afterLoadingAction?: typeAfterLoadingAction): Promise<void> {
400407

401408
// extract the url and codec from sources
402409
const { url, codec = null } = this._findBestSource(sound.source);
@@ -414,10 +421,15 @@ export class PlayerCore {
414421

415422
if (sound.audioElement.buffered.length) {
416423

417-
const duration = sound.getDuration()
418-
const buffered = sound.audioElement.buffered.end(0)
419-
const loadingPercentageRaw = 100 / (duration / buffered);
420-
const loadingPercentage = Math.round(loadingPercentageRaw);
424+
let loadingPercentage: number;
425+
426+
const buffered = sound.audioElement.buffered.end(0);
427+
const duration = sound.getDuration();
428+
429+
if (typeof duration !== 'undefined') {
430+
const loadingPercentageRaw = 100 / (duration / buffered);
431+
loadingPercentage = Math.round(loadingPercentageRaw);
432+
}
421433

422434
sound.loadingProgress = loadingPercentage;
423435

@@ -446,11 +458,11 @@ export class PlayerCore {
446458
sound.duration = sound.audioElement.duration;
447459
}
448460

449-
switch (sound.state) {
450-
case PlayerSound.SOUND_STATE_SEEKING:
461+
switch (afterLoadingAction) {
462+
case PlayerCore.AFTER_LOADING_SEEK:
451463
this._setPosition(sound)
452464
break;
453-
case PlayerSound.SOUND_STATE_PLAYING:
465+
case PlayerCore.AFTER_LOADING_PLAY:
454466
this._play(sound);
455467
break;
456468
}
@@ -480,7 +492,7 @@ export class PlayerCore {
480492

481493
}
482494

483-
protected async _loadSoundUsingRequest(sound: ISound): Promise<void> {
495+
protected async _loadSoundUsingRequest(sound: ISound, afterLoadingAction?: typeAfterLoadingAction): Promise<void> {
484496

485497
// check for audio buffer before array buffer, because if one exist the other
486498
// should exist too and is better for performance to reuse audio buffer then
@@ -512,7 +524,7 @@ export class PlayerCore {
512524
const arrayBuffer = await request.getArrayBuffer(sound);
513525
sound.arrayBuffer = arrayBuffer;
514526

515-
await this._decodeSound(sound);
527+
await this._decodeSound(sound, afterLoadingAction);
516528

517529
} else {
518530

@@ -522,7 +534,7 @@ export class PlayerCore {
522534

523535
}
524536

525-
protected async _decodeSound(sound: ISound): Promise<void> {
537+
protected async _decodeSound(sound: ISound, afterLoadingAction?: typeAfterLoadingAction): Promise<void> {
526538

527539
// make a copy of the array buffer first
528540
// because the decoding will detach the array buffer
@@ -531,8 +543,9 @@ export class PlayerCore {
531543

532544
const audioBuffer = await this._playerAudio.decodeAudio(arrayBufferCopy);
533545

534-
// only update duration if it did not get set manually
535-
if (!sound.durationSetManually) {
546+
// duration should now be available
547+
// if it got set manually don't overwrite it
548+
if (!isNaN(audioBuffer.duration) && !sound.durationSetManually) {
536549
sound.duration = audioBuffer.duration;
537550
}
538551

@@ -542,11 +555,11 @@ export class PlayerCore {
542555
sound.audioBufferDate = new Date();
543556
sound.isReadyToPLay = true;
544557

545-
switch (sound.state) {
546-
case PlayerSound.SOUND_STATE_SEEKING:
558+
switch (afterLoadingAction) {
559+
case PlayerCore.AFTER_LOADING_SEEK:
547560
this._setPosition(sound)
548561
break;
549-
case PlayerSound.SOUND_STATE_PLAYING:
562+
case PlayerCore.AFTER_LOADING_PLAY:
550563
this._play(sound);
551564
break;
552565
}
@@ -614,7 +627,7 @@ export class PlayerCore {
614627

615628
if (!sound.isReadyToPLay) {
616629

617-
await this.loadSound(sound);
630+
await this.loadSound(sound, PlayerCore.AFTER_LOADING_PLAY);
618631

619632
} else {
620633

0 commit comments

Comments
 (0)