简体   繁体   English

WebAudio panner 无法与 WebRTC 音频 stream 一起正常工作

[英]WebAudio panner not working properly with WebRTC audio stream

I have an issue where my audio panner isn't properly panning with the given values.我有一个问题,我的音频平移器没有正确平移给定值。

Currently, if I set positionX.value to 1000, the audio plays as it was in the middle and not panned at all to the right channel.目前,如果我将 positionX.value 设置为 1000,则音频会在中间播放,并且根本不会平移到右声道。

Now if I set positionX.value to 0.5 or 0.9 or 1, the audio plays on the right channel, (even though not entirely, as I can still hear a bit on the left, more than usual).现在,如果我将 positionX.value 设置为 0.5 或 0.9 或 1,音频会在右声道播放(尽管不完全,因为我仍然可以在左边听到一点,比平时更多)。

I don't understand why it only works from -1 to 1, any number higher than that the audio goes back to the center.我不明白为什么它只能从 -1 到 1 工作,任何高于音频返回中心的数字。 Any idea why?知道为什么吗? And I'm sure it should work with higher numbers because I have tested it before in a different situation and nothing says it shouldn't on the documentation.而且我确信它应该适用于更高的数字,因为我之前已经在不同的情况下测试过它,并且没有说它不应该出现在文档中。

peerConnection.onaddstream = (event) => {
    var panner = this.aContext.createPanner();
    panner.panningModel = 'HRTF';
    panner.distanceModel = 'inverse';
    panner.refDistance = 1;
    panner.maxDistance = 10000;
    panner.rolloffFactor = 1;
    panner.coneInnerAngle = 360;
    panner.coneOuterAngle = 0;
    panner.coneOuterGain = 0;
    
    // here is how Im setting the position, using -1 to 1 works, nothing greater tho
    panner.positionX.value = 10000;

    var source = this.aContext.createMediaStreamSource(event.stream);

    source.connect(panner);
    panner.connect(this.aContext.destination);

    const recvAudio = new Audio();
    recvAudio.srcObject = source.mediaStream;
    recvAudio.autoplay = true;
}

You need to set where ths listner is.您需要设置监听器的位置。 Where it is determines the panning of your source node.它在哪里决定了源节点的平移。

By default the listners position is (0,0,0) which is why you can here it when you set the source nodes with low values.默认情况下,侦听器 position 是 (0,0,0),这就是为什么当您将源节点设置为低值时可以在此处使用它。

You can set where the listner is with:您可以设置监听器所在的位置:

var const listener = this.aContext.listener;
listener.setPosition(x,y,z);

Your recvAudio Audio element is diffusing the raw MediaStream directly, without the PannerNode affecting it.您的recvAudio Audio 元素直接扩散原始 MediaStream,而 PannerNode 不会影响它。

    var source = this.aContext.createMediaStreamSource(event.stream);
///...
    recvAudio.srcObject = source.mediaStream;

In this snippet, source.mediaStream is exactly the same object as event.stream .在此代码段中, source.mediaStream与 event.stream 完全相同event.stream

 document.querySelector("button").onclick = (evt) => { const context = new AudioContext(); // let's create an audio MediaStream from the AudioContext // in StackSnippets we can't use gUM... const event_stream = context.createMediaStreamDestination().stream; const source = context.createMediaStreamSource( event_stream ); console.log( "Same Object:", source.mediaStream === event_stream ); context.close(); }
 <button>test</button>

So when you get outside of the reference distance [-1 ~ 1], your AudioContext's output sound will get lower than the one of this Audio element, and you will have the impression that the PannerNode doesn't work anymore, because the Audio element's output covers it.因此,当您超出参考距离 [-1 ~ 1] 时,您的 AudioContext 的 output 声音将低于此 Audio 元素之一,并且您会觉得 PannerNode 不再工作,因为 Audio 元素的output 覆盖它。

To fix it, the best is probably to not use an Audio element at all here, you don't really need it since you can let the AudioContext output the sound itself.要修复它,最好的方法可能是在这里根本不使用 Audio 元素,您并不需要它,因为您可以让 AudioContext output 本身发出声音。

But if you really need to use an Audio element, instead of connecting the AudioPanner node to the context's destination, connect it to a MediaStreamDestinationNode and pass this latter as the srcObject of your Audio element:但是,如果您确实需要使用 Audio 元素,而不是将 AudioPanner 节点连接到上下文的目的地,而是将其连接到 MediaStreamDestinationNode 并将后者作为您的 Audio 元素的srcObject传递:

//...
    panner.positionX.value = 10000;

    const source = this.aContext.createMediaStreamSource(event.stream);
    const destination = this.aContext.createMediaStreamDestination();
    source.connect(panner);
    panner.connect(destination);

    const recvAudio = new Audio();
    recvAudio.srcObject = destination.stream;
    recvAudio.autoplay = true;
//...

https://jsfiddle.net/do9xq681/ https://jsfiddle.net/do9xq681/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM