Javascript 音频上下文平移播放媒体的音频

Javascript 音频上下文平移播放媒体的音频,javascript,html,audio,html5-video,media-player,Javascript,Html,Audio,Html5 Video,Media Player,我想知道是否有办法用JavaScript平移视频的音频 和你调节音量的方法一样,我需要从左向右或从右向左平移立体声音频 此功能对于多语言活动非常有用,您可以使用立体声制作两种语言的视频,例如,向左平移英语音频,向右平移德语翻译。然后,播放器可以根据用户的选择将立体声音轨转换为单声道静音语言之一 我已经用SoundTransform类在flash中实现了这个特性 我猜SoundTransformHTML等价于AudioContext 我可以访问正在播放的视频的音频上下文吗 更新:经过深入研究,我找

我想知道是否有办法用JavaScript平移视频的音频

和你调节音量的方法一样,我需要从左向右或从右向左平移立体声音频

此功能对于多语言活动非常有用,您可以使用立体声制作两种语言的视频,例如,向左平移英语音频,向右平移德语翻译。然后,播放器可以根据用户的选择将立体声音轨转换为单声道静音语言之一

我已经用SoundTransform类在flash中实现了这个特性

我猜SoundTransformHTML等价于AudioContext

我可以访问正在播放的视频的音频上下文吗

更新:经过深入研究,我找到了解决方案。 下面是我用来开发videojs插件videjs stereopanner的一些javascript代码:

//Init AudioContext
var context = new AudioContext();
var gainL = context.createGainNode();
var gainR = context.createGainNode();
gainL.gain.value = 1;
gainR.gain.value = 1;
var merger = this.context.createChannelMerger(2);
var splitter = this.context.createChannelSplitter(2);

//Connect to source
var source = context.createMediaElementSource(node);
//Connect the source to the splitter
source.connect(splitter, 0, 0);
//Connect splitter' outputs to each Gain Nodes
splitter.connect(gainL, 0);
splitter.connect(gainR, 1);

//Connect Left and Right Nodes to the Merger Node inputs
//Assuming stereo as initial status
gainL.connect(merger, 0, 0);
gainR.connect(merger, 0, 1);

//Connect Merger output to context destination
merger.connect(context.destination, 0, 0);

//Disconnect left channel and connect right to both stereo outputs
var function = panToRight(){
    gainL.disconnect();
    gainR.connect(merger, 0, 1);
};

//Disconnect right channel and connect left to both stereo outputs
var function = panToLeft(){
    gainR.disconnect();
    gainL.connect(merger,0,0);
}

//Restore stereo
var function = panToStereo(){
    gainL.connect(merger, 0, 0);
    gainR.connect(merger, 0, 1);
}

这只适用于我的Chrome浏览器。如果我试图在iPad/Safari上执行这个脚本,我会听到一种恼人的声音,几乎让我耳聋。我一直在等待Safari实现整个音频API。

由于还没有一个公认的答案,我仍然愿意帮助您。首先,上面答案中的planner节点不是很有用,因为它根据三维位置、方向和(另一个)方向的速度来计算体积和平移。如Mantiur所述,您可以使用
通道拆分器
获得所需的结果。您可以这样设置:

var element = document.getElementById('player');
Var source = context.createMediaElementSource(element);
var splitter = context.createSplitter(2);
source.connect(splitter);
var left = context.createGain();
var right = context.createGain();
splitter.connect(left);
splitter.connect(right);
现在,您可以将左侧或右侧节点连接到
context.destination
,具体取决于用户需要这两个节点中的哪一个。 请记住,只有chrome和Firefox支持web音频api

