webamp/experiments/audioAbstraction/elementSource.js
2017-09-28 21:45:41 -07:00

120 lines
2.6 KiB
JavaScript

(function() {
const STATUS = {
WAITING: "WAITING",
PLAYING: "PLAYING",
STOPPED: "STOPPED",
PAUSED: "PAUSED"
};
class ElementSource extends window.Emitter {
constructor(context, destination) {
super();
this._context = context;
this._destination = destination;
this._audio = document.createElement("audio");
this._audio.crossorigin = "anonymous";
this._audio.addEventListener("loadend", () => {
if (this._autoPlay) {
this.play();
}
});
this._audio.addEventListener("timeupdate", () => {
this.trigger("positionChange");
});
this._source = this._context.createMediaElementSource(this._audio);
this._loop = true;
this._autoPlay = true; // Do this ourselves for now. The actual API is bonkers and may not play well with mobile Safari
this._source.connect(destination);
}
disconnect() {
this._source.disconnect();
}
// Async for now, for compatibility with BufferAudioSource
async loadUrl(url) {
this._audio.src = url;
if (this._autoPlay) {
this.play();
}
}
loadFile(fileReference) {
this.loadUrl(URL.createObjectURL(fileReference));
}
async play() {
// TODO: set status waiting
if (this._status !== STATUS.PAUSED) {
this.seekToTime(0);
}
await this._audio.play();
this._setStatus(STATUS.PLAYING);
// TODO: set status playing
}
pause() {
this._audio.pause();
this._setStatus(STATUS.PAUSED);
}
stop() {
this._audio.pause();
this._audio.currentTime = 0;
this._setStatus(STATUS.STOPPED);
}
seekToTime(time) {
// Make sure we are within range
// TODO: Use clamp
time = Math.min(time, this.getDuration());
time = Math.max(time, 0);
this._audio.currentTime = time;
this.trigger("positionChange");
}
getStatus() {
return this._status;
}
getDuration() {
const { duration } = this._audio;
return isNaN(duration) ? 0 : duration;
}
getTimeElapsed() {
return this._audio.currentTime;
}
getNumberOfChannels() {
return this._source.channelCount;
}
getSampleRate() {
return null;
}
getLoop() {
return this._loop;
}
setLoop(shouldLoop) {
this._loop = shouldLoop;
}
setAutoPlay(shouldAutoPlay) {
this._autoPlay = shouldAutoPlay;
}
_setStatus(status) {
this._status = status;
this.trigger("statusChange");
}
}
window.ElementSource = ElementSource;
//export default AudioSource;
})();