1
0
mirror of https://github.com/troisjs/trois.git synced 2024-11-24 04:12:02 +08:00

refactor using audio instance on Audio component + no need to inject render

This commit is contained in:
dataexcess 2022-11-29 12:30:42 +01:00
parent 62b0db0cd5
commit c75964d599
4 changed files with 50 additions and 53 deletions

View File

@ -3,12 +3,13 @@ import { defineComponent } from 'vue'
import Object3D from '../core/Object3D' import Object3D from '../core/Object3D'
import { bindProp } from '../tools' import { bindProp } from '../tools'
export interface AudioSetupInterface {
streamMediaElement?: HTMLAudioElement
}
type ConcreteAudio = StaticAudio | PositionalAudio type ConcreteAudio = StaticAudio | PositionalAudio
export interface AudioSetupInterface {
audio?: ConcreteAudio
streamedAudio?: HTMLAudioElement
}
export default defineComponent({ export default defineComponent({
extends: Object3D, extends: Object3D,
name: 'Audio', name: 'Audio',
@ -18,64 +19,65 @@ export default defineComponent({
isStreamed: { type: Boolean, default: true } isStreamed: { type: Boolean, default: true }
}, },
setup (): AudioSetupInterface { setup (): AudioSetupInterface {
let streamMediaElement = new Audio(); let streamedAudio = new Audio();
return { streamMediaElement } return { streamedAudio }
}, },
methods: { methods: {
initAudio(audio: ConcreteAudio) { initAudio(audio: ConcreteAudio) {
this.initObject3D(audio) this.audio = audio
this.bindProps(audio) this.initObject3D(this.audio)
this.loadAudioAndPlay(audio) this.bindProps()
this.loadAudioAndPlay()
}, },
bindProps(audio: ConcreteAudio) { bindProps() {
['volume', 'isStreamed'].forEach(p => { ['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.src) return undefined
if (this.isStreamed) { if (this.isStreamed) {
this.loadAudioFromStream(audio, this.src) this.loadAudioFromStream()
} else { } else {
this.loadAudioFromMemory(audio, this.src) this.loadAudioFromMemory()
} }
}, },
loadAudioFromMemory(audio:ConcreteAudio, src:string) { loadAudioFromMemory() {
const audioLoader = new AudioLoader(); const audioLoader = new AudioLoader();
const instance = this const instance = this
audioLoader.load( src, function( buffer ) { audioLoader.load(this.src!, function( buffer ) {
audio.setBuffer( buffer ); console.log('loaded audio from memory')
instance.play(audio) instance.audio?.setBuffer( buffer );
instance.play()
}); });
}, },
loadAudioFromStream(audio:ConcreteAudio, src:string) { loadAudioFromStream() {
this.streamMediaElement = new Audio(src); this.streamedAudio = new Audio(this.src);
this.streamMediaElement.loop = true; this.streamedAudio.loop = true;
this.streamMediaElement.preload = 'metadata'; this.streamedAudio.preload = 'metadata';
this.streamMediaElement.crossOrigin = 'anonymous'; this.streamedAudio.crossOrigin = 'anonymous';
const instance = this const instance = this
this.streamMediaElement.addEventListener("loadedmetadata", function(_event) { this.streamedAudio.addEventListener("loadedmetadata", function(_event) {
console.log('loaded the stream') console.log('loaded audio from stream')
instance.play(audio) instance.play()
}); });
audio.setMediaElementSource(this.streamMediaElement) this.audio?.setMediaElementSource(this.streamedAudio)
}, },
play(audio:ConcreteAudio) { play() {
if (this.isStreamed) { if (this.isStreamed) {
if (!this.streamMediaElement) { return } this.streamedAudio?.play()
this.streamMediaElement.play()
} else { } else {
audio.play() this.audio?.play()
} }
}, },
stop(audio:ConcreteAudio) { stop() {
if (this.isStreamed) { if (this.isStreamed) {
if (!this.streamMediaElement) { return } if (!this.streamedAudio) { return }
this.streamMediaElement.pause() this.streamedAudio.pause()
this.streamMediaElement.currentTime = 0; this.streamedAudio.currentTime = 0;
} else { } else {
audio.stop() this.audio?.stop()
} }
} }
}, },

View File

@ -1,12 +1,11 @@
import { defineComponent, ComponentPublicInstance, InjectionKey, inject } from 'vue' import { defineComponent, ComponentPublicInstance, InjectionKey, inject } from 'vue'
import { AudioListener } from 'three' import { AudioListener } from 'three'
import Object3D from '../core/Object3D' import Object3D from '../core/Object3D'
import { RendererInjectionKey } from './../core/Renderer'
//TODO: currently the AudioListener is inheriting Object3D so it must be a //TODO: currently the AudioListener is inheriting Object3D so it must be a
// child of Scene. However the AudioListener should actually be possible to be // 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 // 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 { export interface AudioListenerSetupInterface {
audioListener?: AudioListener audioListener?: AudioListener
@ -21,12 +20,12 @@ export default defineComponent({
created() { created() {
this.audioListener = new AudioListener() this.audioListener = new AudioListener()
this.initObject3D(this.audioListener) this.initObject3D(this.audioListener)
const renderer = inject(RendererInjectionKey)
if (!renderer) { if (!this.renderer) {
console.error('Renderer not found') console.error('Renderer not found')
return return
} }
renderer.audioListener = this.audioListener this.renderer.audioListener = this.audioListener
}, },
__hmrId: 'AudioListener', __hmrId: 'AudioListener',
}) })

View File

@ -1,6 +1,5 @@
import { defineComponent, inject } from 'vue' import { defineComponent, inject } from 'vue'
import { PositionalAudio } from 'three' import { PositionalAudio } from 'three'
import { RendererInjectionKey } from './../core/Renderer'
import Audio from './Audio' import Audio from './Audio'
import { bindProp } from '../tools' import { bindProp } from '../tools'
@ -12,26 +11,25 @@ export default defineComponent({
rolloffFactor: { type: Number, default: 1.0 } rolloffFactor: { type: Number, default: 1.0 }
}, },
created() { created() {
const renderer = inject(RendererInjectionKey)
if (!renderer) { if (!this.renderer) {
console.error('Renderer not found') console.error('Renderer not found')
return return
} }
if (!renderer.audioListener) { if (!this.renderer.audioListener) {
console.error("No AudioListener component found in the Renderer's child components tree!") console.error("No AudioListener component found in the Renderer's child components tree!")
return return
} }
const positionalAudio = new PositionalAudio(renderer.audioListener) const positionalAudio = new PositionalAudio(this.renderer.audioListener)
this.initAudio(positionalAudio) this.initAudio(positionalAudio)
this.bindProps(positionalAudio) this.bindProps()
}, },
methods: { methods: {
bindProps(audio: PositionalAudio) { bindProps(audio: PositionalAudio) {
['refDistance', 'rolloffFactor'].forEach(p => { ['refDistance', 'rolloffFactor'].forEach(p => {
bindProp(this.$props, p, audio) bindProp(this.$props, p, this.audio)
}) })
}, },
}, },

View File

@ -1,25 +1,23 @@
import { defineComponent, inject } from 'vue' import { defineComponent, inject } from 'vue'
import { Audio as StaticAudio } from 'three' import { Audio as StaticAudio } from 'three'
import { RendererInjectionKey } from './../core/Renderer'
import Audio from './Audio' import Audio from './Audio'
export default defineComponent({ export default defineComponent({
extends: Audio, extends: Audio,
name: 'StaticAudio', name: 'StaticAudio',
created() { created() {
const renderer = inject(RendererInjectionKey)
if (!renderer) { if (!this.renderer) {
console.error('Renderer not found') console.error('Renderer not found')
return return
} }
if (!renderer.audioListener) { if (!this.renderer.audioListener) {
console.error("No AudioListener component found in the Renderer's child components tree!") console.error("No AudioListener component found in the Renderer's child components tree!")
return return
} }
const staticAudio = new StaticAudio(renderer.audioListener) const staticAudio = new StaticAudio(this.renderer.audioListener)
this.initAudio( staticAudio ) this.initAudio( staticAudio )
}, },
__hmrId: 'StaticAudio', __hmrId: 'StaticAudio',