一、背景

在社交元宇宙、大逃杀等类型的游戏场景下,用户在通过简单语音交流外,结合场景也需要一些立体声效果来让用户感知游戏角色周围其他用户的存在及其对应的距离和方位,提高语音互动的趣味性。

为了满足上述需求 ZEGO Express Web SDK 从  v2.10.0(Native 为 v2.11.0)开始加入范围语音功能模块,为游戏提供语音服务。

当前范围语音功能模块主要包括如下功能:

  • 范围语音:房间内的收听者对音频的接收距离有范围限制,若发声者与自己的距离超过该范围,则无法听到声音。
  • 3D 音效:听者接收的声音根据发声者相对于听者的距离和方位模拟现实中声音的立体声效果。
  • 小队语音:玩家可以选择加入小队,并支持在房间内自由切换“全世界”模式和“仅小队”模式。

其中对于 Web 3D 音效这部分功能的实现,我们是基于浏览器提供的 Web Audio API 对音频进行处理。这里小编也通过使用 Web Audio API 做了一个简单的环绕音的 demo 页面。

demo 在线体验地址:https://keen_wang.gitee.io/demo/music3d,页面如下图,点击“开始播放”按钮开始播放音乐,再点击“开闭空间化”进行开启或关闭 3D 音效,打开 3D 音效后就可以听到空间环绕声效果。(在体验 3D 音效时需要使用左右声道分开的耳机或音响设备)

下文将介绍如何使用 Web Audio API 来做这个环绕音 demo。

二、Web Audio API 简介

Web Audio API 用于操作声音,很多时候用于替代 <audio> 标签来播放一段音频,除此之外,还有音频处理的功能,比如音量调节、音频混合、音频空间化等。

Web Audio API 使用户可以在音频上下文( AudioContext )中进行音频操作,具有模块化路由的特点。

下面是最简单的一个路由图,表示音频源通过效果处理后输出到音频目的地,图中的 inputs、Effects、Destination 三个模块分别对应为音频节点( AudioNode )的输入源节点、处理节点、输出节点。

下面我们将介绍 Web Audio API 的简单使用步骤:

1、创建 AudioContext 音频上下文实例

// 创建音频上下文
const AudioContext = window.AudioContext || window.webkitAudioContext;
const audioCtx = new AudioContext();

AudioContext 为音频处理提供一个上下文环境,相当于一个中央控制器,用于控制着音频路由图中的各个音频节点。

2、在音频上下文里创建输入源节点和处理节点。

// 创建输入结点,解码 audio 标签的音频源
const audioEl = document.querySelector('audio');
const sourceNode = audioCtx.createMediaElementSource(audioEl);
// 创建用于控制音频振幅的处理结点 GainNode
const gainNode = audioCtx.createGain(); 

3、将输入源节点连到处理节点。

输入源节点通过 connect 方法将音频数据传输给处理节点。

sourceNode.connect(gainNode);

4、将处理节点连接到选定的输出节点进行效果输出。

处理节点通过 connect 方法将处理完的音频数据传输给输出节点进行效果输出。

这里的输出节点 audioCtx.destination 为当前使用的扬声器。

gainNode.connect(audioCtx.destination);

5、修改处理节点的属性以修改输出效果。

// 设置静音处理
gainNode.gain.setValueAtTime(0, audioCtx.currentTime);

了解完 Web Audio API 的使用特点,接下来介绍如何进行音频空间化处理。

三、实现 3D 音效

音频空间化的实现主要是通过 PannerNode 和 AudioListener 结合使用来处理声音效果。这两个类的实例对象进行设置空间方位信息后动态处理音频源并输出到左右声道。

  • AudioListener 对象代表三维空间中的听者(用户),通过 AudioContext.listener 属性获取对应的实例对象;
  • PannerNode 对象指的是三维空间中的声音源,通过 new 的方式或者 AudioContext.createPanner() 创建得到。

下面将介绍如何设置 AudioListener 和 PannerNode 的属性来改变 3D 音效效果。

1、设置 AudioListener 

AudioListener 对象表示听者,这里可以定义听者在空间中的位置和他(她)们面向的方向,PannerNode 可以计算出声音相对于收听者位置的位置。

对于听者位置信息,AudioListener 提供了三个位置属性:positionX 、positionY 、positionZ ,它分别代表听者当前位置的 xyz 坐标,这里坐标系使用的是右手笛卡尔坐标系,x 轴和 z 轴在水平方向、y 轴在垂直方向。

// 为 listener 设置 position
const listener = audioCtx.listener;
listener.positionX = camera.position.x;
listener.positionY = camera.position.y;
listener.positionZ = camera.position.z;
(听者朝向向量的图示说明)

对于听者的朝向可通过 AudioListener 的forwardXforwardY 、forwardZ 这三个属性设置听者的正面朝向向量,默认值是 (0,0,-1) 。通过 AudioListener 的 upXupYupZ 这三个属性设置听者的头顶朝向方向向量,默认值是 (0,1,0) ,即垂直朝上的方向。通过这两个朝向向量的设置,即可确定听者左右耳的位置来生成立体声效果。

