Skip to content

Commit

Permalink
Add howler.js for seamless audio looping
Browse files Browse the repository at this point in the history
  • Loading branch information
selimnahimi committed Sep 29, 2023
1 parent fff1da4 commit 95521b5
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 13 deletions.
12 changes: 12 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"format": "prettier --write src/"
},
"dependencies": {
"howler": "^2.2.4",
"vue": "^3.3.4",
"vue-facing-decorator": "^3.0.2",
"vue-router": "^4.2.4",
Expand All @@ -22,6 +23,7 @@
"@rushstack/eslint-patch": "^1.3.3",
"@tsconfig/node18": "^18.2.2",
"@types/node": "^18.17.19",
"@types/howler": "^2.2.9",
"@vitejs/plugin-vue": "^4.3.4",
"@vitejs/plugin-vue-jsx": "^3.0.2",
"@vue/eslint-config-prettier": "^8.0.0",
Expand Down
9 changes: 5 additions & 4 deletions src/components/SoundscapePlayer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class SoundscapePlayer extends Vue {
timers: { [key: number]: ReturnType<typeof setTimeout> } = {};
activeLoopingSounds: HTMLAudioElement[] = [];
activeLoopingSounds: Howl[] = [];
mounted() {
console.log("playing " + this.soundscape.name);
Expand Down Expand Up @@ -56,7 +56,8 @@ class SoundscapePlayer extends Vue {
private stopLoops() {
this.activeLoopingSounds.forEach(sound => {
sound.pause();
sound.stop();
sound.unload();
});
this.activeLoopingSounds = [];
Expand Down Expand Up @@ -141,9 +142,9 @@ class SoundscapePlayer extends Vue {
return;
let randomVolume = this.getRandomVolume(action);
let sound = SoundPlayer.playSoundFileLoop(soundFile, randomVolume);
this.activeLoopingSounds.push(sound);
SoundPlayer.playSoundFileLoop(soundFile, randomVolume)
.then(audio => this.activeLoopingSounds.push(audio));
}
private playActionRandom(action: SoundscapeAction) {
Expand Down
34 changes: 25 additions & 9 deletions src/lib/SoundPlayer.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,40 @@
import { Howl } from "howler";

export default class SoundPlayer {
static defaultGame = 'hl2';

static playSoundFile(file: File, volume: number = 1.0, game: string = this.defaultGame): HTMLAudioElement {
return this.play(file, volume, false, game);
}

static playSoundFileLoop(file: File, volume: number = 1.0, game: string = this.defaultGame): HTMLAudioElement {
return this.play(file, volume, true, game);
}

private static play(file: File, volume: number, loop: boolean = false, game: string): HTMLAudioElement {
const url = URL.createObjectURL(file);
const audio = new Audio(url);
audio.volume = this.clampVolume(volume);
audio.loop = loop;
audio.play();

return audio;
}

static playSoundFileLoop(file: File, volume: number = 1.0, game: string = this.defaultGame): Promise<Howl> {
return new Promise((resolve, _) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onloadend = () => {
const base64data = reader.result;

if (typeof base64data !== 'string')
return;

var audio = new Howl({
src: [base64data],
volume: volume,
autoplay: false,
loop: true
});
audio.play();

resolve(audio);
}
});
}

private static clampVolume(volume: number): number {
if (volume > 1.0) {
return 1.0;
Expand Down

0 comments on commit 95521b5

Please sign in to comment.