Reputation: 31
I am trying to use an audio visualisation for the stream of my online radio using the example that I found on this page. However, similar to the problem found in this post , my audio file (even when testing with a local file) just does not sound and of course the visualisation does nothing as well.
My HTML is the following:
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<audio src="http://50.22.218.101:38838/;steam.mp3" id="audio"
controls>HTML5 Audio element not supported</audio>
<canvas id="canvas" width="800" height="350"></canvas>
<script src="main.js"></script>
</body>
</html>
This is "main.js":
window.AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext;
window.onload = function() {
var audio = document.getElementById('audio');
var ctx = new AudioContext();
var analyser = ctx.createAnalyser();
var audioSrc = ctx.createMediaElementSource(audio);
// we have to connect the MediaElementSource with the analyser
audioSrc.connect(analyser);
analyser.connect(ctx.destination);
// we could configure the analyser: e.g. analyser.fftSize (for further infos read the spec)
// analyser.fftSize = 64;
// frequencyBinCount tells you how many values you'll receive from the analyser
var frequencyData = new Uint8Array(analyser.frequencyBinCount);
// we're ready to receive some data!
var canvas = document.getElementById('canvas'),
cwidth = canvas.width,
cheight = canvas.height - 2,
meterWidth = 10, //width of the meters in the spectrum
gap = 2, //gap between meters
capHeight = 2,
capStyle = '#fff',
meterNum = 800 / (10 + 2), //count of the meters
capYPositionArray = []; ////store the vertical position of hte caps for the preivous frame
ctx = canvas.getContext('2d'),
gradient = ctx.createLinearGradient(0, 0, 0, 300);
gradient.addColorStop(1, '#0f0');
gradient.addColorStop(0.5, '#ff0');
gradient.addColorStop(0, '#f00');
// loop
function renderFrame() {
var array = new Uint8Array(analyser.frequencyBinCount);
analyser.getByteFrequencyData(array);
var step = Math.round(array.length / meterNum); //sample limited data from the total array
ctx.clearRect(0, 0, cwidth, cheight);
for (var i = 0; i < meterNum; i++) {
var value = array[i * step];
if (capYPositionArray.length < Math.round(meterNum)) {
capYPositionArray.push(value);
};
ctx.fillStyle = capStyle;
//draw the cap, with transition effect
if (value < capYPositionArray[i]) {
ctx.fillRect(i * 12, cheight - (--capYPositionArray[i]), meterWidth, capHeight);
} else {
ctx.fillRect(i * 12, cheight - value, meterWidth, capHeight);
capYPositionArray[i] = value;
};
ctx.fillStyle = gradient; //set the filllStyle to gradient for a better look
ctx.fillRect(i * 12 /*meterWidth+gap*/ , cheight - value + capHeight, meterWidth, cheight); //the meter
}
requestAnimationFrame(renderFrame);
}
renderFrame();
audio.play();
};
Any idea what am I doing wrong?
Upvotes: 3
Views: 3633
Reputation: 404
Here's a full example, combining @miknik's answer, your display code (which is awesome by the way), and a public web radio station
window.AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext;
let audio = document.getElementById('audio')
let ctx = ""
let audioSrc = ""
function start(){
if (!ctx){
ctx = new AudioContext();
analyser = ctx.createAnalyser();
audioSrc = ctx.createMediaElementSource(audio)
// we have to connect the MediaElementSource with the analyser
audioSrc.connect(analyser)
analyser.connect(ctx.destination)
}
// we could configure the analyser: e.g. analyser.fftSize (for further infos read the spec)
// analyser.fftSize = 64;
// frequencyBinCount tells you how many values you'll receive from the analyser
var frequencyData = new Uint8Array(analyser.frequencyBinCount);
// we're ready to receive some data!
var canvas = document.getElementById('canvas'),
cwidth = canvas.width,
cheight = canvas.height - 2,
meterWidth = 10, //width of the meters in the spectrum
gap = 2, //gap between meters
capHeight = 2,
capStyle = '#fff',
meterNum = 800 / (10 + 2), //count of the meters
capYPositionArray = []; ////store the vertical position of hte caps for the preivous frame
ctx = canvas.getContext('2d'),
gradient = ctx.createLinearGradient(0, 0, 0, 300);
gradient.addColorStop(1, '#0f0');
gradient.addColorStop(0.5, '#ff0');
gradient.addColorStop(0, '#f00');
// loop
function renderFrame() {
var array = new Uint8Array(analyser.frequencyBinCount);
analyser.getByteFrequencyData(array);
var step = Math.round(array.length / meterNum); //sample limited data from the total array
ctx.clearRect(0, 0, cwidth, cheight);
for (var i = 0; i < meterNum; i++) {
var value = array[i * step];
if (capYPositionArray.length < Math.round(meterNum)) {
capYPositionArray.push(value);
};
ctx.fillStyle = capStyle;
//draw the cap, with transition effect
if (value < capYPositionArray[i]) {
ctx.fillRect(i * 12, cheight - (--capYPositionArray[i]), meterWidth, capHeight);
} else {
ctx.fillRect(i * 12, cheight - value, meterWidth, capHeight);
capYPositionArray[i] = value;
};
ctx.fillStyle = gradient; //set the filllStyle to gradient for a better look
ctx.fillRect(i * 12 /*meterWidth+gap*/ , cheight - value + capHeight, meterWidth, cheight); //the meter
}
requestAnimationFrame(renderFrame);
}
renderFrame();
audio.play();
}
function stop(){
audio.pause()
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
#container {
position: absolute;
top: 0;
left: 0;
background: #000;
width: 100%;
height: 100%;
}
#canvas {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: black;
z-index: -1;
opacity: .8;
}
.button-container{
padding-top: 5px;
display: grid;
grid-template-columns: repeat(2,300px);
grid-gap: 1px;
width: 100%;
align-items: center;
justify-content: center;
}
button{
width: 300px;
text-align: center;
}
<html>
<link rel="stylesheet" type="text/css" href="style.css">
<body>
<audio src="https://streaming.witr.rit.edu/live-aac-96" crossorigin="anonymous" id="audio" >HTML5 Audio element not supported</audio>
<div class="button-container">
<button onclick="start()">Stream Radio</button>
<button onclick="stop()">Stop Radio</button>
</div>
<canvas id="canvas"></canvas>
<script src="main.js"></script>
</body>
</html>
Upvotes: 1
Reputation: 5951
You can usually fix this by simply adding a crossorigin option to your html audio tag
so this:
<audio src="http://50.22.218.101:38838/;steam.mp3" id="audio" controls>
becomes this:
<audio src="http://50.22.218.101:38838/;steam.mp3" crossorigin="anonymous" id="audio" controls>
Upvotes: 2