【问题标题】:Why is my program running in atom-html-preview and atom-live-server inside Atom but not in Chrome nor in JSFiddle?为什么我的程序在 Atom 内的 atom-html-preview 和 atom-live-server 中运行,但不在 Chrome 或 JSFiddle 中?
【发布时间】:2021-03-20 20:52:00
【问题描述】:

我有一个程序使用 Web Audio API 来可视化音频的时域波形。它在我使用“harmsk”的“atom-html-preview”包的 Atom 中运行良好,但它不能在 Chrome 或 JSFiddle 中运行。

我做错了什么?是语法错误还是我使用了过时的函数?

编辑:它也适用于“jas-chen”的“atom-live-server”

在 Atom 中,输出类似于 this

let frequencyArray = [];
let analyser;
let request;
var flag=0;
var height=0;

const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");
const bars = Math.round(canvas.width);
const lineWidth = 3;


var centerX = canvas.width / 2;
var centerY = canvas.height / 2;


const audio = new Audio();
audio.src =
  "https://s3.us-west-2.amazonaws.com/storycreator.uploads/ck9kpb5ss0xf90132mgf8z893?client_id=d8976b195733c213f3ead34a2d95d1c1";
audio.crossOrigin = "anonymous";
audio.load();

const context = new (window.AudioContext || window.webkitAudioContext)();
analyser = context.createAnalyser();
const source = context.createMediaElementSource(audio);

source.connect(analyser);
analyser.connect(context.destination);

frequencyArray = new Uint8Array(analyser.frequencyBinCount);


  function begin()
  {
    audio.play();
    requestAnimationFrame(drawCanvas);
  };

  function end()
  {
    cancelAnimationFrame(request);
    audio.pause();
  };

audio.addEventListener("ended", close);

function close()
{
  if(flag==0)
  {
    flag=1;
  }
  else
  {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      flag=0;
  }
}


  const drawCanvas = () => {

      ctx.clearRect(0, 0, canvas.width, canvas.height);
      analyser.getByteTimeDomainData(frequencyArray);

      for (var i = 0; i < bars; i+=5) {
       height = frequencyArray[i] * 0.25;

        drawLine(
          {
            i,
            bars,
            height
          },
          canvas,
          ctx
        );
      }

      if(flag==0)
      {
      request = requestAnimationFrame(drawCanvas);
      }
      else
      {
        flag=2;
        close();
      }
  };

  
  const drawLine = (opts, canvas, ctx) => {
    const { i, bars, height } = opts;

    // draw the bar
    ctx.strokeStyle = "#212121";
    ctx.lineWidth = lineWidth;
    ctx.lineCap = "round";
    ctx.beginPath();
    ctx.moveTo(i, centerY);
    ctx.lineTo(i, centerY + height);
    ctx.stroke();

    ctx.beginPath();
    ctx.moveTo(i, centerY);
    ctx.lineTo(i, centerY - height);
    ctx.stroke();


};
<!DOCTYPE html>
<html>
<head>

<body>

<button onClick=begin()>Start</button>
<button onClick=end()>End</button>
<canvas id="myCanvas" width="500" height="200" style="border:1px solid #d3d3d3;">
</canvas>


</body>
</html>

【问题讨论】:

  • 您可以为此创建一个 JSfiddle 以便更轻松地检查正在发生的事情吗?
  • @RaymondToy 它就在那里。尝试打开整个页面。

标签: javascript html atom-editor web-audio-api


【解决方案1】:

我认为是因为这个错误,在控制台中

js:47 AudioContext 不允许启动。它必须在页面上的用户手势之后恢复(或创建)。

如果您在消息中引用link,它会指定

如果您在页面加载时创建 AudioContext,则必须在用户与页面交互后的某个时间调用 resume()(例如,用户单击按钮)。或者,如果在任何附加节点上调用 start(),AudioContext 将在用户手势后恢复。

由于您的AudioContext 是在用户手势(点击)之前创建的,您可以修改begin 函数以恢复上下文,

  function begin()
  {
    context.resume().then(() => {
          audio.play();
          requestAnimationFrame(drawCanvas);
    });
  };

工作演示

let frequencyArray = [];
let analyser;
let request;
var flag=0;
var height=0;

const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");
const bars = Math.round(canvas.width);
const lineWidth = 3;


var centerX = canvas.width / 2;
var centerY = canvas.height / 2;


const audio = new Audio();
audio.src =
  "https://s3.us-west-2.amazonaws.com/storycreator.uploads/ck9kpb5ss0xf90132mgf8z893?client_id=d8976b195733c213f3ead34a2d95d1c1";
audio.crossOrigin = "anonymous";
audio.load();

const context = new (window.AudioContext || window.webkitAudioContext)();
analyser = context.createAnalyser();
const source = context.createMediaElementSource(audio);

source.connect(analyser);
analyser.connect(context.destination);

frequencyArray = new Uint8Array(analyser.frequencyBinCount);


  function begin()
  {
    context.resume().then(() => {
     audio.play();
     requestAnimationFrame(drawCanvas);
    })
  };

  function end()
  {
    cancelAnimationFrame(request);
    audio.pause();
  };

audio.addEventListener("ended", close);

function close()
{
  if(flag==0)
  {
    flag=1;
  }
  else
  {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      flag=0;
  }
}


  const drawCanvas = () => {

      ctx.clearRect(0, 0, canvas.width, canvas.height);
      analyser.getByteTimeDomainData(frequencyArray);

      for (var i = 0; i < bars; i+=5) {
       height = frequencyArray[i] * 0.25;

        drawLine(
          {
            i,
            bars,
            height
          },
          canvas,
          ctx
        );
      }

      if(flag==0)
      {
      request = requestAnimationFrame(drawCanvas);
      }
      else
      {
        flag=2;
        close();
      }
  };

  
  const drawLine = (opts, canvas, ctx) => {
    const { i, bars, height } = opts;

    // draw the bar
    ctx.strokeStyle = "#212121";
    ctx.lineWidth = lineWidth;
    ctx.lineCap = "round";
    ctx.beginPath();
    ctx.moveTo(i, centerY);
    ctx.lineTo(i, centerY + height);
    ctx.stroke();

    ctx.beginPath();
    ctx.moveTo(i, centerY);
    ctx.lineTo(i, centerY - height);
    ctx.stroke();


};
<!DOCTYPE html>
<html>
<head>

<body>

<button onClick=begin()>Start</button>
<button onClick=end()>End</button>
<canvas id="myCanvas" width="500" height="200" style="border:1px solid #d3d3d3;">
</canvas>


</body>
</html>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-20
    • 1970-01-01
    相关资源
    最近更新 更多