cgc*_*era 6 javascript audio html5 media-player html5-video
我想知道是否有一种方法可以用JavaScript平移视频的音频。
用与您调整音量相同的方法,我需要从左到右或从右到左平移立体声音频。
此功能对于多语言事件很有用,您可以使用立体声以两种语言制作视频,例如,向左平移英语音频,向右平移德语翻译。然后,播放器可以根据用户的选择将立体声轨道转换成单声道静音的一种语言。
我已经使用SoundTransform类http://help.adobe.com/zh_CN/FlashPlatform/reference/actionscript/3/flash/media/SoundTransform.html#pan在Flash中实现了此功能。
我猜SoundTransform html等效于AudioContext http://www.w3.org/TR/webaudio/#AudioContext-section。
我可以访问正在播放的视频的音频上下文吗?
更新:经过深入研究,我找到了解决方案。这是一些我用来开发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);
}
Run Code Online (Sandbox Code Playgroud)
那只对我有效。如果我尝试在iPad / Safari上执行此脚本,则会听到令人讨厌的声音,这几乎使我耳目一新。我等到Safari实现整个音频API。
由于目前还没有一个公认的答案,我仍然想帮助你。首先,上面答案中的规划器节点不太有用,因为它根据(另一个)方向上的 3 维位置、方向和速度来计算体积和平移。正如 Mantiur 已经说过的,您可以使用 来channelSplitter获得所需的结果。你可以这样设置:
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);
Run Code Online (Sandbox Code Playgroud)
您现在可以将左节点或右节点连接到context.destination,具体取决于用户需要这两个节点中的哪一个。请记住,只有 Chrome 和 Firefox 支持网络音频 API。
您的代码看起来不错,但将左侧和右侧的增益设置为 0 或 1 而不是断开连接并连接它们要好得多。对于当前问题,您将遇到一只耳朵的问题,但是您最好不要使用合并,而只是将音频直接推送到目的地(或通过额外的增益节点来设置最终音量。另请注意,您的代码可能会在 chrome 上可以工作,但是在我使用的版本上这不起作用,因为context.createGain()和中存在命名问题context.createGainNode()。官方文档使用.createGain,所以我们最好坚持这一点并创建一个后备:
context.createGain = context.createGain||context.createGainNode;
Run Code Online (Sandbox Code Playgroud)
这可能会解决 iOS 设备中的问题,因为我们应该能够在 iOS 设备上使用它。尽管如此,MDN 并不确定safari 上的兼容性。遗憾的是,由于网络音频 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;
}
Run Code Online (Sandbox Code Playgroud)
哦,顺便说一句,var function = funcName(){}这不是有效的 javascript(你是否使用了一些改变此行为的 API)?