音频炼金术:Threejs 让 3D 场景「听」起来更真实

在 Three.js 中允许在场景中添加声音,将声音与 3D 对象关联,实现更丰富的交互体验。

Audio

Three.js 中的Audio对象用于表示音频源,它是一个THREE.Object3D的子类,用于控制音频播放、暂停、是否循环等设置的对象,可以添加到场景中,并与其他 3D 对象关联。它依赖于 Web Audio API,因此需要浏览器支持。

js 复制代码
const audio = new THREE.Audio(listener);

实例化构造函数,接收一个必选的音频监听器参数,用于接收和处理音频信号。

属性:

  • isPlaying:布尔值,表示音频是否正在播放。

  • hasPlaybackControl:布尔值,表示音频是否具有播放控制权。

  • playbackRate:浮点数,表示音频播放速度,默认值为 1.0。

  • offset:浮点数,表示音频播放的起始位置,默认值为 0.0。

  • duration:浮点数,获取音频的时长,但是不是在 Audio 上,而是使用 buffer 的 duration 属性。

  • autoplay:布尔值,是否自动播放音频。

  • context:音频上下文,构造函数中传入 listener 的 AudioContext.。

  • detune:整数,修改音高,以音分为单位。 +/- 100 为一个半音, +/- 1200 为一个八度。默认值为 0。

  • gain:AudioGainNode,用于控制音频的音量。

  • source:Audio 对象的 source,属性属于底层的 Web Audio API。通过 source 可以控制音频的播放、暂停、循环等。

方法:

  • connect(destination):将音频连接到目标节点。

  • disconnect(destination):将音频从目标节点断开连接。

  • getVolume():获取音量。

  • play():播放音频。

  • pause():暂停音频。

  • stop():停止音频。

  • setLoop(loop):设置音频是否循环播放。

  • setVolume(volume):设置音量。

  • setBuffer(buffer):设置音频缓冲区。

  • onEnded():播放完成后自动调用。

js 复制代码
// 创建一个AudioListener对象
const listener = new THREE.AudioListener();
// 将AudioListener对象添加到相机上
camera.add(listener);
// 创建一个Audio对象,并将AudioListener对象作为参数传入
const sound = new THREE.Audio(listener);
// 创建一个AudioLoader对象
const audioLoader = new THREE.AudioLoader();
// 加载音频文件
audioLoader.load("./audio/song.ogg", (buffer) => {
  // 将加载的音频文件设置为Audio对象的缓冲区
  sound.setBuffer(buffer);
  // 设置Audio对象循环播放
  sound.setLoop(true);
  // 设置Audio对象的音量为0.5
  sound.setVolume(0.5);
  // 播放Audio对象
  sound.play();
});
// 在控制台打印Audio对象
console.log(sound);
// 获取按钮元素
const btn = document.querySelector(".btn");
// 为按钮添加点击事件监听器
btn.addEventListener("click", () => {
  // 如果Audio对象正在播放,则暂停播放
  if (sound.isPlaying) {
    sound.pause();
    // 否则,播放Audio对象
  } else {
    sound.play();
  }
});

有时候播放会报警告,这个时候就需要手动触发播放。

The AudioContext was not allowed to start. It must be resumed (or created) after a user gesture on the page.

不允许启动音频上下文。用户在页面上做出手势后,必须恢复(或创建)它。

AudioListener

AudioListener是 Threejs 中用来管理 3D 音频的核心类,创建一个音频监听器。需要将AudioListener对象添加到相机上,以便在播放音频时能够正确地处理声音的位置和方向。

js 复制代码
const listener = new THREE.AudioListener();
camera.add(listener);

属性:

  • context:音频上下文,构造函数中传入的 AudioContext 对象。

  • gain:该属性标时音频系统中的主音量控制器,可以通过它来调节整个场景的音量。

  • filter:用于处理音频的滤波器。允许对音频信号进行过滤或效果处理。例如:可以用滤波器来创建环绕声效果或调节音质。

方法:

  • getInput():获取音频监听器的输入节点。
js 复制代码
const listener = new THREE.AudioListener();
const gainNode = listener.getInput();
gainNode.gain.value = 0.5; //调节整个场景音量到50%
  • setMasterVolume(volume):设置主音量。范围:0.0 到 1.0。
js 复制代码
listener.setMasterVolume(0.5); //调节整个场景音量到50%
  • setFilter():设置滤波器。
js 复制代码
//创建一个低通滤波器
const lowPassFilter = listener.context.createBiquadFilter();
lowPassFilter.type = "lowpass";
//低于500Hz的频率会通过,高于500Hz的频率会被衰减
lowPassFilter.frequency.value = 500;
sound.setFilter(lowPassFilter);

createBiquadFilter():创建一个滤波器,用于处理音频信号。可以设置滤波器的类型、频率、Q 值等参数。

音频效果是用于处理音频数据的对象,可以对音频进行各种处理,如混响、均衡器等。在 Three.js 中,可以使用ConvolverNodeGainNodeBiquadFilterNode等对象来创建音频效果。

PositionalAudio

PositionalAudio它继承自Audio类,用于创建具有空间定位效果的 3D 音频。会根据音源的位置和方向来计算声音的到达方向,从而实现更逼真的声音效果。

