mirror of
https://github.com/troisjs/trois.git
synced 2024-11-24 12:22:03 +08:00
refactor using audio instance on Audio component + no need to inject render
This commit is contained in:
parent
62b0db0cd5
commit
c75964d599
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -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',
|
||||||
})
|
})
|
||||||
|
@ -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)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -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',
|
||||||
|
Loading…
Reference in New Issue
Block a user