问题
I have an audio element on a webpage and I need to add an id tag "player" to the element. I am using getElementById("player").
The element in quesiton:
<audio id="player" controls loop>
<source src="Out_of_the_Skies_Under_the_Earth.mp3" type="audio/mp3">
</audio>
I am using the 'player' tag to make the next two lines useful, using the Web Audio API:
var mediaElement = document.getElementById('player');
var sourceNode = context.createMediaElementSource(mediaElement);
This is the only place I am using the id 'player,' and I am open to any alternatives.
When I add the id tag the audio does not play in Chrome (it will play without the tag). It will play fine in Safari and Opera but not Chrome. I have tried bouncing the file to a smaller bit/sample rate, using .ogg, using getElementByClassName instead, but nothing seems to be working.
EDIT: Also, I'd like to note that the player does show the correct length of the audio file (6:03) and it shows the progress bar moving and the time updating correctly. It's just as if the sound is muted.
This snippet isn't necessarily the exact problem I was having since my audio file is local.
Since posting this I have noticed that I get the error: 'MediaElementAudioSource outputs zeroes due to CORS access restrictions for [local file]' I think that hosting the file under my own domain with the required CORS header might fix the issue. I don't have time to implement this right now but I will update the post my solution in the answers below.
But in the mean time, any suggestions would be great.
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>
回答1:
The URL set at <source>
element src
attribute is not served with CORS headers and is not an .mp3
file.
To avoid
MediaElementAudioSource outputs zeroes due to CORS access restrictions for <URL>
error, you can use fetch()
, Body.blob()
to fetch a resource which is served with Access-Control-Allow-Origin
header, URL.createObjectURL()
to convert the Blob
to a Blob URL
, then set the <audio>
element src
to the Blob URL
.
Note also that <input>
tag is self-closing; and filters
should be defined globally.
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>
来源:https://stackoverflow.com/questions/48370887/id-tag-causes-audio-to-not-play-in-chrome