js 复制代码
const sound = new THREE.PositionalAudio(listener);

方法:

  • setRefDistance(distance):用于设置音源在特定距离内保持最大音量的范围。当音源距离监听器超过这个距离时,音量会逐渐减小。

  • setRolloffFactor(rolloffFactor):用于设置音量随距离变化的速率。默认值为 1,表示音量随距离线性减小。如果设置为 0,则音量不会随距离变化。

  • setMaxDistance(maxDistance):用于设置音源的最大距离。当音源距离监听器超过这个距离时,音量会变为 0。

  • getDistanceModel():获取音量随距离变化的模型。

js 复制代码
//创建一个音频监听器
const listener = new THREE.AudioListener();
//将音频监听器添加到相机上
camera.add(listener);
//创建一个位置音频对象
const sound = new THREE.PositionalAudio(listener);
//创建一个音频加载器
const audioLoader = new THREE.AudioLoader();
//加载音频文件
audioLoader.load("./audio/song.ogg", (buffer) => {
  //将音频缓冲区设置为音效的缓冲区
  sound.setBuffer(buffer);
  sound.setRefDistance(1); //设置音效开始衰减的距离
  sound.setLoop(true);
  sound.setVolume(0.5);
  sound.play();
});
//将音效关联到物体上
const sphere = new THREE.Mesh(
  new THREE.SphereGeometry(1),
  new THREE.MeshBasicMaterial({ color: 0x00ff00 })
);
scene.add(sphere);
sphere.position.set(15, 0, 0);
sphere.add(sound); //将音效关联到物体上

拖动这个球体,可以听到音效的位置发生了变化。

AudioAnalyser

AudioAnalyser是 Three.js 中用于分析音频数据的类,可以获取音频的频谱数据,从而实现音频可视化效果、分析音频的频率和波形数据、与场景元素结合实现音频驱动的动画。

js 复制代码
const listener = new THREE.AudioListener();
camera.add(listener);

const sound = new THREE.PositionalAudio(listener);

const audioLoader = new THREE.AudioLoader();
audioLoader.load("./audio/song.ogg", (buffer) => {
  sound.setBuffer(buffer);
  sound.setLoop(true);
  sound.setVolume(0.5);
  sound.play();

  //创建AudioAnalyser对象,传入sound和FFT大小
  const analyser = new THREE.AudioAnalyser(sound, 32);
  //获取频率数据
  const data = analyser.getFrequencyData();
  console.log(data);
  //获取平均频率
  const averageFrequency = analyser.getAverageFrequency();
  console.log(averageFrequency);
});

参数:

  • audio:音频对象,用于获取音频数据。

  • fftSize:用于设置 FFT 大小,默认值为 2048。FFT 大小决定了频谱数据的分辨率,较大的 FFT 大小可以提供更详细的频谱数据,但会消耗更多的计算资源。

方法:

  • getFrequencyData():获取频率数据,返回一个 Uint8Array 数组,每个值表示一个频率段的强度,范围为 0 到 255。用来创建频谱分析、柱状图等可视化效果。

  • getAverageFrequency():获取平均频率。用于判断整体的音量水平。适用于音频驱动的动画或音量监控。

AudioContext

AudioContext是 Web Audio API 的核心对象,用于创建和管理音频节点,处理音频数据,播放音频等。在 Three.js 中,可以通过AudioListener对象获取AudioContext对象,然后使用AudioContext对象创建音频节点,处理音频数据。

js 复制代码
const listener = new THREE.AudioListener();
camera.add(listener);

const audioContext = listener.context;

AudioContext

示例代码

演示

书洞笔记

相关推荐
Addisonx3 天前
深度复盘 III: 核心逻辑篇:构建 WebGL 数字孪生的“业务中枢”与“安全防线”
webgl·three.js
爱看书的小沐3 天前
【小沐学WebGIS】基于Three.JS绘制二三维地图地球晨昏效果(WebGL / vue / react )
javascript·vue.js·gis·webgl·three.js·opengl·晨昏线
Addisonx6 天前
深度复盘: WebGL 数字孪生前端架构:如何打造高颜值、高性能的 Web 3D 可视化系统
three.js
BUG创建者8 天前
thee.js完成线上展厅demo
开发语言·前端·javascript·css·html·css3·three.js
mortimer12 天前
Python + FFmpeg 视频自动化处理指南:从硬件加速到精确剪辑
python·ffmpeg·音视频开发
否子戈12 天前
做中国人自己的视频编辑UI框架,WebCut正式开源
前端框架·音视频开发·视频编码
音视频牛哥14 天前
从低延迟到高可用:RTMP与 HTTP/HTTPS-FLV在App播放体系中的角色重构
人工智能·音视频·音视频开发·http-flv播放器·https-flv播放器·ws-flv播放器·wss-flv播放器
一千柯橘17 天前
从摄影新手到三维光影师:Three.js 核心要素的故事
前端·three.js
音视频牛哥18 天前
轻量级RTSP服务的工程化设计与应用:从移动端到边缘设备的实时媒体架构
人工智能·计算机视觉·音视频·音视频开发·rtsp播放器·安卓rtsp服务器·安卓实现ipc功能
big男孩19 天前
OrbitControls 的完整原理
three.js