【问题标题】:Id tag causes audio to not play in chromeId 标签导致音频无法在 chrome 中播放
【发布时间】:2018-06-30 10:52:12
【问题描述】:

我在网页上有一个音频元素,我需要向该元素添加一个 id 标签“播放器”。我正在使用 getElementById("player")。

问题中的元素:

<audio id="player" controls loop>
     <source src="Out_of_the_Skies_Under_the_Earth.mp3" type="audio/mp3">
</audio>

我正在使用“播放器”标签来使接下来的两行有用,使用 Web 音频 API:

var mediaElement = document.getElementById('player');
var sourceNode = context.createMediaElementSource(mediaElement);

这是我唯一使用 id 'player' 的地方,我愿意接受任何替代方案。

当我添加 id 标签时,音频不会在 Chrome 中播放(它会在没有标签的情况下播放)。它可以在 Safari 和 Opera 中正常播放,但不能在 Chrome 中播放。我尝试使用 .ogg 将文件反弹到较小的位/采样率,使用 getElementByClassName 代替,但似乎没有任何效果。

编辑: 另外,我想指出,播放器确实显示了正确的音频文件长度(6:03),它显示了进度条的移动和正确更新的时间。就好像声音被静音了一样。

这个 sn-p 不一定是我遇到的确切问题,因为我的音频文件是本地的。

自从发布此消息后,我注意到我收到错误消息:“MediaElementAudioSource 由于 [本地文件] 的 CORS 访问限制而输出零”我认为使用所需的 CORS 标头在我自己的域下托管文件可能会修复问题。我现在没有时间实施这个,但我会在下面的答案中更新我的解决方案。

但与此同时,任何建议都会很棒。

var ctx = window.AudioContext || window.webkitAudioContext;
var context = new ctx();

var mediaElement = document.getElementById('player');
var sourceNode = context.createMediaElementSource(mediaElement);

// create the equalizer. It's a set of biquad Filters

var filters = [];

    // Set filters
    [60, 170, 350, 1000, 3500, 10000].forEach(function(freq, i) {
      var eq = context.createBiquadFilter();
      eq.frequency.value = freq;
      eq.type = "peaking";
      eq.gain.value = 0;
      filters.push(eq);
    });

 // Connect filters in serie
   sourceNode.connect(filters[0]);
   for(var i = 0; i < filters.length - 1; i++) {
      filters[i].connect(filters[i+1]);
    }

// connect the last filter to the speakers
filters[filters.length - 1].connect(context.destination);

function changeGain(sliderVal,nbFilter) {
  var value = parseFloat(sliderVal);
  filters[nbFilter].gain.value = value;

  // update output labels
  var output = document.querySelector("#gain"+nbFilter);
  output.value = value + " dB";
}
div audio {
  display: block;
  margin-bottom:10px;
}

.eq {
  margin: 32px;
  border:1px solid;
  border-radius:15px;
  background-color:lightGrey;
  padding:10px;
  width:300px;
  box-shadow: 10px 10px 5px grey;
  text-align:center;
  font-family: "Open Sans";
  font-size: 12px;
}


div.controls:hover {
  color:blue;
  font-weight:bold;
}
div.controls label {
  display: inline-block;
  text-align: center;
  width: 50px;
}

div.controls label, div.controls input, output {
    vertical-align: middle;
    padding: 0;
    margin: 0;
   font-family: "Open Sans",Verdana,Geneva,sans-serif,sans-serif;
  font-size: 12px;
}
<!DOCTYPE html>
<html lang="en" >

<head>
  <meta charset="UTF-8">
  <title>Equalizer with Bi-Quad Filters</title>



      <link rel="stylesheet" href="css/style.css">


</head>

<body>

  <html lang="en">
  <head>
  </head>
<body>

<div class="eq">
  <audio id="player" controls crossorigin="anonymous" loop>
  <source src="https://vocaroo.com/i/s1lfs67BmoTC">

</audio>
  <div class="controls">
    <label>60Hz</label>
    <input type="range" value="0" step="1" min="-30" max="30" oninput="changeGain(this.value, 0);"></input>
  <output id="gain0">0 dB</output>
  </div>
  <div class="controls">
    <label>170Hz</label>
    <input type="range" value="0" step="1" min="-30" max="30" oninput="changeGain(this.value, 1);"></input>
<output id="gain1">0 dB</output>
  </div>
  <div class="controls">
    <label>350Hz</label>
    <input type="range" value="0" step="1" min="-30" max="30" oninput="changeGain(this.value, 2);"></input>
<output id="gain2">0 dB</output>
  </div>
  <div class="controls">
    <label>1000Hz</label>
    <input type="range" value="0" step="1" min="-30" max="30" oninput="changeGain(this.value, 3);"></input>
<output id="gain3">0 dB</output>
  </div>
  <div class="controls">
    <label>3500Hz</label>
    <input type="range" value="0" step="1" min="-30" max="30" oninput="changeGain(this.value, 4);"></input>
