如何编写基于Web的音乐可视化程序?

7

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

4个回答

8
使某物对音频有反应是很简单的。这里有一个开源网站,提供了许多音频反应示例
至于如何实现,基本上使用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. At this point in time (2017/1/3) neither Android Chrome nor iOS Safari support analysing streaming audio data. Instead you have to load the entire song. Here'a a library that tries to abstract that a little

  2. On Mobile you can not automatically play audio. You must start the audio inside an input event based on user input like 'click' or 'touchstart'.

  3. As pointed out in the sample you can only analyse audio if the source is either from the same domain OR you ask for CORS permission and the server gives permission. AFAIK only Soundcloud gives permission and it's on a per song basis. It's up to the individual artist's song's settings whether or not audio analysis is allowed for a particular song.

    To try to explain this part

    The default is you have permission to access all data from the same domain but no permission from other domains.

    When you add

    audio.crossOrigin = "anonymous";
    

    That basically says "ask the server for permission for user 'anonymous'". The server can give permission or not. It's up to the server. This includes asking even the server on the same domain which means if you're going to request a song on the same domain you need to either (a) remove the line above or (b) configure your server to give CORS permission. Most servers by default do not give CORS permission so if you add that line, even if the server is the same domain, if it does not give CORS permission then trying to analyse the audio will fail.


音乐:DOCTOR VOX - Level Up


5
通过说WebGL“不准备好”,我假设你指的是它的渗透性(目前只在WebKit和Firefox中支持)。
除此之外,使用HTML5音频和WebGL肯定可以实现均衡器。一个叫David Humphrey的人写了关于使用WebGL制作不同音乐可视化效果的博客文章,并且能够创建一些非常令人印象深刻的效果。以下是一些可视化视频(点击观看):


2

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接