介绍
如果您正在某个平台上工作,需要向用户播放一些音频,例如,出售一些音频文件,那么展示它的波形非常棒,这样用户就会对音频的结构以及您的内容印象深刻平台可以做。您可以使用Web Audio API在 JavaScript 中构建一个简单的音频播放器应用程序. API 允许您从音频文件中提取频率、波形和其他数据。提取的数据可用于通过生成波来可视化。当您处理音频波形生成的大数据时,在网页中没有任何延迟的情况下更平滑、更快地绘制波形非常重要。作为开发人员,我更喜欢让页面保持更快,而不管页面中的内容负载如何。如果我们尝试在页面中绘制波形,则必须牢记性能并构建一些简单的库来实现它。相反,我使用CanvasJS 图表来可视化可以在几毫秒内绘制数百万个数据点的波形。
底层技术是使用 Web Audio API 和 CanvasJS 在 JavaScript 中构建的。但是,它适用于 Angular、React 或任何其他 JavaScript 框架。
分步说明
要播放或可视化音频的波形,需要音频文件。让我们添加一个输入字段,让用户可以从他们的机器上浏览 MP3 文件。为简单起见,我将其限制为只允许用户浏览 MP3 文件。但是,网络音频 API支持 WAV、MP3、AAC、OGG 和其他格式。
<span style="color:#000000"><span style="background-color:#fbedbb"><span style="color:#0000ff"><</span><span style="color:#800000">input</span> <span style="color:#ff0000">type</span><span style="color:#0000ff">="</span><span style="color:#0000ff">file"</span> <span style="color:#ff0000">class</span><span style="color:#0000ff">="</span><span style="color:#0000ff">file-input"</span> <span style="color:#ff0000">id</span><span style="color:#0000ff">="</span><span style="color:#0000ff">mp3-input"</span> <span style="color:#ff0000">accept</span><span style="color:#0000ff">="</span><span style="color:#0000ff">audio/mp3"</span><span style="color:#0000ff">></span></span></span>
读取音频文件
在 Web Audio API 中,我们需要获取ArrayBuffer
音频数据并将其传递给 aBufferSource
以获取音频。使用AudioContext.decodeAudioData方法获取声音的音频缓冲区。解码后被AudioBuffer
重新采样到AudioContext的采样率,然后传递给回调或承诺。
<span style="color:#000000"><span style="background-color:#fbedbb"><span style="color:#0000ff">let</span> margin = <span style="color:#000080">10</span>,
chunkSize = <span style="color:#000080">500</span>,
height = chart.get(<span style="color:#800080">"</span><span style="color:#800080">height"</span>),
scaleFactor = (height - margin * <span style="color:#000080">2</span>) / <span style="color:#000080">2</span>;
audioContext = <span style="color:#0000ff">new</span> AudioContext();
<span style="color:#0000ff">let</span> buffer = <span style="color:#0000ff">await</span> file.arrayBuffer(),
audioBuffer = <span style="color:#0000ff">await</span> audioContext.decodeAudioData(buffer),
float32Array = audioBuffer.getChannelData(<span style="color:#000080">0</span>);
<span style="color:#0000ff">let</span> array = [], i = <span style="color:#000080">0</span>, length = float32Array.length;
<span style="color:#0000ff">while</span> (i < length) {
array.push(
float32Array.slice(i, i += chunkSize).reduce(<span style="color:#0000ff">function</span> (total, value) {
<span style="color:#0000ff">return</span> Math.max(total, Math.abs(value));
})
);
}</span></span>
添加播放/暂停和停止按钮
让我们添加两个按钮,一个用于控制播放/暂停,另一个用于停止。通常,按钮中的图标/文本应显示用户可以执行的操作。播放音频时,暂停时显示“暂停”文本/图标和“播放”文本/图标。您可以轻松地在播放和暂停状态之间切换来实现这一点。在 Web Audio API 中,您可以检查音频上下文的状态,并根据当前状态恢复或暂停音频。
<span style="color:#000000"><span style="background-color:#fbedbb"><span style="color:#0000ff"><</span><span style="color:#800000">button</span> <span style="color:#ff0000">class</span><span style="color:#0000ff">="</span><span style="color:#0000ff">button"</span> <span style="color:#ff0000">id</span><span style="color:#0000ff">="</span><span style="color:#0000ff">play-pause-btn"</span>
<span style="color:#ff0000">title</span><span style="color:#0000ff">="</span><span style="color:#0000ff">Play / Pause"</span><span style="color:#0000ff">></span><span style="color:#0000ff"><</span><span style="color:#800000">span</span> <span style="color:#ff0000">class</span><span style="color:#0000ff">="</span><span style="color:#0000ff">pp-icon"</span><span style="color:#0000ff">></span><span style="color:#0000ff"><</span><span style="color:#800000">/span</span><span style="color:#0000ff">></span><span style="color:#0000ff"><</span><span style="color:#800000">/button</span><span style="color:#0000ff">></span>
<span style="color:#0000ff"><</span><span style="color:#800000">button</span> <span style="color:#ff0000">class</span><span style="color:#0000ff">="</span><span style="color:#0000ff">button"</span> <span style="color:#ff0000">id</span><span style="color:#0000ff">="</span><span style="color:#0000ff">stop-btn"</span>
<span style="color:#ff0000">title</span><span style="color:#0000ff">="</span><span style="color:#0000ff">Stop"</span><span style="color:#0000ff">></span><span style="color:#0000ff"><</span><span style="color:#800000">span</span> <span style="color:#ff0000">class</span><span style="color:#0000ff">="</span><span style="color:#0000ff">stop-icon"</span><span style="color:#0000ff">></span><span style="color:#0000ff"><</span><span style="color:#800000">/span</span><span style="color:#0000ff">></span><span style="color:#0000ff"><</span><span style="color:#800000">/button</span><span style="color:#0000ff">></span></span></span>
<span style="color:#000000"><span style="background-color:#fbedbb"><span style="color:#0000ff">if</span>(audioContext.state === <span style="color:#800080">'</span><span style="color:#800080">running'</span>) {
audioContext.suspend().then(() => {
playPauseBtn.classList.toggle(<span style="color:#800080">'</span><span style="color:#800080">is-play'</span>);
});
}
<span style="color:#0000ff">else</span> <span style="color:#0000ff">if</span>(audioContext.state === <span style="color:#800080">'</span><span style="color:#800080">suspended'</span>) {
audioContext.resume().then(() => {
playPauseBtn.classList.toggle(<span style="color:#800080">'</span><span style="color:#800080">is-play'</span>);
});
}</span></span>
停止音频非常简单。Web Audio API 可以选择通过调用stop() 方法来停止源。
<span style="color:#000000"><span style="background-color:#fbedbb">source.stop();</span></span>
从音频数据生成数据点
CanvasJS 支持多种图表类型,如折线、面积、饼图、范围、财务图表等,适用于不同的数据集和用例。在这种情况下,范围区域非常适合 - 因为它看起来像音频波。我们唯一的任务是从音频文件生成数据点,将其传递给图表。CanvasJS 像魅力一样为您绘制波形图。
<span style="color:#000000"><span style="background-color:#fbedbb"><span style="color:#0000ff">let</span> dps = []
<span style="color:#0000ff">for</span> (<span style="color:#0000ff">let</span> index <span style="color:#0000ff">in</span> array) {
dps.push({ x: margin + Number(index),
y: [<span style="color:#000080">50</span> - array[index] * scaleFactor, <span style="color:#000080">50</span> + array[index] * scaleFactor]});
}
chart.options.<span style="color:#339999">data</span>[<span style="color:#000080">0</span>].dataPoints = dps;
chart.<span style="color:#339999">render</span>();</span></span>
将音频播放效果添加到 Wave
当音频开始播放时,对波形中已经播放过的区域进行阴影处理是一个不错的选择。添加带状线以显示图表中的阴影区域并每隔几毫秒或 1 秒更新一次。一旦音频停止播放,就停止更新它。
<span style="color:#000000"><span style="background-color:#fbedbb">source.onended = () => {
chart.axisX[<span style="color:#000080">0</span>].stripLines[<span style="color:#000080">0</span>].set(<span style="color:#800080">"</span><span style="color:#800080">endValue"</span>, chart.axisX[<span style="color:#000080">0</span>].get(<span style="color:#800080">"</span><span style="color:#800080">maximum"</span>));
clearInterval(intervalId);
}
<span style="color:#0000ff">let</span> intervalId = setInterval(() => {
chart.axisX[<span style="color:#000080">0</span>].stripLines[<span style="color:#000080">0</span>].set
(<span style="color:#800080">"</span><span style="color:#800080">endValue"</span>, audioContext.currentTime *
(chart.<span style="color:#339999">data</span>[<span style="color:#000080">0</span>].dataPoints.length / audioBuffer.duration));
}, <span style="color:#000080">250</span>);</span></span>
伊皮!您刚刚构建了一个带有播放、暂停和停止选项的自定义音频播放器,以及使用CanvasJS 范围-面积图生成的音频波形。您甚至可以使用柱形图,范围柱形图确实以不同的方式显示波浪。您甚至可以使用简单的 CSS 属性自定义音频播放器的外观和感觉,并通过更改 CanvasJS 图表属性将其与波形匹配。
这个由 CanvasJS 图表生成的波形可以与音频/视频播放器集成,以吸引用户。库有更多自定义选项来更改外观 - 这使您可以更灵活地自定义图表外观以匹配您的网站/播放器主题。在本教程中,我禁用了图表交互性以便仅展示波形。但是,CanvasJS 支持交互性,当您悬停图表时它会显示工具提示和突出显示。检查此JSFiddle以获取实时代码。