注意样式不是重点,所有css没有解释
<!DOCTYPE html>
<html class=''>
<head>
<title>music</title>
<meta charset='UTF-8'/>
<style type="text/css">
*{margin: 0;padding: 0; }
html,body {
height: 100%;
width: 100%;
margin-top:5px
}
canvas{
display: block;
}
#list {
background: rgba(146, 186, 226, 0.2);
width: 25%;
height: 600px;
display: block;
float: left;
overflow-y :auto;
overflow-x :auto;
}
img {
height: 10%;
width: 10%;
}
ul {
list-style: none;
margin-left: 8%;
}
.openAndStop{
width: 100px;
height: 20px;
margin-left: 20px;
float: left;
}
.button{
float: none;
}
</style>
<script type="text/javascript">
window.onload = function() {
var canvas = document.getElementById("mycan");//获取canvas
var context = canvas.getContext("2d");//获取绘图环境
var showList = document.getElementById("showList");//获取开始按钮
var displayList = document.getElementById("displayList");//获取停止按钮
var list = document.getElementById("list");//音乐选择按钮(原本是音乐列表后来变按钮,没改变量 名)
var canvasWidth,canvasHeight;//定义变量记录canvas的宽高
canvasWidth = canvas.width;
canvasHeight = canvas.height;
list.width = window.innerWidth*0.25;//初始化选择按钮
list.height = window.innerHeight;
showList.style.display = 'none';//是否显示按钮
showList.onclick = function () {//添加点击事件
canvas.setAttribute("width",window.innerWidth-list.width-5);
canvas.setAttribute("height",window.innerHeight*0.9);
list.style.display = 'block';
this.style.display = 'none';
displayList.style.display = 'block';
};
displayList.onclick = function () {
canvas.setAttribute("width",window.innerWidth-5);
canvas.setAttribute("height",window.innerHeight*0.9);
list.style.display = 'none';
this.style.display = 'none';
showList.style.display = 'block';
};
window.onresize = resizeCanvas();//窗口改变重新计算Canvas大小
function resizeCanvas() {
canvas.setAttribute("width",window.innerWidth-list.width-5);
canvas.setAttribute("height",window.innerHeight*0.9);
canvasWidth = canvas.width;
canvasHeight = canvas.height;
}
resizeCanvas();
//____________________________________________________________________________________
//柱状图颜色
//1. Math.ceil()用作向上取整。 2. Math.floor()用作向下取整。 3. Math.round() 四舍五入取整
var color = context.createLinearGradient(canvas.width*0.5,0,canvas.width*0.5,300);
color.addColorStop(0,"#BE77FF");
color.addColorStop(0.5,"#FF0000");
color.addColorStop(1,"#FF60AF");
//倒影渐变
var colordao = context.createLinearGradient(canvas.width*0.5,300,canvas.width*0.5,600);
colordao.addColorStop(0,"#FFD9EC");
colordao.addColorStop(0.5,"#FFAAD5");
colordao.addColorStop(1,"#FF79BC");
//____________________________________________________________________________
//AudioContext是用于管理和播放所有的声音(以下为兼容写法)
window.AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext || window.msAudioContext;
requestAnimationFrame = (function(){
return window.requestAnimationFrame||
window.webkitRequestAnimationFrame||
window.mozRequestAnimationFrame||
window.msRequestAnimationFrame||
function( callback ){
window.setTimeout(callback, 1000 / 60);
};
})();
var audioContext = new window.AudioContext();
//音频分析器
var analyser;
var audio = document.getElementById("myaudio");
function audioplay() {
initaudio(audio);//初始化音频分析器
draw();//绘制频谱
}
function initaudio(audio) {
analyser = audioContext.createAnalyser();
//analyser.fftSize = 1024;
audioSrc = audioContext.createMediaElementSource(audio);
audioSrc.connect(analyser);
analyser.connect(audioContext.destination);
}
var num = 60;
function draw() {
//Uint8Array 8位无符号整形类型化数组
//analyser.frequencyBinCount 实时得到的音频频域的数据的个数为fftSize的一半
//定义一个Uint8Array数组,大小为analyser.frequencyBinCount
//计算出采样频率44100所需的缓冲区长度
var length=analyser.frequencyBinCount*44100/audioContext.sampleRate|0;
var arr = new Uint8Array(length);
//getByteFrequencyData()复制音频当前的频域数据(数量是frequencyBinCount)到 (8位无符号整形类型化数组)中
analyser.getByteFrequencyData(arr);
//console.log(arr);
//canvas的2D pixi.js库的时候,其动画的刷新都用requestAnimationFrame替代了setTimeout 或 setInterval
//它可以帮你以60fps的帧率绘制动画。
var step = Math.round(arr.length/num);
context.clearRect(0, 0, canvas.width, canvas.height);
context.beginPath();
for (var i = 1; i <= num; i++) {
var value = arr[step*i];
//为画笔设置填充渐变
context.fillStyle = color;
//由画布中间向两边画矩形
context.fillRect(canvas.width*0.5-(i-1)*10, 300,7,(-value)+1);//左边
context.fillRect(i*10 + canvas.width*0.5,300,7,(-value)+1);//右边
context.fill();//fill() 方法填充当前的图像(路径)。默认颜色是黑色
//画倒影
context.fillStyle = colordao;
context.fillRect(canvas.width*0.5-(i-1)*10,300,7,value+1);
context.fillRect(i*10 + canvas.width*0.5,300,7, value+1);
context.fill();
}
requestAnimationFrame(draw);
}
audio.addEventListener("play()",audioplay());//绑定音频播放事件
var audioInput = document.getElementById('uploadedFile');
audioInput.onchange = function() {
if(!audio.paused){
audio.pause();//如果音乐正在播放则停止音乐
}
if (audioInput.files.length !== 0) {
var file = audioInput.files[0];//获取选择的文件
var fileName = file.name;
var fr = new FileReader();
fr.readAsDataURL(file);//以DataURL的方式读取
fr.onload = function(e) {//文件加载完成后处理
var fileResult = e.target.result;
if(audioContext===null){
return;
}
document.getElementById("videoName").innerHTML=fileName;//设置文件名
audio.src = fileResult;//将src设置为刚加载的文件
audio.play();//播放音乐
}
}
};
};
</script>
</head>
<body>
<div id="list" style="">
<div style="text-align:center;width:100%;">
<input type="file" id="uploadedFile" style="margin:0 auto;"/>
</div>
<ul id="vedios">
</ul>
</div>
<div>
<div class="button">
<div class="openAndStop">
<button id="showList">显示目录</button>
<button id="displayList">关闭目录</button>
</div>
</div>
<div id="video">
<div style="float: left;margin-right:5%;">
<audio id="myaudio" crossOrigin="anonymous" name="myaudio" src="" controls="controls"></audio>
</div>
<div id="videoName" style="color: red;height:33px">Baby Don′t Know Why - Ms.Ooja.mp3</div>
<div style="width:70%;height:70%;float: left;"><canvas style="background: rgba(120, 158, 255, 0.55);" id="mycan"></canvas></div>
</div>
</div>
</body>
</html>
效果图: