WIP: Migrate AudioManager in Svelte (#1325)
* Migrate AudioManager in Svelte * use import type when needed
This commit is contained in:
parent
ac282db1ac
commit
e0fb31fc58
9 changed files with 258 additions and 288 deletions
|
@ -1,188 +0,0 @@
|
|||
import {HtmlUtils} from "./HtmlUtils";
|
||||
import {isUndefined} from "generic-type-guard";
|
||||
import {localUserStore} from "../Connexion/LocalUserStore";
|
||||
|
||||
enum audioStates {
|
||||
closed = 0,
|
||||
loading = 1,
|
||||
playing = 2
|
||||
}
|
||||
|
||||
const audioPlayerDivId = "audioplayer";
|
||||
const audioPlayerCtrlId = "audioplayerctrl";
|
||||
const audioPlayerVolId = "audioplayer_volume";
|
||||
const audioPlayerMuteId = "audioplayer_volume_icon_playing";
|
||||
const animationTime = 500;
|
||||
|
||||
class AudioManager {
|
||||
private opened = audioStates.closed;
|
||||
|
||||
private audioPlayerDiv: HTMLDivElement;
|
||||
private audioPlayerCtrl: HTMLDivElement;
|
||||
private audioPlayerElem: HTMLAudioElement | undefined;
|
||||
private audioPlayerVol: HTMLInputElement;
|
||||
private audioPlayerMute: HTMLInputElement;
|
||||
|
||||
private volume = 1;
|
||||
private muted = false;
|
||||
private decreaseWhileTalking = true;
|
||||
private volumeReduced = false;
|
||||
|
||||
constructor() {
|
||||
this.audioPlayerDiv = HtmlUtils.getElementByIdOrFail<HTMLDivElement>(audioPlayerDivId);
|
||||
this.audioPlayerCtrl = HtmlUtils.getElementByIdOrFail<HTMLDivElement>(audioPlayerCtrlId);
|
||||
this.audioPlayerVol = HtmlUtils.getElementByIdOrFail<HTMLInputElement>(audioPlayerVolId);
|
||||
this.audioPlayerMute = HtmlUtils.getElementByIdOrFail<HTMLInputElement>(audioPlayerMuteId);
|
||||
|
||||
this.volume = localUserStore.getAudioPlayerVolume();
|
||||
this.audioPlayerVol.value = '' + this.volume;
|
||||
|
||||
this.muted = localUserStore.getAudioPlayerMuted();
|
||||
if (this.muted) {
|
||||
this.audioPlayerMute.classList.add('muted');
|
||||
}
|
||||
}
|
||||
|
||||
public playAudio(url: string|number|boolean, mapDirUrl: string, volume: number|undefined, loop=false): void {
|
||||
const audioPath = url as string;
|
||||
let realAudioPath = '';
|
||||
|
||||
if (audioPath.indexOf('://') > 0) {
|
||||
// remote file or stream
|
||||
realAudioPath = audioPath;
|
||||
} else {
|
||||
// local file, include it relative to map directory
|
||||
realAudioPath = mapDirUrl + '/' + url;
|
||||
}
|
||||
|
||||
this.loadAudio(realAudioPath, volume);
|
||||
|
||||
if (loop) {
|
||||
this.loop();
|
||||
}
|
||||
}
|
||||
|
||||
private close(): void {
|
||||
this.audioPlayerCtrl.classList.remove('loading');
|
||||
this.audioPlayerCtrl.classList.add('hidden');
|
||||
this.opened = audioStates.closed;
|
||||
}
|
||||
|
||||
private load(): void {
|
||||
this.audioPlayerCtrl.classList.remove('hidden');
|
||||
this.audioPlayerCtrl.classList.add('loading');
|
||||
this.opened = audioStates.loading;
|
||||
}
|
||||
|
||||
private open(): void {
|
||||
this.audioPlayerCtrl.classList.remove('hidden', 'loading');
|
||||
this.opened = audioStates.playing;
|
||||
}
|
||||
|
||||
private changeVolume(talking = false): void {
|
||||
if (isUndefined(this.audioPlayerElem)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const reduceVolume = talking && this.decreaseWhileTalking;
|
||||
if (reduceVolume && !this.volumeReduced) {
|
||||
this.volume *= 0.5;
|
||||
} else if (!reduceVolume && this.volumeReduced) {
|
||||
this.volume *= 2.0;
|
||||
}
|
||||
this.volumeReduced = reduceVolume;
|
||||
|
||||
this.audioPlayerElem.volume = this.volume;
|
||||
this.audioPlayerVol.value = '' + this.volume;
|
||||
this.audioPlayerElem.muted = this.muted;
|
||||
}
|
||||
|
||||
private setVolume(volume: number): void {
|
||||
this.volume = volume;
|
||||
localUserStore.setAudioPlayerVolume(volume);
|
||||
}
|
||||
|
||||
private loadAudio(url: string, volume: number|undefined): void {
|
||||
this.load();
|
||||
|
||||
/* Solution 1, remove whole audio player */
|
||||
this.audioPlayerDiv.innerHTML = ''; // necessary, if switching from one audio context to another! (else both streams would play simultaneously)
|
||||
|
||||
this.audioPlayerElem = document.createElement('audio');
|
||||
this.audioPlayerElem.id = 'audioplayerelem';
|
||||
this.audioPlayerElem.controls = false;
|
||||
this.audioPlayerElem.preload = 'none';
|
||||
|
||||
const srcElem = document.createElement('source');
|
||||
srcElem.type = "audio/mp3";
|
||||
srcElem.src = url;
|
||||
|
||||
this.audioPlayerElem.append(srcElem);
|
||||
|
||||
this.audioPlayerDiv.append(this.audioPlayerElem);
|
||||
this.volume = volume ? Math.min(volume, this.volume) : this.volume;
|
||||
this.changeVolume();
|
||||
this.audioPlayerElem.play();
|
||||
|
||||
const muteElem = HtmlUtils.getElementByIdOrFail<HTMLInputElement>('audioplayer_mute');
|
||||
muteElem.onclick = (ev: Event) => {
|
||||
this.muted = !this.muted;
|
||||
this.changeVolume();
|
||||
localUserStore.setAudioPlayerMuted(this.muted);
|
||||
|
||||
if (this.muted) {
|
||||
this.audioPlayerMute.classList.add('muted');
|
||||
} else {
|
||||
this.audioPlayerMute.classList.remove('muted');
|
||||
}
|
||||
}
|
||||
|
||||
this.audioPlayerVol.oninput = (ev: Event)=> {
|
||||
this.setVolume(parseFloat((<HTMLInputElement>ev.currentTarget).value));
|
||||
this.changeVolume();
|
||||
|
||||
(<HTMLInputElement>ev.currentTarget).blur();
|
||||
}
|
||||
|
||||
const decreaseElem = HtmlUtils.getElementByIdOrFail<HTMLInputElement>('audioplayer_decrease_while_talking');
|
||||
decreaseElem.oninput = (ev: Event)=> {
|
||||
this.decreaseWhileTalking = (<HTMLInputElement>ev.currentTarget).checked;
|
||||
this.changeVolume();
|
||||
}
|
||||
|
||||
this.open();
|
||||
}
|
||||
|
||||
private loop(): void {
|
||||
if (this.audioPlayerElem !== undefined) {
|
||||
this.audioPlayerElem.loop = true;
|
||||
}
|
||||
}
|
||||
|
||||
public unloadAudio(): void {
|
||||
try {
|
||||
const audioElem = HtmlUtils.getElementByIdOrFail<HTMLAudioElement>('audioplayerelem');
|
||||
this.volume = audioElem.volume;
|
||||
this.muted = audioElem.muted;
|
||||
audioElem.pause();
|
||||
audioElem.loop = false;
|
||||
audioElem.src = "";
|
||||
audioElem.innerHTML = "";
|
||||
audioElem.load();
|
||||
} catch (e) {
|
||||
console.log('No audio element loaded to unload');
|
||||
}
|
||||
|
||||
this.close();
|
||||
}
|
||||
|
||||
public decreaseVolume(): void {
|
||||
this.changeVolume(true);
|
||||
}
|
||||
|
||||
public restoreVolume(): void {
|
||||
this.changeVolume(false);
|
||||
}
|
||||
}
|
||||
|
||||
export const audioManager = new AudioManager();
|
Loading…
Add table
Add a link
Reference in a new issue