谷歌播放音乐用于创建"粒子"在他们的网站上的visualiser?

时间:2017-01-03 03:22:28

标签: google-play

谷歌播放音乐用于创建"粒子"在他们的网站上的visualiser? 使用了什么3D图形软件?我的猜测最初是通过webGL导出的统一3D,或者也许是three.js或UE4?

我不明白当3D视觉设备对音频做出反应时,他们如何让音频网络播放器流式播放音频。

我想重新创造同样的东西。不知道从哪里开始。我缺乏如何完成的知识。 无法在网上找到任何答案。

最重要的是谷歌做了什么不同的方法。有哪些主要区别?

Visualiser演示链接:https://www.youtube.com/watch?v=mjfKCSPFdGI

感谢。

1 个答案:

答案 0 :(得分:3)

如果您发布一个gif或其他内容来展示您所指的内容,那就太好了。

制作音频反应非常简单。 Here's an open source site with lots audio reactive examples

至于如何操作,你基本上使用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
  var 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
  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>

然后由你做一些有创意的事情。例如,不像在第一个例子中那样在屏幕上绘制一堆黑点,我们可以缩放随机彩色圆圈并调整它们的颜色和速度,就像这样

"use strict";

var context = new AudioContext();
var analyser = context.createAnalyser();

var numPoints = analyser.frequencyBinCount;
var audioDataArray = new Uint8Array(numPoints);

var ctx = document.querySelector("canvas").getContext("2d");
var ctx2 = document.createElement("canvas").getContext("2d");

var numSpots = 5;
var spots = [];
for (var ii = 0; ii < numSpots; ++ii) {
  spots.push({
    x: Math.random(), 
    y: Math.random(), 
    velocity: 0.01,
    direction: Math.random(),
    hue: Math.random() * 360 | 0,
  });
}

function rnd(min, max) {
  if (max === undefined) {
    max = min;
    min = 0;
  }
  return Math.random() * (max - min) + min;
}

function render() {
  ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
  ctx.save();
  ctx.globalAlpha = .97;
  ctx.globalCompositeOperation = "source-out";
  ctx.translate(ctx.canvas.width / 2, ctx.canvas.height / 2);
  ctx.scale(1.001, 1.001);
  ctx.rotate(0.003);
  ctx.translate(-ctx.canvas.width / 2, -ctx.canvas.height / 2);
  ctx.drawImage(ctx2.canvas, 0, 0, ctx.canvas.width, ctx.canvas.height);
  ctx.restore();

  analyser.getByteFrequencyData(audioDataArray);
  
  const width = ctx.canvas.width;
  const height = ctx.canvas.height;

  spots.forEach((spot, n) => {
    const ndx = n * numPoints / numSpots | 0;
    const audioValue = audioDataArray[ndx] / 255;
    const sat = Math.pow(audioValue, 2) * 100;
    
    spot.velocity = audioValue * 0.02;
    spot.direction = (spot.direction + 1 + rnd(-.01, 0.01)) % 1;
    const angle = spot.direction * Math.PI * 2;
    spot.x = (spot.x + Math.cos(angle) * spot.velocity + 1) % 1; 
    spot.y = (spot.y + Math.sin(angle) * spot.velocity + 1) % 1;
    
    ctx.fillStyle = "hsl(" + spot.hue + "," + sat + "%,50%)";
    ctx.beginPath();
    ctx.arc(spot.x * width, spot.y * height, 50 * audioValue, 0, Math.PI * 2, false);
    ctx.fill();
  });
  
  var temp = ctx;
  ctx = ctx2;
  ctx2 = temp;
  
  requestAnimationFrame(render);
}
requestAnimationFrame(render);


var 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
audio.crossOrigin = "anonymous";

audio.addEventListener('canplay', handleCanplay);
audio.loop = true;
audio.src = "https://twgljs.org/examples/sounds/DOCTOR%20VOX%20-%20Level%20Up.mp3";
audio.load();


function handleCanplay() {
  const source = context.createMediaElementSource(audio);
  source.connect(analyser);
  analyser.connect(context.destination);
}
canvas { border: 1px solid black; display: block; }
<canvas></canvas>

音乐:DOCTOR VOX - Level Up