<output id="gain4">0 dB</output>
  </div>
  <div class="controls">
    <label>10000Hz</label>
    <input type="range" value="0" step="1" min="-30" max="30" oninput="changeGain(this.value, 5);"></input>
<output id="gain5">0 dB</output>
  </div>
</div>
</body>
</html>



    <script  src="js/index.js"></script>




</body>

</html>

【问题讨论】:

  • console 是否记录了任何 CORS 访问限制错误?
  • 有,我刚刚更新了帖子

标签: javascript html google-chrome audio web-audio-api


【解决方案1】:

&lt;source&gt; 元素 src 属性处设置的 URL 不与 CORS 标头一起提供,并且不是 .mp3 文件。

避免

MediaElementAudioSource outputs zeroes due to CORS access restrictions for <URL>

错误,您可以使用fetch()Body.blob() 获取带有Access-Control-Allow-Origin 标头的资源,URL.createObjectURL()Blob 转换为Blob URL,然后设置&lt;audio&gt; 元素srcBlob URL

还要注意&lt;input&gt; 标签是自动关闭的;和filters 应该在全局范围内定义。

var ctx = window.AudioContext || window.webkitAudioContext;
var context = new ctx();
var url = "https://ia600305.us.archive.org/30/items/return_201605/return.mp3";

var filters = [];

fetch(url)
  .then(response => response.blob())
  .then(blob => {
    var blobURL = URL.createObjectURL(blob);
    var mediaElement = document.getElementById('player');
    mediaElement.src = blobURL;
    var sourceNode = context.createMediaElementSource(mediaElement);

    // create the equalizer. It's a set of biquad Filters
    // Set filters
    [60, 170, 350, 1000, 3500, 10000].forEach(function(freq, i) {
      var eq = context.createBiquadFilter();
      eq.frequency.value = freq;
      eq.type = "peaking";
      eq.gain.value = 0;
      filters.push(eq);
    });

    // Connect filters in serie
    sourceNode.connect(filters[0]);
    for (var i = 0; i < filters.length - 1; i++) {
      filters[i].connect(filters[i + 1]);
    }

    // connect the last filter to the speakers
    filters[filters.length - 1].connect(context.destination);

  });

function changeGain(sliderVal, nbFilter) {
  var value = parseFloat(sliderVal);
  filters[nbFilter].gain.value = value;

  // update output labels
  var output = document.querySelector("#gain" + nbFilter);
  output.value = value + " dB";
}
div audio {
  display: block;
  margin-bottom: 10px;
}

.eq {
  margin: 32px;
  border: 1px solid;
  border-radius: 15px;
  background-color: lightGrey;
  padding: 10px;
  width: 300px;
  box-shadow: 10px 10px 5px grey;
  text-align: center;
  font-family: "Open Sans";
  font-size: 12px;
}

div.controls:hover {
  color: blue;
  font-weight: bold;
}

div.controls label {
  display: inline-block;
  text-align: center;
  width: 50px;
}

div.controls label,
div.controls input,
output {
  vertical-align: middle;
  padding: 0;
  margin: 0;
  font-family: "Open Sans", Verdana, Geneva, sans-serif, sans-serif;
  font-size: 12px;
}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Equalizer with Bi-Quad Filters</title>

</head>
<body>

    <div class="eq">
      <audio id="player" controls crossorigin="anonymous" loop></audio>
      <div class="controls">
        <label>60Hz</label>
        <input type="range" value="0" step="1" min="-30" max="30" oninput="changeGain(this.value, 0);">
        <output id="gain0">0 dB</output>
      </div>
      <div class="controls">
        <label>170Hz</label>
        <input type="range" value="0" step="1" min="-30" max="30" oninput="changeGain(this.value, 1);">
        <output id="gain1">0 dB</output>
      </div>
      <div class="controls">
        <label>350Hz</label>
        <input type="range" value="0" step="1" min="-30" max="30" oninput="changeGain(this.value, 2);">
        <output id="gain2">0 dB</output>
      </div>
      <div class="controls">
        <label>1000Hz</label>
        <input type="range" value="0" step="1" min="-30" max="30" oninput="changeGain(this.value, 3);">
        <output id="gain3">0 dB</output>
      </div>
      <div class="controls">
        <label>3500Hz</label>
        <input type="range" value="0" step="1" min="-30" max="30" oninput="changeGain(this.value, 4);">
        <output id="gain4">0 dB</output>
      </div>
      <div class="controls">
        <label>10000Hz</label>
        <input type="range" value="0" step="1" min="-30" max="30" oninput="changeGain(this.value, 5);">
        <output id="gain5">0 dB</output>
      </div>
    </div>
  </body>

  </html>

【讨论】:

  • @AvaD 注意,fetch()URL.createObjectURL() 不是达到预期结果所必需的。该文件需要使用 CORS 标头提供服务,或者使用 --allow-file-access-from-files 标头启动 Chrome 或使用 &lt;input type="file"&gt; 元素在本地测试代码,请参阅 Read local XML with JS
猜你喜欢
  • 2018-03-25
  • 1970-01-01
  • 1970-01-01
  • 2017-09-20
  • 1970-01-01
  • 2011-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多