65.9K
CodeProject 正在变化。 阅读更多。
Home

3 种突破性的 HTML5 <audio> 可视化方法

starIconstarIconstarIconstarIconstarIcon

5.00/5 (3投票s)

2012 年 3 月 15 日

CPOL

6分钟阅读

viewsIcon

27272

我将重点关注一个 HTML5 标准未直接涵盖,但需求量大且视觉效果令人印象深刻的场景。那就是使用 HTML5 &lt;audio&gt; 进行音频可视化。

如今,HTML5 就像一部还没有写下一季的电视剧。

它已经拍摄了一些剧集,还有一些需要编辑的原始素材,一些正在等待酷炫特效的镜头,以及许多许多的粗略草稿。是的,我说的是整个 HTML5 的故事,而不仅仅是规范,但希望你明白了我的意思。

我将重点关注一个 HTML5 标准未直接涵盖,但需求量大且视觉效果令人印象深刻的场景。那就是使用 HTML5 <audio> 进行音频可视化,就像这样

在我刚才提到的电视剧类比中,音频可视化(特别是访问音频流的低级 API)正好介于早期草稿和未来剧集的想法之间。

你能用 <audio> 做什么……和不能做什么。

<audio> 元素在 HTML5 中,正如你所猜测的,并不提供低级 API。它允许你在高层面上管理音频流的播放:播放和暂停,设置和获取时间线上的当前位置,知道总时长,处理文本轨道,以及控制音量。

如果你尝试用 <audio> 做比播放单个音乐文件更复杂的事情——比如同步音频样本——你会发现它并不像你期望的那么容易。

在你可能想在网站上实现的许多其他音频任务方面,也存在一些限制:

正如你所看到的,这不仅取决于规范本身,还取决于实际浏览器中的实际实现。

未来的音频标准……也许

W3C 的音频工作组正在推进一项提供音频流低级 API 的倡议。

“音频 API 将提供读取音频样本、写入音频数据、创建声音以及以最小延迟执行客户端音频处理和合成的方法。它还将为脚本中的低级直接操作提供 PCM 音频流的编程访问。”

所以,也许在未来的某一天,我们会看到一种通用的、基于标准的音频流操作解决方案。

在此期间,让我们回到现实世界,深入探讨一下今天我们可以用 HTML5 做些什么!

实际方法:今天我能做什么?

首先,要构建可视化,你到底需要什么?你需要一些与音频播放及时同步的数据。它可以是歌词等文本信息,表示音量的数据,或者任何你想用来进行实验的其他数据。

从哪里获取数据?实际的方法是预处理。是的!就是这么简单和琐碎……

基本上,如果你想可视化音频,就需要做一些功课。先分析你的音频流,然后你就能生成与背景播放的音频同步的可视化。

例如,如果你想提取语义重要的数据(如歌曲的歌词),预处理是唯一可能的解决方案(除非你有足够熟练的人工智能来理解歌曲中的单词和句子)。

通常,这是一项枯燥的手工任务。你坐下来,打开你的音频播放器,开始播放歌曲,记住一句歌词,暂停,写下来,看时间,记下当前时间……一次又一次地重复。有时,你可以直接从网上找到。

而且预处理非常高效。使用这种方法可以节省计算资源,从而减少客户端的负载。这意味着你应该只计算(或写入)你的音频可视化数据一次,然后就可以随时使用这些数据来实现你的魔法。

现在让我们看看它在实际生活中是如何运作的……

处理实际示例

为了熟悉我稍后将介绍的所有很棒的解决方案,你可以使用你喜欢的浏览器中的开发者工具。 Internet Explorer 为此目的提供了出色的开发工具(只需按 F12!)。你可以使用“脚本”面板查看 JavaScript 代码、调试它、设置断点或在控制台中运行自己的代码。

有时你需要处理压缩(或最小化)的代码。在这种情况下,只需按“格式化 JavaScript”使其更易读。

示例 #1:雨中的 Chell

Chell in the Rain 是 Matthew Merkle 创建的歌曲 Exile Vilify 的令人惊叹的音频-文本可视化。你将看到歌曲的歌词与音频流完美同步出现。

里面有什么

  • jQuery + Sizzle.js(构建 jQuery)
  • jPlayer(用于播放音频和视频的库)
  • 以及一些我们感兴趣的代码 ;)

工作原理

