steep-balloon-41261
10/25/2022, 11:14 PMmagnificent-art-43333
10/25/2022, 11:16 PMearly-piano-21116
10/26/2022, 4:04 AMmagnificent-art-43333
10/26/2022, 4:05 AMmagnificent-art-43333
10/26/2022, 4:05 AMearly-piano-21116
10/26/2022, 4:05 AMearly-piano-21116
10/26/2022, 4:06 AMmagnificent-art-43333
10/26/2022, 4:06 AMpolite-kilobyte-67570
10/26/2022, 10:04 AMexpWebaudioMix: true in the room options in the latest js client version, which will pipe all audio through web audio. You can then add audio nodes on a track basis by calling remoteAudioTrack.setWebAudioPlugins([myPannerNode]).
These options are still marked as experimental and aren’t battle tested yet. would be great to hear your feedback whether this makes your life easier already.
In terms of spatial support, we aim to make this even easier for people in the future, so anything you are willing to share about your specific usecase would help us make decisions also with your usecase in mind 🙂early-piano-21116
10/26/2022, 11:49 PMasync init() {
// code inspired by decentraland kernal repo
// they also use livekit and to get proper positional audio it seems a loopback
// stream is required, at least in chrome
const listener = this.engine.audio.listener
this.destination = listener.context.createMediaStreamDestination()
this.destinationStream = window.navigator.userAgent.includes('Chrome')
? await startLoopback(this.destination.stream)
: this.destination.stream
this.audio = new Audio()
this.audio.srcObject = this.destinationStream
await this.driver.gesture
this.audio.play()
}
After doing that then the following way of connecting tracks works:
const stream = track.mediaStream
this.source = listener.context.createMediaStreamSource(stream)
this.source.connect(this.isSpatial ? this.panner : this.gain)polite-kilobyte-67570
10/27/2022, 7:29 PMearly-piano-21116
10/27/2022, 10:40 PMpolite-kilobyte-67570
10/28/2022, 8:19 AMearly-piano-21116
10/28/2022, 11:07 AMearly-piano-21116
10/28/2022, 11:45 AMexpWebAudioMix: true as a Room option, I removed our loopback.
And for each RemoteAudioTrack we basically do this:
track.setAudioContext(listener.context)
track.attach()
const node = this.isSpatial ? this.panner : this.gain
track.setWebAudioPlugins([node])
To disconnect we call:
track.disconnectWebAudio()
track.detach()
Does this seem about right to you?
I couldn't find anything in your source code that would let me provide my own context so i'm feeling a bit iffy about using track.setAudioContext as I think it's a private apipolite-kilobyte-67570
10/28/2022, 11:59 AMdisconnectWebAudio yourself, this is handled within the detach function already.
the same is true for attach. but you’re raising a good point about not being able to set the audio context from outside via public APIs.
Two things that I’m thinking about:
1. would a custom audioContext be set once via room options (e.g. expWebAudioMix: { audioContext: myCustomContext} or is there the need to update the context programatically on demand via something like room.setAudioContext
2. could there be cases where individual tracks would need a different audioContext to the “main” one? If so, we could make that API publicearly-piano-21116
10/28/2022, 12:39 PMearly-piano-21116
10/28/2022, 12:39 PMearly-piano-21116
10/28/2022, 12:39 PMearly-piano-21116
10/28/2022, 12:42 PMearly-piano-21116
10/28/2022, 12:42 PMearly-piano-21116
10/28/2022, 12:43 PMenough-balloon-75992
11/02/2022, 2:09 PM