BufferGeometry
Object3D
Raycaster
Camera
CubeCamera
PerspectiveCamera
OrthographicCamera
StereoCamera
Clock
Curve
CurvePath
Path
Shape
ShapePath
ArrowHelper
AxesHelper
BoxHelper
Box3Helper
CameraHelper
DirectionalLightHelper
GridHelper
PolarGridHelper
HemisphereLightHelper
PlaneHelper
PointLightHelper
SkeletonHelper
SpotLightHelper
Light
PointLight
RectAreaLight
SpotLight
DirectionalLight
HemisphereLight
LightShadow
PointLightShadow
AnimationLoader
AudioLoader
BufferGeometryLoader
CompressedTextureLoader
CubeTextureLoader
DataTextureLoader
FileLoader
ImageBitmapLoader
ImageLoader
Loader
LoaderUtils
MaterialLoader
ObjectLoader
TextureLoader
LoadingManager
Material
Box2
Box3
Color
Cylindrical
Euler
Frustum
Interpolant
Line3
MathUtils
Matrix3
Matrix4
Plane
Quaternion
AnimationAction
AnimationClip
AnimationMixer
AnimationObjectGroup
AnimationUtils
keyframeTrack
PropertyBinding
PropertyMixer
BooleanKeyframeTrack
QuaternionKeyframeTrack
StringKeyframeTrack
Audio
AudioAnalyser
AudioContext
AudioListener
PositionalAudio

AudioAnalyser.getFrequencyData()

该函数用于获取用于可视化的音频频谱数据,它是three.js的核心API之一。

语法

AudioAnalyser.getFrequencyData();

返回值

该函数会返回一个数组,其中包含了当前音频输入的频域数据(DFT),其长度为FFTSize属性值的一半。

用法

通过实例化音频分析器AudioAnalyser,我们可以轻松地读取当前输入音频数据的频率信息。

const audioAnalyser = new THREE.AudioAnalyser(audioListener, FFTSize);

// 用于显示频谱数据的mesh对象
const frequencyDataBox = new THREE.Mesh(
  new THREE.BoxGeometry(1, 1, 1),
  new THREE.MeshBasicMaterial({ color: 'red' })
);

scene.add(frequencyDataBox);

function render() {
  requestAnimationFrame(render);

  // 获取音频分析器的频域数据
  const frequencyData = audioAnalyser.getFrequencyData();

  // 更新mesh对象的缩放值
  for (let i = 0; i< frequencyData.length; i++) {
    // 将频域数据映射到[0,1]区间内
    const scaleValue = frequencyData[i]/255;
    frequencyDataBox.scale.set(i, scaleValue ,i);
  }

  renderer.render(scene, camera);
}

render();

参数

该函数不接受任何参数。

示例

我们可以使用three.jscanvas绘制API绘制出一个音频的频谱图。

const canvas = document.createElement('canvas');
document.body.appendChild(canvas);

const ctx = canvas.getContext('2d');

const audioContext = new window.AudioContext();
const audioBufferSourceNode = audioContext.createBufferSource();
const audioAnalyser = audioContext.createAnalyser();
const frequencyDataArray = new Uint8Array(audioAnalyser.frequencyBinCount);

// 音频数据获取
fetch('audio.mp3')
  .then(res => res.arrayBuffer())
  .then(buffer => audioContext.decodeAudioData(buffer))
  .then(decodedAudioData => {
    audioBufferSourceNode.buffer = decodedAudioData;
    audioAnalyser.fftSize = 512;
    audioBufferSourceNode.connect(audioAnalyser);
    audioAnalyser.connect(audioContext.destination);
    audioBufferSourceNode.start();

    function update() {
      requestAnimationFrame(update);
      audioAnalyser.getByteFrequencyData(frequencyDataArray);
      draw(frequencyDataArray);
    }

    update();
  });

function draw(frequencyDataArray) {
  const w = canvas.width;
  const h = canvas.height;
  const barWidth = w / frequencyDataArray.length;

  ctx.clearRect(0, 0, w, h);

  frequencyDataArray.forEach((value, index) => {
    const x = index * barWidth;
    const y = h - value * 0.5;

    ctx.fillRect(x, y, barWidth, h - y);
  });
}

注意事项

  • 在使用该函数时,需要指定AudioAnalyser实例的FFTSize属性值。FFTSize表示DFT(离散傅里叶变换)所采用的样本数量,其默认值为2048
  • 由于该函数返回的频谱数据并不是在每一帧都变化的,而是在音频输入流中有更新时才进行更新。因此,我们需要在渲染循环中频繁地调用该函数才能尽可能地保证频率信息的实时性和准确性。