Skip to content

Commit df28c55

Browse files
committed
replace setInterval with requestAnimationFrame
1 parent a7dacdf commit df28c55

File tree

3 files changed

+32
-43
lines changed

3 files changed

+32
-43
lines changed

dist/library/core.d.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ export declare class PlayerCore {
5050
protected _currentIndex: number;
5151
protected _playerAudio: PlayerAudio;
5252
protected _playingProgressIntervalTime: number;
53-
protected _playingTimeoutID: number | null;
53+
protected _playingProgressRequestId: number | null;
54+
protected _playingProgressPreviousTimestamp: DOMHighResTimeStamp;
5455
protected _playNextOnEnded: boolean;
5556
protected _loopQueue: boolean;
5657
protected _loopSong: boolean;
@@ -103,6 +104,7 @@ export declare class PlayerCore {
103104
protected _playAudioBuffer(sound: ISound): Promise<void>;
104105
protected _playMediaElementAudio(sound: ISound): Promise<void>;
105106
protected _setupSoundEvents(sound: ISound): ISound;
107+
protected _progressTrigger: (sound: ISound, timestamp: DOMHighResTimeStamp) => void;
106108
protected _onEnded(): void;
107109
/**
108110
* whichSound is optional, if set it can be the sound id or if it's

src/library/audio.ts

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -48,21 +48,10 @@ interface IAudioOptions {
4848

4949
interface IAudioBufferSourceOptions extends AudioBufferSourceOptions {
5050
onEnded: IOnEnded;
51-
/* AudioBufferSourceOptions:
52-
AudioBuffer? buffer;
53-
float detune = 0;
54-
boolean loop = false;
55-
double loopEnd = 0;
56-
double loopStart = 0;
57-
float playbackRate = 1;
58-
*/
5951
}
6052

6153
interface IMediaElementAudioSourceOptions extends MediaElementAudioSourceOptions {
6254
onEnded: IOnEnded;
63-
/* MediaElementAudioSourceOptions:
64-
required HTMLMediaElement mediaElement;
65-
*/
6655
loop: boolean;
6756
}
6857

@@ -185,7 +174,7 @@ class PlayerAudio {
185174

186175
} else {
187176
// TODO: are other states possible?
188-
console.log('audioContext.state: ', this._audioContext.state);
177+
//console.log('audioContext.state: ', this._audioContext.state);
189178
}
190179

191180
});

