如何在HTML中为音频文件/标签创建移动波形? 单击播放按钮时,必须播放音频HTML元素,并生成相应的移动波形....如何实现?
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title id='title'>HTML Page setup Tutorial</title>
<script src='riffwave.js'></script>
<script type="text/javascript">
function myFunction()
{
var data = []; // just an array
for (var i=0; i<10000; i++) data[i] = /*Math.round(255 * Math.random())*/i; // fill data with random samples
var wave = new RIFFWAVE(data); // create the wave file
var audio = new Audio(wave.dataURI); // create the HTML5 audio element
audio.play();
}
</script>
</head>
<body>
<button type="button" onclick="myFunction()">Click Me!</button>
</body>
</html>
这样的波形
答案 0 :(得分:7)
与下面相同,但随后是canvasjs:
演示:http://seapip.com/canvas/visualizer4/
/*
Speed has to be bigger then refresh!!!
*/
//Speed to move from right to left, also the visible amount of time on the x axis (in milliseconds)
var speed = 10000;
//Time in milliseconds to redraw chart
var refresh = 30;
//Without var to make it a global variable accessable by the html onclick attribute
audioElement = document.getElementById('audioElement');
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
var audioSrc = audioCtx.createMediaElementSource(audioElement);
var analyser = audioCtx.createAnalyser();
// Bind our analyser to the media element source.
audioSrc.connect(analyser);
audioSrc.connect(audioCtx.destination);
//Get frequency data
var frequencyData = new Uint8Array(analyser.frequencyBinCount);
//The animation reference
var animation;
//Create chart
var dps = []; // dataPoints
var chart = new CanvasJS.Chart("chart", {
interactivityEnabled: false,
width: 500,
height: 200,
axisX: {
title: "Time",
valueFormatString: "mm:ss"
},
axisY: {
title: "dB"
},
data: [{
type: "line",
dataPoints: dps
}]
});
chart.render();
//On play
audioElement.onplay = function() {
//Start drawing
animation = setInterval(function() {
drawWave();
}, refresh);
};
//On pause
audioElement.onpause = function() {
//Stop drawing
clearInterval(animation);
};
//On ended
audioElement.onended = function() {
//Stop drawing
clearInterval(animation);
//Reset time
time = 0;
//Reset dataPoints
dps = [];
//Prevent audio from looping (you can remove this if you want it to loop)
audioElement.pause();
};
//Max dB
var max = analyser.maxDecibels;
//Min dB
var min = analyser.minDecibels;
//Time
var time = 0;
//Our drawing method
function drawWave() {
// Copy frequency data to frequencyData array.
analyser.getByteFrequencyData(frequencyData);
//Total loudness of all frequencies in frequencyData
var totalLoudness = 0;
for(var i = 0; i < frequencyData.length; i++) {
totalLoudness += frequencyData[i];
}
//Average loudness of all frequencies in frequencyData on scale from 0 to 255
var averageLoudness = totalLoudness / frequencyData.length / 255;
//Decibels
var decibels = min + averageLoudness * Math.abs(min - max);
//Increase time
time += refresh;
//Add to chart
dps.push({
x: new Date(time),
y: decibels
});
//Maximum x values to draw based on speed ad refresh
if(dps.length > speed / refresh) {
dps.shift();
}
//Draw new chart
chart.render();
}
<audio id="audioElement" src="audio/Odesza - Above The Middle.mp3"></audio>
<div id="chart"></div>
<div>
<button onclick="audioElement.play()">Play the Audio</button>
<button onclick="audioElement.pause()">Pause the Audio</button>
<button onclick="audioElement.volume+=0.1">Increase Volume</button>
<button onclick="audioElement.volume-=0.1">Decrease Volume</button>
</div>
请记住,#chart是一个div而不是一个canvas元素,我花了几分钟才找出图表最初没有显示的原因:P
与下面相同,但是从右到左绘图。 stepSize变量设置动画速度和步长大小,如果你想要绘制更大的步骤,那么它需要更快地移动,如果你想要绘制更小的步骤,它需要移动得更慢。
演示:http://seapip.com/canvas/visualizer3
//Step size (pixels per 20ms)
var stepSize = 0.5;
//Without var to make it a global variable accessable by the html onclick attribute
audioElement = document.getElementById('audioElement');
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
var audioSrc = audioCtx.createMediaElementSource(audioElement);
var analyser = audioCtx.createAnalyser();
// Bind our analyser to the media element source.
audioSrc.connect(analyser);
audioSrc.connect(audioCtx.destination);
//Get frequency data (800 = max frequency)
var frequencyData = new Uint8Array(400);
//Use below to show all frequencies
//var frequencyData = new Uint8Array(analyser.frequencyBinCount);
//Create canvas
var canvas = document.getElementById("wave");
canvas.style.width = "500px";
canvas.style.height = "100px";
//High dpi stuff
canvas.width = parseInt(canvas.style.width) * 2;
canvas.height = parseInt(canvas.style.height) * 2;
//Get canvas context
var ctx = canvas.getContext("2d");
//Stroke color
ctx.strokeStyle = "#ffff00";
//Draw thicker lines due to high dpi scaling
ctx.lineWidth = 2;
//Store y values
var drawY = [canvas.height];
//The animation reference
var animation;
//On play
audioElement.onplay = function() {
//Start drawing
animation = setInterval(function() {
drawWave();
}, 20);
};
//On pause
audioElement.onpause = function() {
//Stop drawing
clearInterval(animation);
};
//On ended
audioElement.onended = function() {
//Stop drawing
clearInterval(animation);
//Clear previous y values
drawY = [canvas.height];
//Prevent audio from looping (you can remove this if you want it to loop)
audioElement.pause();
};
//Our drawing method
function drawWave() {
// Copy frequency data to frequencyData array.
analyser.getByteFrequencyData(frequencyData);
//Total loudness of all frequencies in frequencyData
var totalLoudness = 0;
for(var i = 0; i < frequencyData.length; i++) {
totalLoudness += frequencyData[i];
}
//Average loudness of all frequencies in frequencyData
var averageLoudness = totalLoudness / frequencyData.length;
//Scale of average loudness from (0 to 1), frequency loudness scale is (0 to 255)
var y = averageLoudness / 255;
//Multiply with canvas height to get scale from (0 to canvas height)
y *= canvas.height;
//Since a canvas y axis is inverted from a normal y axis we have to flip it to get a normal y axis value
y = canvas.height - y;
//Store new y value
drawY.push(y);
//Clear previous drawing
ctx.clearRect(0, 0, canvas.width, canvas.height);
//Draw line
for(var i = drawY.length; i > 0; i--) {
//calculate x values
var x1 = canvas.width - (drawY.length - i - 1) * stepSize;
var x2 = canvas.width - (drawY.length - i) * stepSize;
//Stop drawing y values if the x value is outside the canvas
if(!x2) {
break;
}
ctx.beginPath();
ctx.moveTo(x1, drawY[i - 1]);
ctx.lineTo(x2, drawY[i]);
ctx.stroke();
}
}
<audio id="audioElement" src="audio/Odesza - Above The Middle.mp3"></audio>
<canvas id="wave"></canvas>
<div>
<button onclick="audioElement.play()">Play the Audio</button>
<button onclick="audioElement.pause()">Pause the Audio</button>
<button onclick="audioElement.volume+=0.1">Increase Volume</button>
<button onclick="audioElement.volume-=0.1">Decrease Volume</button>
</div>
这是我认为你可能想要的,x轴是时间,y轴是所有频率的平均响度。请注意,Chrome之类的浏览器不能在后台标签中正确绘制图形,因为它会限制刷新间隔和音频分析器输出。
演示:http://seapip.com/canvas/visualizer2
//Without var to make it a global variable accessable by the html onclick attribute
audioElement = document.getElementById('audioElement');
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
var audioSrc = audioCtx.createMediaElementSource(audioElement);
var analyser = audioCtx.createAnalyser();
// Bind our analyser to the media element source.
audioSrc.connect(analyser);
audioSrc.connect(audioCtx.destination);
//Get frequency data (800 = max frequency)
var frequencyData = new Uint8Array(400);
//Use below to show all frequencies
//var frequencyData = new Uint8Array(analyser.frequencyBinCount);
//Create canvas
var canvas = document.getElementById("wave");
canvas.style.width = "1000px";
canvas.style.height = "100px";
//High dpi stuff
canvas.width = parseInt(canvas.style.width) * 2;
canvas.height = parseInt(canvas.style.height) * 2;
//Get canvas context
var ctx = canvas.getContext("2d");
//Set stroke color to yellow
ctx.strokeStyle = "#ffff00";
//Draw twice as thick lines due to high dpi scaling
ctx.lineWidth = 2;
//Save x and y from the previous drawing
var drawX = 0;
var drawY = 0;
//Total duration (Seconds)
var duration;
//The animation reference
var animation;
//Audio is loaded
audioElement.oncanplaythrough = function() {
//Get duration
duration = audioElement.duration;
//On play
audioElement.onplay = function() {
//Start drawing
drawWave();
};
//On pause
audioElement.onpause = function() {
//Stop drawing
cancelAnimationFrame(animation);
};
//On ended
audioElement.onended = function() {
//Stop drawing
cancelAnimationFrame(animation);
//Clear previous drawing
ctx.clearRect(0, 0, canvas.width, canvas.height);
//Clear previous x and y values
drawX = 0;
drawY = 0;
//Prevent audio from looping (you can remove this if you want it to loop)
audioElement.pause();
};
};
//Our drawing method
function drawWave() {
//Current time (seconds)
var currentTime = audioElement.currentTime;
// Copy frequency data to frequencyData array.
analyser.getByteFrequencyData(frequencyData);
//Total loudness of all frequencies in frequencyData
var totalLoudness = 0;
for(var i = 0; i < frequencyData.length; i++) {
totalLoudness += frequencyData[i];
}
//Average loudness of all frequencies in frequencyData
var averageLoudness = totalLoudness / frequencyData.length;
//Get the previous x axis value
var previousDrawX = drawX;
//Scale of progress in song (from 0 to 1)
drawX = currentTime / duration;
//Multiply with canvas width to get x axis value
drawX *= canvas.width;
//Get the previous y axis value
var previousDrawY = drawY;
//Scale of average loudness from (0 to 1), frequency loudness scale is (0 to 255)
drawY = averageLoudness / 255;
//Multiply with canvas height to get scale from (0 to canvas height)
drawY *= canvas.height;
//Since a canvas y axis is inverted from a normal y axis we have to flip it to get a normal y axis value
drawY = canvas.height - drawY;
//Draw line
ctx.beginPath();
ctx.moveTo(previousDrawX, previousDrawY);
ctx.lineTo(drawX, drawY);
ctx.stroke();
//Animate
animation = requestAnimationFrame(drawWave);
}
<audio id="audioElement" src="audio/Odesza - Above The Middle.mp3"></audio>
<canvas id="wave"></canvas>
<div>
<button onclick="audioElement.play()">Play the Audio</button>
<button onclick="audioElement.pause()">Pause the Audio</button>
<button onclick="audioElement.volume+=0.1">Increase Volume</button>
<button onclick="audioElement.volume-=0.1">Decrease Volume</button>
</div>
Canvas visualizer示例
演示:http://seapip.com/canvas/visualizer/
//Without var to make it a global variable accessable by the html onclick attribute
audioElement = document.getElementById('audioElement');
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
var audioSrc = audioCtx.createMediaElementSource(audioElement);
var analyser = audioCtx.createAnalyser();
// Bind our analyser to the media element source.
audioSrc.connect(analyser);
audioSrc.connect(audioCtx.destination);
//Get frequency data (400 = max frequency)
var frequencyData = new Uint8Array(400);
//Use below to show all frequencies
//var frequencyData = new Uint8Array(analyser.frequencyBinCount);
//Create canvas
var canvas = document.getElementById("wave");
canvas.style.width = "500px";
canvas.style.height = "100px";
//High dpi stuff
canvas.width = parseInt(canvas.style.width) * 2;
canvas.height = parseInt(canvas.style.height) * 2;
//Get canvas context
var ctx = canvas.getContext("2d");
//Set stroke color
ctx.strokeStyle = "#ffff00"
//Draw twice as thick lines due to high dpi scaling
ctx.lineWidth = 2;
//Animation reference
var animation;
//On play
audioElement.onplay = funtion() {
drawWave();
};
//On pause
audioElement.onpause = funtion() {
cancelAnimationFrame(animation);
};
//On ended
audioElement.onended = funtion() {
cancelAnimationFrame(animation);
};
//Our drawing method
function drawWave() {
// Copy frequency data to frequencyData array.
analyser.getByteFrequencyData(frequencyData);
//Draw the wave
ctx.clearRect(0, 0, canvas.width, canvas.height);
for(var i = 1; i < frequencyData.length; i++) {
var x1 = canvas.width / (frequencyData.length - 1) * (i - 1);
var x2 = canvas.width / (frequencyData.length - 1) * i;
var y1 = canvas.height - frequencyData[i - 1] / 255 * canvas.height;
var y2 = canvas.height - frequencyData[i] / 255 * canvas.height;
if(x1 && y1 && x2 && y2) {
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.stroke();
}
}
//Animate
animation = requestAnimationFrame(drawWave);
}
<audio id="audioElement" src="audio/Odesza - Above The Middle.mp3"></audio>
<canvas id="wave"></canvas>
<div>
<button onclick="document.getElementById('audioElement').play()">Play the Audio</button>
<button onclick="document.getElementById('audioElement').pause()">Pause the Audio</button>
<button onclick="document.getElementById('audioElement').volume+=0.1">Increase Volume</button>
<button onclick="document.getElementById('audioElement').volume-=0.1">Decrease Volume</button>
</div>
关于音频可视化的插件和教程:
https://www.bignerdranch.com/blog/music-visualization-with-d3-js/
https://github.com/wayou/HTML5_Audio_Visualizer
https://www.patrick-wied.at/blog/how-to-create-audio-visualizations-with-javascript-html
https://p5js.org/examples/examples/Sound_Frequency_Spectrum.php