如何编写基于网络的音乐可视化工具?

nic*_*ico 5 visualization quartz-graphics raphael unity-game-engine webgl

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

Bri*_*nna 5

由于WebGL尚未准备就绪,因此我假设您是指渗透(目前仅在WebKit和Firefox中受支持)。

除此之外,使用HTML5音频和WebGL绝对可以实现均衡器。一个叫David Humphrey的人在博客上发表了有关使用WebGL 制作不同音乐可视化工具的文章,并且能够创建一些非常令人印象深刻的音乐可视化工具。这是一些可视化的视频(点击观看):


gma*_*man 5

使音频无反应非常简单。这是一个开放源码的站点,其中包含许多音频响应示例

至于如何做,您基本上是使用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);
  }
}
Run Code Online (Sandbox Code Playgroud)
canvas { border: 1px solid black; display: block; }
Run Code Online (Sandbox Code Playgroud)
<canvas></canvas>
Run Code Online (Sandbox Code Playgroud)

然后由您决定是否要创作一些东西。

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

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

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

  3. 如样本中所指出的,如果源是来自同一域,或者您请求CORS许可并且服务器提供了许可,则您只能分析音频。仅AFAIK Soundcloud授予许可,并且基于每首歌曲。是否允许对特定歌曲进行音频分析取决于个人歌手的歌曲设置。

    试图解释这部分

    默认设置是您有权访问同一域中的所有数据,但没有其他域的许可。

    当您添加

    audio.crossOrigin = "anonymous";
    
    Run Code Online (Sandbox Code Playgroud)

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


音乐:DOCTOR VOX-升级