src/library/core.ts

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,10 @@ export class PlayerCore {
7979
protected _playerAudio: PlayerAudio;
8080
// playing progress time interval
8181
protected _playingProgressIntervalTime: number;
82-
// playing progress interval id
83-
protected _playingProgressIntervalId: number | null = null;
8482
// playing progress animation frame request id
8583
protected _playingProgressRequestId: number | null = null;
84+
// playing progress animation frame previous timestamp
85+
protected _playingProgressPreviousTimestamp: DOMHighResTimeStamp = 0;
8686
// when a song finishes, automatically play the next one
8787
protected _playNextOnEnded: boolean;
8888
// do we start over again at the end of the queue
@@ -129,7 +129,7 @@ export class PlayerCore {
129129
loopQueue: false,
130130
loopSong: false,
131131
soundsBaseUrl: '',
132-
playingProgressIntervalTime: -1,
132+
playingProgressIntervalTime: 200,
133133
playNextOnEnded: true,
134134
audioGraph: null,
135135
audioContext: null,
@@ -526,12 +526,10 @@ export class PlayerCore {
526526
this._initializeAudioElementListeners(sound);
527527

528528
sound.audioElement.addEventListener('canplaythrough', () => {
529-
//console.log('BBBBBBBBBBBB', event, sound);
530529
resolve(sound);
531530
});
532531

533532
sound.audioElement.addEventListener('error', () => {
534-
//console.log('CCCCCCCCCCCC', event, sound);
535533
const soundLoadingError = new PlayerError('loading sound failed');
536534
reject(soundLoadingError);
537535
});
@@ -764,9 +762,8 @@ export class PlayerCore {
764762
// source node options
765763
const sourceOptions: IAudioBufferSourceOptions = {
766764
loop: sound.loop,
767-
onEnded: (event: Event) => {
765+
onEnded: (/*event: Event*/) => {
768766
this._onEnded()
769-
console.log('AudioBufferSourceNode ended', event);
770767
}
771768
};
772769

@@ -808,9 +805,8 @@ export class PlayerCore {
808805
// source node options
809806
const sourceOptions: IMediaElementAudioSourceOptions = {
810807
loop: sound.loop,
811-
onEnded: (event: Event) => {
808+
onEnded: (/**event: Event*/) => {
812809
this._onEnded()
813-
console.log('MediaElementSourceNode ended', event);
814810
},
815811
mediaElement: sound.audioElement
816812
};
@@ -849,37 +845,31 @@ export class PlayerCore {
849845

850846
protected _setupSoundEvents(sound: ISound): ISound {
851847

852-
// trigger resumed event
848+
// if there is an onResumed callback for the sound trigger it
853849
if (sound.onResumed !== null && !sound.firstTimePlayed) {
854850
sound.onResumed(sound.playTimeOffset);
855851
}
856852

857-
// trigger started event
853+
// if there is an onStarted callback for the sound trigger it
858854
if (sound.onStarted !== null && sound.firstTimePlayed) {
859855

860856
sound.onStarted(sound.playTimeOffset);
861857
sound.firstTimePlayed = false;
862858

863859
}
864860

865-
// trigger playing event
861+
// if there is an onPlaying callback for the sound trigger it
866862
if (sound.onPlaying !== null) {
867863

868-
if (this._playingProgressIntervalTime < 0) {
869-
// on request animation frame callback set playing progress
870-
this._playingProgressRequestId = window.requestAnimationFrame(() => {
871-
this._playingProgress(sound);
872-
});
873-
} else {
874-
// at interval set playing progress
875-
this._playingProgressIntervalId = window.setInterval(() => {
876-
this._playingProgress(sound);
877-
}, this._playingProgressIntervalTime);
878-
}
864+
// on request animation frame callback set playing progress
865+
// request animation frame callback has a argument, which
866+
// is the timestamp when the callback gets called
867+
this._playingProgressRequestId = window.requestAnimationFrame((timestamp) => {
868+
this._progressTrigger(sound, timestamp)
869+
});
879870

880871
} else {
881872

882-
this._playingProgressIntervalId = null;
883873
this._playingProgressRequestId = null;
884874

885875
}
@@ -888,6 +878,19 @@ export class PlayerCore {
888878

889879
}
890880

881+
protected _progressTrigger = (sound: ISound, timestamp: DOMHighResTimeStamp) => {
882+
// throttle requests to not more than once every 200ms
883+
if ((timestamp - this._playingProgressPreviousTimestamp) >= this._playingProgressIntervalTime) {
884+
// execute playing progress callback
885+
this._playingProgress(sound);
886+
this._playingProgressPreviousTimestamp = timestamp;
887+
}
888+
// request animation frame loop
889+
this._playingProgressRequestId = window.requestAnimationFrame((timestamp) => {
890+
this._progressTrigger(sound, timestamp);
891+
});
892+
};
893+
891894
protected _onEnded(): void {
892895

893896
// get the current sound if any
@@ -1255,12 +1258,9 @@ export class PlayerCore {
12551258
// state is now stopped
12561259
sound.state = soundState;
12571260

1258-
if (this._playingProgressIntervalId !== null) {
1259-
clearInterval(this._playingProgressIntervalId);
1260-
}
1261-
12621261
if (this._playingProgressRequestId !== null) {
12631262
cancelAnimationFrame(this._playingProgressRequestId);
1263+
this._playingProgressPreviousTimestamp = 0;
12641264
}
12651265

12661266
}
@@ -1306,8 +1306,6 @@ export class PlayerCore {
13061306

13071307
sound.onPlaying(playingPercentage, duration, sound.playTime);
13081308

1309-
1310-
13111309
}
13121310

13131311
public setAudioGraph(customAudioGraph: IAudioGraph): void {

0 commit comments

Comments
 (0)