2、设置 PannerNode

PannerNode 是一个处理节点,提供了 3D 空间音频能力,PannerNode 通过相对于 AudioContext 的 AudioListener 的位置和朝向信息对声音进行空间化处理。

PannerNode 有以下几个常用属性:

  • panningModel:音频空间化算法模型,默认值是 “equalpower”,即等幂平移算法,建议设置更为只能的 “HRTF” 。
  • positionX/positionY/positionZ:声源位置坐标。
  • orientationX/orientationY/orientationZ:声源朝向向量。
  • coneInnerAngle:锥形角度,单位为度,默认是 360。
  • rolloffFactor:声音随距离的衰减速度,默认值为 1。
  • distanceModel:声音衰减算法模型,默认值是 “inverse”,即相反距离模型。

3、环绕音 Demo

了解了这些 Web Audio API,就可以开始实现一个音频空间化效果了。下面是一个播放环绕声歌曲的 demo 代码,模拟空间中一个音源在听者周围环绕。通过在播放过程中动态修改 PannerNode 的定位信息来生成环绕效果。

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Web Audio</title>
</head><body><audio loop autoplay crossorigin="anonymous"src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/858/outfoxing.mp3"></audio><button onclick="startPlay()">开始播放</button><button onclick="spatialize()">开闭空间化</button><span>音效状态:</span><span id="status">关闭</span><script>// 音源初始位置信息const audioPosition = [0, 0, 1]// 创建音频上下文const AudioContext = window.AudioContext || window.webkitAudioContext;const audioCtx = new AudioContext();// 设置 AudioListenerconst listener = audioCtx.listener;listener.positionX.value = 0;listener.positionY.value = 0;listener.positionZ.value = 0;listener.forwardX.value = 0;listener.forwardY.value = 0;listener.forwardZ.value = -1;// 创建输入结点,解码 audio 标签的音频源;创建处理结点,处理音频const audioEl = document.querySelector('audio');const sourceNode = audioCtx.createMediaElementSource(audioEl);// 创建和设置 PannerNodeconst pannerNode = new PannerNode(audioCtx, {panningModel: "HRTF",  // 音频空间化算法模型distanceModel: "linear",  // 远离时的音量衰减算法rolloffFactor: 1,  // 衰减速度coneInnerAngle: 360, // 声音 360 度扩散positionX: audioPosition[0],positionY: audioPosition[1],positionZ: audioPosition[2],maxDistance: 10000,});// 将输入节点直接连接到输出节点sourceNode.connect(audioCtx.destination);// 设置音源自动分别沿 xyz 三个轴来回移动效果,形成环绕效果function autoMove(axis, interval, step = 100, maxDistance = 1000) {let isAdd = trueconst positionAxisMap = ["positionX", "positionY", "positionZ"]setInterval(() => {if (isAdd && audioPosition[axis] >= maxDistance) {isAdd = false;} else if (!isAdd && audioPosition[axis] <= -maxDistance) {isAdd = true;}if (isAdd) {audioPosition[axis] += step;} else {audioPosition[axis] -= step;}pannerNode[positionAxisMap[axis]].value = audioPosition[axis]console.log('audioPosition', audioPosition);}, interval)}// 沿 x 轴在 -1000 到 1000 之间来回移动autoMove(0, 100, 100, 1000)// 沿 z 轴在 -1000 到 1000 之间来回移动autoMove(2, 200, 100, 1000)// 沿 y 轴在 -100 到 100 之间来回移动autoMove(1, 400, 10, 100)// 开始播放音乐function startPlay() {audioCtx.resume();// 设置静音播放。audioEl.play();}// 开关 3D 音效let isSpatialized = falsefunction spatialize() {isSpatialized = !isSpatializeddocument.querySelector("#status").innerText = isSpatialized ? "开启" : "关闭"if (isSpatialized) {sourceNode.disconnect();sourceNode.connect(pannerNode);// 将处理节点连接到 destination 输出节点进行效果输出。pannerNode.connect(audioCtx.destination);} else {sourceNode.disconnect();sourceNode.connect(audioCtx.destination);}}</script>
</body></html>

四、结语

本文主要讲解了对于 Web Audio API 的基本使用及使用 AudioListener 和 PannerNode 实现环绕声效果。

Web Audio API 除了进行 3D 音效外还有很多强大的音频处理能力,可以查看 MDN 上的文档了解 Web Audio API 更多能力,链接:https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Audio_API#%E5%AE%9A%E4%B9%89%E9%9F%B3%E6%95%88 。

如果想要了解更多关于 ZEGO Express SDK 范围语音功能模块,可以查看 ZEGO 官网介绍文档,链接: https://doc-zh.zego.im/article/12045 。

也可以打开我们的范围语音 Demo 进行体验:https://zegoim.github.io/express-demo-web/src/Examples/Others/RangeAudio/index.html

