【前端】Web Audio API接口介绍
ZSK6 2024-06-30 17:03:08 阅读 59
简言
记录下Web Audio API接口的介绍。
Web Audio API 提供了在 Web 上控制音频的一个非常有效通用的系统,允许开发者来自选音频源,对音频添加特效,使音频可视化,添加空间效果(如平移),等等。
Web Audio API
Web Audio API 使用户可以在音频上下文(AudioContext)中进行音频操作。
基本音频操作通过音频节点执行,这些节点连接在一起形成音频路由图。即使在单个上下文中,也可支持多个具有不同类型通道布局的音源。这种模块化设计为创建具有动态效果的复杂音频功能提供了灵活性。这种模块化设计提供了灵活创建动态效果的复合音频的方法。
音频节点(audio node)通过它们的输入输出相互连接,形成一个链或者一个简单的网。一般来说,这个链或网起始于一个或多个音频源。
音频源可以提供一个片段一个片段的音频采样数据(以数组的方式),也可以是音频或视频的文件读出来的,又或者是音频流(MediaStreamAudioSourceNode)。
这些节点的输出可以连接到其他节点的输入上,然后新节点可以对接收到的采样数据再进行其他的处理,再形成一个结果流。
声音处理完成之后,可以连接到一个目的地(AudioContext.destination),这个目的地负责把声音数据传输给扬声器或者耳机。注意,只有当用户期望听到声音时,才需要进行最后一个这个连接。
web audio流程如下:
使用 AudioContext 创建音频上下文。在音频上下文里创建音频源,音频源可以是上面说的那三种情况。对音频进行处理(当然也可以不处理),处理需要创建效果节点,例如混响、双二阶滤波器、平移、压缩等。为音频选择一个目的地,例如你的系统扬声器连接源到效果器,对目的地进行效果输出。
Web Audio API 接口
Web Audio API 共有一系列接口和相关的事件。
AudioContext — AudioContext 接口代表由音频模块构成的音频处理图。音频上下文控制其所包含节点的创建和音频处理、解码。使用其他接口前你必需创建一个音频上下文,一切操作都在这个环境里进行。AudioNode — 音频节点 接口是一个音频处理模块,包含了音频源节点、音频输出、音量控制节点等。AudioParam — AudioParam 接口代表音频相关的参数,比如一个 AudioNode的参数。它可以设置为特定值或值的变化,并且可以在指定的时间之后以指定模式变更。ended结束事件 — 当媒体播放停止时,会触发ended事件。OscillatorNode — OscillatorNode 接口代表一种随时间变化的波形,比如正弦波形或三角波形。类型是AudioNode,功能是音频处理模块,可以产生指定频率的波形。AudioBuffer — AudioBuffer 代表内存中的一段音频数据,可以通过AudioContext.decodeAudioData()方法从音频文件创建,也可以通过AudioContext.createBuffer()方法从原始数据创建。当音频数据被解码成这种格式之后,就可以被放入一个AudioBufferSourceNode中使用。AudioBufferSourceNode — AudioBufferSourceNode 表示由内存音频数据组成的音频源,音频数据存储在AudioBuffer中。这是一个作为音频源的AudioNode。MediaElementAudioSourceNode — MediaElementAudioSourceNode 接口表示由 HTML5 <audio>或<video>元素生成的音频源。这是一个作为音频源的AudioNode。MediaStreamAudioSourceNode — MediaStreamAudioSourceNode 接口表示由 WebRTC MediaStream(如网络摄像头或麦克风)生成的音频源。这是一个作为音频源的AudioNode。BiquadFilterNode — BiquadFilterNode 接口表示一个简单的低阶滤波器。它是一个AudioNode,可以表示不同种类的滤波器、调音器或图形均衡器。BiquadFilterNode 总是只有一个输入和一个输出。ConvolverNode — ConvolverNode 接口是一个AudioNode,对给定的 AudioBuffer 执行线性卷积,通常用于实现混响效果。DelayNode — DelayNode 接口表示延迟线;是AudioNode 类型的音频处理模块,使输入的数据延时输出。DynamicsCompressorNode — DynamicsCompressorNode 提供了一个压缩效果,当多个音频在同时播放并且混合的时候,可以通过它降低音量最大的部分的音量来帮助避免发生削波和失真。GainNode — GainNode 接口用于音量变化。它是一个 AudioNode 类型的音频处理模块,输入后应用增益 效果,然后输出。StereoPannerNode — StereoPannerNode 接口表示一个简单立体声控制节点,用来左右移动音频流(左右声道处理)。WaveShaperNode — WaveShaperNode 接口表示一个非线性的扭曲。它是AudioNode类型,可以利用曲线来对信号进行扭曲。除了一些效果明显的扭曲,还常被用来给声音添加温暖的感觉(暖调处理)。PeriodicWave — 用来定义周期性的波形,可被用来重塑 OscillatorNode的输出。AudioDestinationNode — AudioDestinationNode 定义了最后音频要输出到哪里,通常是输出到你的扬声器。MediaStreamAudioDestinationNode — MediaStreamAudioDestinationNode 定义了使用 WebRTC 的MediaStream(只包含单个 AudioMediaStreamTrack)应该连接的目的地,AudioMediaStreamTrack 的使用方式和从getUserMedia()中得到MediaStream相似。这个接口是AudioNode类型的音频目的地。AnalyserNode — AnalyserNode 表示一个可以提供实时频率分析与时域分析的切点,这些分析数据可以用做数据分析和可视化。如果你想从音频里提取时间、频率或者其他数据,你需要 AnalyserNodeChannelSplitterNode — ChannelSplitterNode 可以把输入流的每个声道输出到一个独立的输出流(通道分离)。ChannelMergerNode — ChannelMergerNode 用于把一组输入流合成到一个输出流。输出流的每一个声道对应一个输入流(通道合并)。AudioListener — 代表场景中正在听声音的人的位置和朝向。PannerNode — PannerNode 用于表示场景是声音的空间行为。它是AudioNode类型的音频处理模块,这个节点用于表示右手笛卡尔坐标系里声源的位置信息,运动信息(通过一个速度向量表示),方向信息(通过一个方向圆锥表示)。ScriptProcessorNode — ScriptProcessorNode 接口用于通过 JavaScript 代码生成,处理,分析音频。它是一个AudioNode类型的音频处理模块,但是它与两个缓冲区相连接,一个缓冲区里包含当前的输入数据,另一个缓冲区里包含着输出数据。每当新的音频数据被放入输入缓冲区,就会产生一个AudioProcessingEvent 事件,当这个事件处理结束时,输出缓冲区里应该写好了新数据。audioprocess事件 — 当一个 Web Audio API ScriptProcessorNode已经准备好进行处理时,这个事件回调会被调用。AudioProcessingEvent 事件 — 当ScriptProcessorNode的输入流数据准备好了时,AudioProcessingEvent事件会产生。OfflineAudioContext — OfflineAudioContext 离线音频上下文也是音频上下文AudioContext,也表示把AudioNode连接到一起的一个音频处理图。但是,与一个标准的音频上下文相比,离线上下文不能把音频渲染到扬声器,仅仅是把音频渲染到一个缓冲区。complete — Complete 事件,当离线音频上下文被终止时产生。OfflineAudioCompletionEvent 事件 — OfflineAudioCompletionEvent表示上下文被终止时的事件。
示例
音频可视化:
<!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>可视化</title>
<style>
#canvas,
#canvas2 {
border: 1px solid #000;
}
</style>
</head>
<h1>声音可视化</h1>
<div>
<audio controls autoplay loop crossorigin="anonymous">
<source src="./2789078374.mp3" type="audio/mpeg">
Your browser does not support the audio element.
</audio>
<h2>可视化图形</h2>
<canvas id="canvas"></canvas>
<canvas id="canvas2"></canvas>
<button id="btn">生成</button>
</div>
<body>
<script>
const canvasDom = document.getElementById("canvas");
const canvasW = 1000
const canvasH = 256
canvasDom.width = canvasW;
canvasDom.height = canvasH;
const canvasCtx = canvasDom.getContext("2d");
const canvasDom2 = document.getElementById("canvas2");
canvasDom2.width = canvasW;
canvasDom2.height = canvasH;
const canvasCtx2 = canvasDom2.getContext("2d");
const btn = document.getElementById("btn");
let audioCtx = null
let analyser
let source
btn.addEventListener("click", () => {
if (audioCtx == null) {
audioCtx = new (window.AudioContext || window.webkitAudioContext)()
// 创建 AnalyserNode节点
analyser = audioCtx.createAnalyser()
const distortion = audioCtx.createWaveShaper()
// 连接声源
source = audioCtx.createMediaElementSource(document.querySelector('audio'))
source.connect(analyser)
analyser.connect(audioCtx.destination);
}
analyser.fftSize = 2048
let bufferLength = analyser.frequencyBinCount
const dataArray = new Uint8Array(bufferLength)
analyser.getByteTimeDomainData(dataArray)
//要捕获数据,你需要使用 AnalyserNode.getFloatFrequencyData() 或 AnalyserNode.getByteFrequencyData() 方法来获取频率数据,
// 用 AnalyserNode.getByteTimeDomainData() 或 AnalyserNode.getFloatTimeDomainData() (en-US) 来获取波形数据。
let drawVisual;
canvasCtx.clearRect(0, 0, canvasW, canvasH);
// 波形图
function draw() {
analyser.getByteTimeDomainData(dataArray)
canvasCtx.fillStyle = "rgb(200, 200, 200)";
canvasCtx.fillRect(0, 0, canvasW, canvasH);
var sliceWidth = (canvasW * 1.0) / bufferLength;
canvasCtx.lineWidth = 2;
canvasCtx.strokeStyle = "rgb(0, 0, 0)";
canvasCtx.beginPath();
canvasCtx.moveTo(0, canvasH / 2);
canvasCtx.lineTo(canvasW, canvasH / 2);
canvasCtx.stroke()
canvasCtx.beginPath();
let x = 0
for (let i = 0; i < bufferLength; i++) {
let v = dataArray[i] / 128.0;
let y = (v * canvasH) / 2;
if (i === 0) {
canvasCtx.moveTo(x, y);
} else {
canvasCtx.lineTo(x, y);
}
x += sliceWidth;
canvasCtx.stroke();
}
drawVisual = requestAnimationFrame(draw);
}
draw()
// 柱形图
function drawBar() {
analyser.getByteTimeDomainData(dataArray)
canvasCtx2.fillStyle = "rgb(0,0,0)";
canvasCtx2.fillRect(0, 0, canvasW, canvasH);
let barWidth = canvasW / bufferLength * 2.5;
let x = 0
for (let i = 0; i < bufferLength; i++) {
let barHeight = dataArray[i] / 128.0 / 2 * canvasH;
canvasCtx2.fillStyle = 'rgb(' + (barHeight + 100) + ',50,50)';
canvasCtx2.fillRect(x, canvasH - barHeight, barWidth, barHeight);
x += barWidth + 1;
}
requestAnimationFrame(drawBar);
}
drawBar()
})
</script>
</body>
</html>
使用 file://打开的话会报cors,使用http服务打开。
结语
结束了。
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。