6

我正在尝试找到构建音乐可视化器以通过网络在浏览器中运行的最佳方法。Unity 是一个选项,但我需要构建一个自定义音频导入/分析插件来获取最终用户的声音输出。Quartz 可以满足我的需要,但只能在 Mac/Safari 上运行。WebGL 似乎还没有准备好。Raphael 主要是 2D,还有获取用户声音的问题......有什么想法吗?有没有人这样做过?

4

4 回答 4

7

制作音频反应非常简单。这是一个包含大量音频反应示例的开源网站

至于如何做,您基本上使用 Web Audio API 来流式传输音乐并使用它的 AnalyserNode 来获取音频数据。

"use strict";
const ctx = document.querySelector("canvas").getContext("2d");

ctx.fillText("click to start", 100, 75);
ctx.canvas.addEventListener('click', start);  

function start() {
  ctx.canvas.removeEventListener('click', start);
  // make a Web Audio Context
  const context = new AudioContext();
  const analyser = context.createAnalyser();

  // Make a buffer to receive the audio data
  const numPoints = analyser.frequencyBinCount;
  const audioDataArray = new Uint8Array(numPoints);

  function render() {
    ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);

    // get the current audio data
    analyser.getByteFrequencyData(audioDataArray);

    const width = ctx.canvas.width;
    const height = ctx.canvas.height;
    const size = 5;

    // draw a point every size pixels
    for (let x = 0; x < width; x += size) {
      // compute the audio data for this point
      const ndx = x * numPoints / width | 0;
      // get the audio data and make it go from 0 to 1
      const audioValue = audioDataArray[ndx] / 255;
      // draw a rect size by size big
      const y = audioValue * height;
      ctx.fillRect(x, y, size, size);
    }
    requestAnimationFrame(render);
  }
  requestAnimationFrame(render);

  // Make a audio node
  const audio = new Audio();
  audio.loop = true;
  audio.autoplay = true;

  // this line is only needed if the music you are trying to play is on a
  // different server than the page trying to play it.
  // It asks the server for permission to use the music. If the server says "no"
  // then you will not be able to play the music
  // Note if you are using music from the same domain 
  // **YOU MUST REMOVE THIS LINE** or your server must give permission.
  audio.crossOrigin = "anonymous";

  // call `handleCanplay` when it music can be played
  audio.addEventListener('canplay', handleCanplay);
  audio.src = "https://twgljs.org/examples/sounds/DOCTOR%20VOX%20-%20Level%20Up.mp3";
  audio.load();


  function handleCanplay() {
    // connect the audio element to the analyser node and the analyser node
    // to the main Web Audio context
    const source = context.createMediaElementSource(audio);
    source.connect(analyser);
    analyser.connect(context.destination);
  }
}
canvas { border: 1px solid black; display: block; }
<canvas></canvas>

然后由你来画一些有创意的东西。

请注意您可能会遇到的一些麻烦。

  1. 目前(2017 年 1 月 3 日)Android Chrome 和 iOS Safari 都不支持分析流式音频数据。相反,您必须加载整首歌曲。这是一个试图抽象一点的库

  2. 在移动设备上,您无法自动播放音频。您必须根据用户输入(如'click'or )在输入事件中启动音频'touchstart'

  3. 正如示例中所指出的,您只能在源来自同一个域或者您请求 CORS 权限并且服务器授予权限的情况下分析音频。AFAIK 只有 Soundcloud 给予许可,并且是基于每首歌曲的。是否允许对特定歌曲进行音频分析取决于各个艺术家的歌曲设置。

    试图解释这部分

    默认情况下,您有权访问同一域中的所有数据,但无权访问其他域。

    当你添加

    audio.crossOrigin = "anonymous";
    

    这基本上是说“向服务器请求用户'匿名'的许可”。服务器可以给予或不给予许可。这取决于服务器。这甚至包括询问同一域中的服务器,这意味着如果您要请求同一域中的歌曲,您需要 (a) 删除上面的行或 (b) 配置您的服务器以授予 CORS 权限。大多数服务器默认情况下不授予 CORS 权限,因此如果添加该行,即使服务器是同一个域,如果它不授予 CORS 权限,那么尝试分析音频将失败。


音乐:DOCTOR VOX - 升级

于 2017-01-03T12:25:21.633 回答
5

通过 WebGL “未准备好”,我假设您指的是渗透(目前仅在 WebKit 和 Firefox 中支持)。

除此之外,均衡器绝对可以使用 HTML5 音频和 WebGL。一个叫 David Humphrey 的人写了一篇关于使用 WebGL 制作不同的音乐可视化器的博客,并且能够创建一些非常令人印象深刻的音乐可视化器。以下是一些可视化视频(点击观看):

于 2010-06-24T07:00:26.347 回答
2

我使用 SoundManager2 从 mp3 文件中提取波形数据。该功能需要 Flash 9,因此它可能不是最佳方法。

我的 HMTL5 Canvas 波形演示: http ://www.momentumracer.com/electriccanvas/

和 WebGL: http ://www.momentumracer.com/electricwebgl/

资料来源: https ://github.com/pepez/Electric-Canvas

于 2011-04-11T11:18:22.683 回答
1

根据您可能有兴趣尝试 Processing (http://www.processing.org) 的复杂性,它具有制作基于 Web 的应用程序的非常简单的工具,并且具有获取音频文件的 FFT 和波形的工具。

于 2010-10-15T18:22:03.447 回答