This repository has been archived by the owner on Apr 18, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 320
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: LSDV-5033: Add the option to use WebAudioPlayer for Audio (#1360)
* feat: LSDV-5033: Add the option to use WebAudioPlayer for Audio * fix the audio buffer * fix play source for webaudio player * formatting of audio model file * putting back the doc param for player * feedback changes * fix player volume and playback rate setting along with webaudio waveform init --------- Co-authored-by: bmartel <[email protected]>
- Loading branch information
Showing
13 changed files
with
553 additions
and
338 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
import { WaveformAudio } from '../Media/WaveformAudio'; | ||
import { Player } from './Player'; | ||
|
||
export class Html5Player extends Player { | ||
mute() { | ||
super.mute(); | ||
if (this.audio?.el) { | ||
this.audio.el.muted = true; | ||
} | ||
} | ||
|
||
unmute() { | ||
super.unmute(); | ||
if (this.audio?.el) { | ||
this.audio.el.muted = false; | ||
} | ||
} | ||
|
||
/** | ||
* Get current playback speed | ||
*/ | ||
get rate() { | ||
if (this.audio?.el) { | ||
if (this.audio.el.playbackRate !== this._rate) { | ||
this.audio.el.playbackRate = this._rate; // restore the correct rate | ||
} | ||
} | ||
|
||
return this._rate; | ||
} | ||
|
||
/** | ||
* Set playback speed | ||
*/ | ||
set rate(value: number) { | ||
const rateChanged = this._rate !== value; | ||
|
||
this._rate = value; | ||
|
||
if (rateChanged) { | ||
if (this.audio?.el) { | ||
this.audio.el.playbackRate = value; | ||
} | ||
this.wf.invoke('rateChanged', [value]); | ||
} | ||
} | ||
|
||
init(audio: WaveformAudio) { | ||
super.init(audio); | ||
|
||
if (!this.audio || !this.audio.el) return; | ||
|
||
this.audio.on('resetSource', this.handleResetSource); | ||
|
||
this.audio.el.addEventListener('play', this.handlePlayed); | ||
this.audio.el.addEventListener('pause', this.handlePaused); | ||
} | ||
|
||
destroy() { | ||
super.destroy(); | ||
|
||
if (this.audio?.el) { | ||
this.audio.el.removeEventListener('play', this.handlePlayed); | ||
this.audio.el.removeEventListener('pause', this.handlePaused); | ||
} | ||
} | ||
|
||
protected adjustVolume(): void { | ||
if (this.audio?.el) { | ||
this.audio.el.volume = this.volume; | ||
} | ||
} | ||
|
||
protected playAudio(_start?: number, _duration?: number): void { | ||
if (!this.audio || !this.audio.el) return; | ||
|
||
this.audio.el.currentTime = this.currentTime; | ||
this.audio.el.addEventListener('ended', this.handleEnded); | ||
this.bufferPromise = new Promise(resolve => { | ||
this.bufferResolve = resolve; | ||
}); | ||
|
||
const time = this.currentTime; | ||
|
||
Promise.all([ | ||
this.audio.el.play(), | ||
this.bufferPromise, | ||
]) | ||
.then(() => { | ||
this.timestamp = performance.now(); | ||
|
||
// We need to compensate for the time it took to load the buffer | ||
// otherwise the audio will be out of sync of the timer we use to | ||
// render updates | ||
if (this.audio?.el) { | ||
// This must not be notifying of this adjustment otherwise it can cause sync issues and near infinite loops | ||
this.setCurrentTime(time); | ||
this.audio.el.currentTime = this.currentTime; | ||
this.watch(); | ||
} | ||
}); | ||
} | ||
|
||
protected updateCurrentSourceTime(timeChanged: boolean) { | ||
if (timeChanged && this.audio?.el) { | ||
this.audio.el.currentTime = this.time; | ||
} | ||
} | ||
|
||
protected canPause() { | ||
return !!(this.audio?.el && !this.audio.el.paused && this.hasPlayed); | ||
} | ||
|
||
protected disconnectSource(): boolean { | ||
if (super.disconnectSource()) { | ||
this.audio?.el?.removeEventListener('ended', this.handleEnded); | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
protected handleResetSource = async () => { | ||
if (!this.audio?.el) return; | ||
|
||
const wasPlaying = this.playing; | ||
|
||
this.stop(); | ||
this.audio.el.load(); | ||
|
||
if (wasPlaying) this.play(); | ||
}; | ||
} |
Oops, something went wrong.