From c75964d599df76186c9f5d0bcce30b2ea10cb8ea Mon Sep 17 00:00:00 2001 From: dataexcess Date: Tue, 29 Nov 2022 12:30:42 +0100 Subject: [PATCH] refactor using audio instance on Audio component + no need to inject render --- src/audio/Audio.ts | 74 ++++++++++++++++++------------------ src/audio/AudioListener.ts | 9 ++--- src/audio/PositionalAudio.ts | 12 +++--- src/audio/StaticAudio.ts | 8 ++-- 4 files changed, 50 insertions(+), 53 deletions(-) diff --git a/src/audio/Audio.ts b/src/audio/Audio.ts index f66443e..0b870ab 100644 --- a/src/audio/Audio.ts +++ b/src/audio/Audio.ts @@ -3,12 +3,13 @@ import { defineComponent } from 'vue' import Object3D from '../core/Object3D' import { bindProp } from '../tools' -export interface AudioSetupInterface { - streamMediaElement?: HTMLAudioElement -} - type ConcreteAudio = StaticAudio | PositionalAudio +export interface AudioSetupInterface { + audio?: ConcreteAudio + streamedAudio?: HTMLAudioElement +} + export default defineComponent({ extends: Object3D, name: 'Audio', @@ -18,64 +19,65 @@ export default defineComponent({ isStreamed: { type: Boolean, default: true } }, setup (): AudioSetupInterface { - let streamMediaElement = new Audio(); - return { streamMediaElement } + let streamedAudio = new Audio(); + return { streamedAudio } }, methods: { initAudio(audio: ConcreteAudio) { - this.initObject3D(audio) - this.bindProps(audio) - this.loadAudioAndPlay(audio) + this.audio = audio + this.initObject3D(this.audio) + this.bindProps() + this.loadAudioAndPlay() }, - bindProps(audio: ConcreteAudio) { + bindProps() { ['volume', 'isStreamed'].forEach(p => { - bindProp(this.$props, p, audio) + bindProp(this, p, this.audio) }) }, - loadAudioAndPlay(audio: ConcreteAudio) { + loadAudioAndPlay() { if (!this.src) return undefined if (this.isStreamed) { - this.loadAudioFromStream(audio, this.src) + this.loadAudioFromStream() } else { - this.loadAudioFromMemory(audio, this.src) + this.loadAudioFromMemory() } }, - loadAudioFromMemory(audio:ConcreteAudio, src:string) { + loadAudioFromMemory() { const audioLoader = new AudioLoader(); const instance = this - audioLoader.load( src, function( buffer ) { - audio.setBuffer( buffer ); - instance.play(audio) + audioLoader.load(this.src!, function( buffer ) { + console.log('loaded audio from memory') + instance.audio?.setBuffer( buffer ); + instance.play() }); }, - loadAudioFromStream(audio:ConcreteAudio, src:string) { - this.streamMediaElement = new Audio(src); - this.streamMediaElement.loop = true; - this.streamMediaElement.preload = 'metadata'; - this.streamMediaElement.crossOrigin = 'anonymous'; + loadAudioFromStream() { + this.streamedAudio = new Audio(this.src); + this.streamedAudio.loop = true; + this.streamedAudio.preload = 'metadata'; + this.streamedAudio.crossOrigin = 'anonymous'; const instance = this - this.streamMediaElement.addEventListener("loadedmetadata", function(_event) { - console.log('loaded the stream') - instance.play(audio) + this.streamedAudio.addEventListener("loadedmetadata", function(_event) { + console.log('loaded audio from stream') + instance.play() }); - audio.setMediaElementSource(this.streamMediaElement) + this.audio?.setMediaElementSource(this.streamedAudio) }, - play(audio:ConcreteAudio) { + play() { if (this.isStreamed) { - if (!this.streamMediaElement) { return } - this.streamMediaElement.play() + this.streamedAudio?.play() } else { - audio.play() + this.audio?.play() } }, - stop(audio:ConcreteAudio) { + stop() { if (this.isStreamed) { - if (!this.streamMediaElement) { return } - this.streamMediaElement.pause() - this.streamMediaElement.currentTime = 0; + if (!this.streamedAudio) { return } + this.streamedAudio.pause() + this.streamedAudio.currentTime = 0; } else { - audio.stop() + this.audio?.stop() } } }, diff --git a/src/audio/AudioListener.ts b/src/audio/AudioListener.ts index 1da10b8..2e9e64e 100644 --- a/src/audio/AudioListener.ts +++ b/src/audio/AudioListener.ts @@ -1,12 +1,11 @@ import { defineComponent, ComponentPublicInstance, InjectionKey, inject } from 'vue' import { AudioListener } from 'three' import Object3D from '../core/Object3D' -import { RendererInjectionKey } from './../core/Renderer' //TODO: currently the AudioListener is inheriting Object3D so it must be a // child of Scene. However the AudioListener should actually be possible to be // a child of Camera... Then again Camera is said to extend Object3D in the -// future... +// future... so might be better to refactor Camera first? export interface AudioListenerSetupInterface { audioListener?: AudioListener @@ -21,12 +20,12 @@ export default defineComponent({ created() { this.audioListener = new AudioListener() this.initObject3D(this.audioListener) - const renderer = inject(RendererInjectionKey) - if (!renderer) { + + if (!this.renderer) { console.error('Renderer not found') return } - renderer.audioListener = this.audioListener + this.renderer.audioListener = this.audioListener }, __hmrId: 'AudioListener', }) diff --git a/src/audio/PositionalAudio.ts b/src/audio/PositionalAudio.ts index 3e274f6..c6aae53 100644 --- a/src/audio/PositionalAudio.ts +++ b/src/audio/PositionalAudio.ts @@ -1,6 +1,5 @@ import { defineComponent, inject } from 'vue' import { PositionalAudio } from 'three' -import { RendererInjectionKey } from './../core/Renderer' import Audio from './Audio' import { bindProp } from '../tools' @@ -12,26 +11,25 @@ export default defineComponent({ rolloffFactor: { type: Number, default: 1.0 } }, created() { - const renderer = inject(RendererInjectionKey) - if (!renderer) { + if (!this.renderer) { console.error('Renderer not found') return } - if (!renderer.audioListener) { + if (!this.renderer.audioListener) { console.error("No AudioListener component found in the Renderer's child components tree!") return } - const positionalAudio = new PositionalAudio(renderer.audioListener) + const positionalAudio = new PositionalAudio(this.renderer.audioListener) this.initAudio(positionalAudio) - this.bindProps(positionalAudio) + this.bindProps() }, methods: { bindProps(audio: PositionalAudio) { ['refDistance', 'rolloffFactor'].forEach(p => { - bindProp(this.$props, p, audio) + bindProp(this.$props, p, this.audio) }) }, }, diff --git a/src/audio/StaticAudio.ts b/src/audio/StaticAudio.ts index e6d3ab2..d390717 100644 --- a/src/audio/StaticAudio.ts +++ b/src/audio/StaticAudio.ts @@ -1,25 +1,23 @@ import { defineComponent, inject } from 'vue' import { Audio as StaticAudio } from 'three' -import { RendererInjectionKey } from './../core/Renderer' import Audio from './Audio' export default defineComponent({ extends: Audio, name: 'StaticAudio', created() { - const renderer = inject(RendererInjectionKey) - if (!renderer) { + if (!this.renderer) { console.error('Renderer not found') return } - if (!renderer.audioListener) { + if (!this.renderer.audioListener) { console.error("No AudioListener component found in the Renderer's child components tree!") return } - const staticAudio = new StaticAudio(renderer.audioListener) + const staticAudio = new StaticAudio(this.renderer.audioListener) this.initAudio( staticAudio ) }, __hmrId: 'StaticAudio',