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

写在前面:

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

实现效果

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

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

在这里插入图片描述

关键技术

在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/webaudiohttps://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. 完整实例效果

在这里插入图片描述

扩展封装

为了能在项目上提高开发效率,我将其封装发布至Npm上了,在我们Web前端常用的开发框架(如:Vue.js,React.js,Angular.js等)中,使用Npm命令直接下载安装即可:

Npm安装命令:npm i @muguilin/web-audio-track

Yarn安装命令:yarn add @muguilin/web-audio-track

Npm地址 :https://www.npmjs.com/package/@muguilin/web-audio-track
GitHub地址:https://github.com/MuGuiLin
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值