歌曲被及时分割成几个片段或时间段(或时间点),指向短语的开始或某些动画。所有时间点都存储在一个数组中。

var timings = newArray();
timings[0] = 11.5;
timings[1] = 17;
timings[2] = 24;
timings[3] = 29;
timings[4] = 35.5;

同时,还有一个歌词数组。

var lyrics = newArray();
lyrics[0] = 'Exile';
lyrics[1] = 'It takes your mind... again';
lyrics[2] = "You've got sucker's luck";
lyrics[3] ='Have you given up?';

现在,播放的当前时间可以与时间点数组关联,并触发相应的事件触发器以跳转到下一个短语。

if(event.jPlayer.status.currentTime >= timings[currentTrigger] && nolyrics != true) {
    fireTrigger(currentTrigger);
    currentTrigger++;
}

接下来,触发的事件使用 jQuery 制作了一些动画。

function fireTrigger(trigger) {
   switch (trigger) {
      case 0:
         $('#lyrics1 p').addClass('vilify').html(lyrics[0]).fadeIn(1500);
         break;
      case 1:
         $('#lyrics2 p').html(lyrics[1]).fadeIn(1000).delay(5000).fadeOut(1000);
         $('#lyrics1 p').delay(6000).fadeOut(1000);
         break;
      case 2:
         $('#lyrics1 p').fadeIn(1000);
         break;
      case 3:
         $('#lyrics2 p').fadeIn(1000).delay(4000).fadeOut(1000);
         $('#lyrics1 p').delay(5000).fadeOut(1000);
         break;
      case 4:
         $('#lyrics1 p').removeClass('vilify').html(lyrics[2]).fadeIn(1000);
         break;
      case 5:
         $('#lyrics2 p').html(lyrics[3]).fadeIn(1000).delay(3000).fadeOut(1000);
         $('#lyrics1 p').delay(4000).fadeOut(1000);
         break;
...

这很简单,而且非常有效。

注意你可以多么轻松地将音频流播放与 HTML、CSS 和 JavaScript 的功能结合起来!

示例 #2:提取音频数据

在他的博文Music Visualizer in HTML5 / JS with Source Code 中,Grant 分享了他使用 HTML5 进行音频可视化的经验。

由于 HTML5 <audio> 不提供任何 API 来提取音频文件的低级数据,Grant 编写了一个小型 AIR 应用程序(包含示例)来帮助我们从 mp3 文件中提取音量数据,然后将其存储在文本文件或图像中。

放大后,音量数据看起来是这样的:

现在,有了这张图片,我们可以轻松地使用 HTML5 canvas 提取所有我们需要的数据。(对于文本文件来说就更简单了——我没有展示它,因为它没有意义让你自己阅读,因为所有数据都已压缩。)

为了处理这种预处理数据,Grant 还编写了一个小型的 JS 库 (VolumeData.js,是我下载的 .zip 中的一部分)。

要可视化某些内容,你需要先加载数据。

loadMusic("music.jpg");

loadMusic 函数只是加载图像。

function loadMusic(dataImageURL) {
   image = new Image();
   image.src = dataImageURL;
   playing = false;
   Ticker.addListener(window);
}

现在你应该创建一个新的 VolumeData 对象。

volumeData = new VolumeData(image);

然后在每次时间更新时,你可以使用当前时间的平均音量数据或每个通道(左和右)的单独数据来做任何你想做的事情。

var t = audio.currentTime;
var vol = volumeData.getVolume(t);
var avgVol = volumeData.getAverageVolume(t-0.1,t);
var volDelta = volumeData.getVolume(t-0.05);
volDelta.left = vol.left-volDelta.left;
volDelta.right = vol.right-volDelta.right;

所有视觉效果都基于这些数据。对于可视化,Grant 使用了 EaselJS 库。以下是一些示例:Star Field 和 Atomic。

现在你拥有了制作酷炫音频可视化所需的所有工具!J

总结:使用预处理来提高解决方案的效率。尝试将音频播放与文本数据、动画和基于音量数据的图形效果相结合,以创造引人入胜的用户体验。让它看起来就像魔法!

附加资源和更多信息

Unlocking the power of HTML5 <audio>,在 IE 团队博客上,描述了使用 HTML 处理音频的基础步骤和最佳实践。

本文中的示例

下载次数

© . All rights reserved.