如何在 Web 前端做 3D 音效处理相关推荐

  1. web前端做汽车之家官网,HTML5+CSS3+JS

    大一写的代码,那时候没有接触到技术博客,没有及时记录下来,如今大三回顾前两年所学,发现好多知识已有所遗忘,现在重新复习web前端语言,当时写代码时所遇到的问题已经记不清楚了,但大体的解决办法还牢记于心 ...

  2. web前端 2D 3D 动画小记(让网页栩栩如生的秘密)

    带上3D眼镜,你就是最靓的崽! 文章目录 前言 一.transform 转换 1.2D转换与3D转换 translate小应用 2.3D眼镜 --preserve 3.透视 perspective 二 ...

  3. 关于Web前端做前后台数据交互的那些事儿

    这里以用户登录为例,用户登录与退出功能应用在很多地方,而在有些项目中,我们需要使用Ajax方式进行登录,登录成功后只刷新页面局部,从而提升了用户体验度.本文将使用PHP和jQuery来实现登录和退出功 ...

  4. Web前端开发是什么?哪类人适合做Web前端?

    哪些人适合做Web前端我们在想要学习一门新的技术时候,大多数都会考虑自己是不是适合学习,零基础的人能学会吗,这个技术未来的发展前景怎么样?诸如此类的问题,下面,千锋广州Web前端小编就给大家的解答这些 ...

  5. 前端交接文档_开发型Web前端和设计型Web前端的区别是什么?

    小编说学Web前端,你弄懂开发型Web前端和设计型Web前端的区别了吗?今天千锋广州小编给大家梳理一下设计型Web前端做什么?都要学习什么? 想必大家也会遇到这种情况,要做一个项目,产品经理说产品原型 ...

  6. WEB前端实现在线预览、编辑Office文档

    这篇文章介绍如何在web前端引入JS插件实现在线预览.编辑Office文档. 使用插件:Spire.Cloud在线Office文档编辑器(官网:冰蓝科技在线编辑) 重点:该方案仅需浏览器支持HTML5 ...

  7. 学习Web前端,是应该自学,还是参加培训班?

    先说观点,我强烈建议每个人都要自学,不要参加培训班. 我干web前端工程师这个职位已经有6年多的时间,之前在蚂蚁金服做过2年,后来离开是因为加班实在熬不住才走的,像这些已经上市的互联网公司几乎没有不加 ...

  8. 零基础如何掌握web前端开发技能

    很多零基础学员想要进入到互联网行业都会选择web前端做首选技术语言来学习,但是学习web前端不是那么容易的,想要成为一名合格的web前端工程师,所要掌握的技能一定要会,下面小编就为大家详细的介绍一下零 ...

  9. 学web前端开发有前途吗

    web前端开发现在如此火爆,可以说是引领了IT培训行业的一个潮流,那么web前端开发都要学些什么知识呢?为什么这么火有前途吗?现在行业很需要这种人才吗?还是大家盲目跟风,随大流,下面小编对web前端做 ...

  10. 准备入行Web前端,又担心适不适合,怎么办?

    随着互联网的迅速发展,人们对界面的要求越来越高,也让Web前端开发走到台前,成为一个重要的开发工种.Web前端也成为大家非常熟悉的一个技术方向,也成为众多年轻人的职位选择新方向. 从目前看来,Web前 ...

最新文章

  1. Android Studio 简介
  2. Oracle Linux Server release 6.3 下安装JDK
  3. mysql innodb 锁_MySQL/InnoDB锁机制
  4. 让改变输入法回车键的图标
  5. mysql 四种存储引擎
  6. jQuery 2.0.3 - 整体架构
  7. 随想录(内核模块的测试方法)
  8. 匹配追踪分解 时频 matlab,基于匹配追踪(MP)算法的信号自适应分解研究及其应用...
  9. Atitit uke各大事业部规划 约365个事业部
  10. win7 64位系统HP LaserJet P1008 / HP LaserJet P1008 P1007 驱动安装成功,但无法打印的原因...
  11. 管家婆设计页面用什么做的_管家婆软件主要是用来做什么的?
  12. 51单片机(AT89S52)设计简单计算器(4位加减乘除)
  13. java实现机器人行走
  14. (2015年度)黑龙江测绘地理信息局青年学术和技术带头人考评与增选公示
  15. iOS及Android消息推送方案安装使用入门
  16. 中国龙与西方龙的区别
  17. 嵌入式linux开发,flex库移植
  18. 投后电视显示无法连接服务器,苹果AirPlay怎么用:AirPlay在哪设置,无法连接电视怎么办?...
  19. 阿里巴巴开源的 Java 诊断工具Arthas【入门篇】
  20. 2018十大国产佳片

热门文章

  1. Redis 设计与实现
  2. 微信小程序码合成图片
  3. JS实现,页面显示数据加载,显示加载效果,加载完成显示数据
  4. 聊聊我是如何编程入门的
  5. 详解Java的IO流Part7:PrintStream打印流【完结】
  6. Linux之kill命令
  7. jQuery源码结构
  8. echarts中国地图及经纬度json
  9. 离散数学及其应用傅彦pdf_离散数学及其应用 傅彦 等 高等教育出版社
  10. USB3014-应用程序开发(2)