@@ -12,8 +12,12 @@ const PLAYER_MODE_FETCH = 'player_mode_fetch';
1212const WHERE_IN_QUEUE_AT_START = 'prepend' ;
1313const WHERE_IN_QUEUE_AT_END = 'append' ;
1414
15+ const AFTER_LOADING_SEEK = 'after_loading_seek' ;
16+ const AFTER_LOADING_PLAY = 'after_loading_play' ;
17+
1518type typePlayerMode = typeof PLAYER_MODE_AUDIO | typeof PLAYER_MODE_AJAX | typeof PLAYER_MODE_FETCH ;
1619type 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
1822export 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