Web前端JS如何控制 Video/Audio 视音频声道(左右声道|多声道)、视音频轨道、音频流数据

写在前面:

接上篇博文:Web前端JS如何获取 Video/Audio 视音频声道(左右声道|多声道)、视音频轨道、音频流数据 讲解了如何根据视频链接地址,实现在播放时实时的显示该视频的音频轨道情况,并实时的将各音频轨道数据以可视化(响度跳表)的形式展现出来。
本篇博文主要讲解:Web前端JS如何控制 Video/Audio 视音频声道(左右声道|多声道)、视音频轨道、音频流数据。如:实现各个 视音频声道(左右声道|多声道)的 独立音量大小、静音的控制。

实现效果

需要注意的是,由于我们日常中活中大部份硬件设备,如:电视机、笔记本电脑、耳机等,只有两个扬声器(简音来说,就是只有左L 和 右R 两个喇叭,就只能听到两个音频轨道的声音)如果要测试多声道的话,至少满足以下两个条件:

  • 1、播放的视音频文件必须是有多音轨的(就是两个以上的声道)
  • 2、播放的硬件设备必须是有多个扬声器(就是两个以上的喇叭)

Web前端JS如何控制 Video/Audio 视音频声道(左右声道|多声道)、视音频轨道、音频流数据_第1张图片

关键技术

在Web浏览器中,想要获取多媒体文件的相关数据信息,需要借助对应的API来完成,比如获取视音文件的音频信息,就需要用到Web Audio API,通过该API我们可以轻松做到播放声音、获取声音数据,修改声音数据、甚至还可以制造声音。

Web Audio API 之 GainNode接口

GainNode 接口表示音量的变化。它是一个 AudioNode 音频处理模块,在输出前使用给定增益应用到输入。一个 GainNode 始终只有一个输入和一个输出,两者拥有同样数量的声道。
增益是一个无单位的值,会对所有输入声道的音频进行相应的增加(相乘)。如果进行了修改,则会立即应用新增益,从而在结果音频中产生奇怪的“咔嗒”声。为了防止这种情况发生,请不要直接更改值,而应在 AudioParam 接口上使用指数插值方法。

GainNode接口:
https://developer.mozilla.org/zh-CN/docs/Web/API/GainNode

在这里插入图片描述

了解更多API:
https://www.w3.org/TR/webaudio、https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Audio_API

实例代码

1. HTML标签

由于video和audio都有音频,所以我们可以video或者audio来获取输入源,除此以外,我们还可以通过 navigator.getUserMedia API 或 Ajax请求的方式来获取输入源。

<video loop controls>
	<source src="./media/xxx.mp4" type="video/mp4" />
video>
<audio loop controls>
	<source src="./media/xxx.mp3" type="audio/mp3" />
audio>
2.JavaScript代码

在创建AudioContext 上下文环境对象时, 由于浏览器安全策略要求音频上下文必须在用户事件(单击、键盘按键等)中启用。这意味着,如果您尝试在没有用户事件的情况下自动播放音乐,所以在loadedmetadata元数据已加载时再执行!!

// 创建一个 AudioContext 环境
const ac = new (window.AudioContext || window.webkitAudioContext)();

// 从 video 或 audio 标签元素中拿到输入源
const audio = document.querySelector("video");
// const audio = document.querySelector("audio");

// 创建并获取输入源
const audioSource = ac.createMediaElementSource(audio);
// 音频通道数 默认值是 2,最高能取 32
const channelCount = 2 || audioSource.channelCount;
// 创建音频处理器
const processor = ac.createScriptProcessor(2048, channelCount, channelCount);
// 链接音频处理器
audioSource.connect(processor).connect(ac.destination);

// 创建通道控制器
const volumeNodeL = new GainNode(ac, { gain: 1 });
const volumeNodeR = new GainNode(ac, { gain: 1 });

// 创建通道分配器
const splitterNode = new ChannelSplitterNode(ac, {
  numberOfOutputs: channelCount,
});

splitterNode.connect(volumeNodeL, 0); 
splitterNode.connect(volumeNodeR, 1); 

// 控制链接到输入源
audioSource.connect(splitterNode);

// 创建通道合并器
const mergerNode = new ChannelMergerNode(ac, {
  numberOfInputs: channelCount,
});

volumeNodeL.connect(mergerNode, 0, 0); 
volumeNodeR.connect(mergerNode, 0, 1); 

// 通道链接到扬声器
mergerNode.connect(ac.destination);

// 监听音频处理器每次处理的样本帧
processor.onaudioprocess = (evt) => {
  //获取声轨1输入的缓冲区数据
  let input =evt.inputBuffer.getChannelData(0);
	
  //获取声轨1输出的缓冲区数据
  let output = evt.outputBuffer.getChannelData(0);
};

// 静音左L声道
LBTN.onclick = function () {
  volumeNodeL.gain.value = Number(!volumeNodeL.gain.value);
};

// 左L声道音量大小控制
VL.oninput = function () {
  // volumeNodeL.gain.value = this.value;
  volumeNodeL.gain.setValueAtTime(this.value, ac.currentTime);
  VLV.innerText = '音量:' + this.value;
}; 
3. 完整实例代码

可以通过添加本地的视频 或 音频文件,来测试对应的声道,并实时的渲染到响度跳表中,需要注意的是,音频跳表从-60开始的原因主要是,当输出音量接近满载时,THD(总谐波失真)的表现会比较差,此时产生的谐波会盖掉原本存在的背景噪音,影响到测试成绩。因此,采用-60dB的测试信号。
音频跳表值通常在-60dB到+3dB之间。在音频设备测试中,跳表值反映了设备的频率响应和增益。不同的音频设备可能会有不同的跳表值范围,根据测试标准和设备要求而定。

>>> 完整实例代码,请点击前往GitHub仓库自行提取!!
4. 完整实例效果

Web前端JS如何控制 Video/Audio 视音频声道(左右声道|多声道)、视音频轨道、音频流数据_第2张图片

扩展封装

Npm:https://www.npmjs.com/package/mu-tooljs
GitHub:https://github.com/MuGuiLin/WebMediaAPI

你可能感兴趣的:(js音视频处理,js声道音量控制,Web,Audio,API,js获取视音频轨道,Web前端,Js音频可视化)