更新的答案:(对更新的问题) 您的代码看起来不错,但是只将左右的增益设置为0或1要好得多,而不是断开连接。对于当前版本,您将遇到单耳问题,但是您最好不要使用合并,而是直接将音频推送到目的地(或者通过一个额外的增益节点来设置最终卷。还请注意,您的代码可能在chrome上工作,但在我使用的版本上,这不起作用,因为
context.createGain()
context.createGainNode()
中存在命名问题。使用
.createGain
,因此我们最好坚持这一点,并创建一个后备方案:

context.createGain = context.createGain||context.createGainNode;
可能会解决iOS设备中的问题,正如我们所说的那样。尽管MDN是关于safari上的兼容性。遗憾的是,由于web音频API的行为,没有解决方法。让我们假设源只有一个输出,但其中包含两个通道。没有其他方法来分割这些通道(一开始我想的是
source.connect(gainL,0,0);
source.connect(gainR,1,0);
,但这不起作用,因为这些数字与输入/输出的数量有关,而不是与这些行中的通道有关)

因此,我建议将代码更改为以下内容:

//Init AudioContext
window.audioContext = window.audioContext||window.webkitAudioContext; //fallback for older chrome browsers
var context = new AudioContext();
context.createGain = context.createGain||context.createGainNode; //fallback for gain naming
var gainL = context.createGain();
var gainR = context.createGain();

var splitter = this.context.createChannelSplitter(2);

//Connect to source
var source = context.createMediaElementSource(audioElement);
//Connect the source to the splitter
source.connect(splitter, 0, 0);
//Connect splitter' outputs to each Gain Nodes
splitter.connect(gainL, 0);
splitter.connect(gainR, 1);

//Connect Left and Right Nodes to the output
//Assuming stereo as initial status
gainL.connect(context.destination, 0);
gainR.connect(context.destination, 0);


//Mute left channel and set the right gain to normal
function panToRight(){
    gainL.gain.value = 0;
    gainR.gain.value = 1;
}

//Mute right channel and set the left gain to normal
function panToLeft(){
    gainL.gain.value = 1;
    gainR.gain.value = 0;
}

//Restore stereo
function panToStereo(){
    gainL.gain.value = 1;
    gainR.gain.value = 1;
}

哦,顺便说一句,
var function=funcName(){}
不是有效的javascript(您是否正在使用一些API来更改此行为)?

我在我的一个页面上添加了环境音频,我正试图为游戏制作环境音频。下面是我的平移实验,我稍后将在整个游戏的某些音效上使用。我花了很长时间才意识到有一个很好的
createStereoPanner
东西,它大大简化了整个过程。我用v测试了它ideo和它同样有效

var ambientAudio=新音频('./ambientVideo.mp4');
document.addEventListener('keydown',环境音频控制)
环境音频控制功能(e){
如果(e.keyCode==37)panToLeft()
如果(e.keyCode==39)panToRight()
如果(e.keyCode==40)panToStereo()
}
const ambientContext=新的AudioContext();
const source=ambientContext.createMediaElementSource(ambientAudio);
const ambientPan=ambientContext.createStereoPanner()
函数panToLeft(){ambientPan.pan.value=-1}
函数panToRight(){ambientPan.pan.value=1}
函数panToStereo(){ambientPan.pan.value=0}
source.connect(ambientPan)
ambientPan.connect(ambientContext.destination)

环境音频播放
谢谢@MarijnS95,这几乎就是我想要的。我已经更新了我的问题,添加了一些关于我最终遇到的解决方案的细节。@cgcladera我更新了问题,包括iOS问题的“答案”,尽管我不确定。哇!再次感谢@MarijnS95!我将从底部开始:是的,我从这是一个API,因此对格式不正确表示歉意。其次,我连接和断开频道是有原因的。当我向右或向左平移时,我希望能够在两个扬声器中收听音频。这是因为我将此功能用于多语言直播活动,我们允许制作人同时使用向左和向右播放两种语言。有因此,我想让用户感觉他们可以切换语言,而不是左右平移音频。就在我发布评论后,我尝试了你的代码,看到了你的意思,真是太遗憾了!!抱歉:(顺便说一句,我在Mac/iOS Safari上仍然有问题。代码不起作用。虽然Safari不会触发异常或错误,但它的行为并不符合预期。@cgcladera我正在考虑使用它,但您当然在使用视频。您是否有可能将视频从音频中分离出来?(但要同步声音还是相当困难的).所以Mantriur在这一点上是正确的,实施还没有完成,而且很难达到预期的结果。我几个小时后就要考试了,但之后我可能会想到一些东西。我本来没有看到你的答案,但我在接下来的几天里决定做一些可疑的类似事情