audiocontext html5,HTML5 getUserMedia/AudioContext 打造音谱图形化

需求是分析音频,用图形化展现。html

1191ab419212bb14966c80eedab5f9f6.png

cba0cd8f1b833d24b269af2c25267cd5.png

7d4ac62bcac2d6cfaf54be41ce95977a.png

思路:git

一、回想当年使用的播放器,如XX静听 通常就2种图形化展现 一个是条形柱 一个是波纹github

二、分析数据转化成图像 这个是canvas经常使用的,以前作过的canvas分析图像数据,作滤镜作变形都是一把好手,这里固然 图形化也交给canvas了。web

三、既然是分析音频,那固然要将音频转化成数据,才能够进行分析,而关于音频的HTML API 就有 audio标签 ,而麦克风访问就有getUserMedia了。什么?你问我咋知道这个api的?我只能告诉你 去查MDN 、W3C 这类网站...canvas

首先咱们要获得音频数据,这里咱们用了2个途径获得,一个是音频流,一个是麦克风api

一、api兼容浏览器

window.AudioContext = (window.AudioContext || window.webkitAudioContext ||window.mozAudioContext);

window.requestAnimationFrame= window.requestAnimationFrame ||window.webkitRequestAnimationFrame;try{

audioCtx= newAudioContext;

console.log('浏览器支持AudioContext');}catch(e) {

console.log('浏览器不支持AudioContext', e);};

二、获得麦克风数据ide

//开始监听

if(navigator.getUserMedia) {

console.log('浏览器支持getUserMedia');

apiMedia.className= "checked";

navigator.getUserMedia(//咱们只获取麦克风数据,这里还能够设置video为true来获取摄像头数据

{

audio:true},

onSccess, onErr)

}else{

console.log('浏览器不支持getUserMedia');

apiMedia.className= "false";

};

经过onSccess来获得数据,介入分析网站

//Success callback

functiononSccess(stream) {//将声音输入对像

source =audioCtx.createMediaStreamSource(stream);

source.connect(analyser);

analyser.connect(distortion);

distortion.connect(biquadFilter);

biquadFilter.connect(convolver);

convolver.connect(gainNode);

gainNode.connect(audioCtx.destination);

visualize();//分析音频

}

一样,文件的也是同样的spa

if (mediaSetting == "file") {

loadFile();//获得数据源

source=audioCtx.createMediaElementSource(audio);//链接节点

source.connect(analyser);

analyser.connect(distortion);

distortion.connect(gainNode);

gainNode.connect(audioCtx.destination);

}

visualize();//分析音频

获得了数据,接下来就交个canvas君吧

//波纹1

if (visualSetting == "wave1") {

analyser.fftSize= 2048;var bufferLength =analyser.fftSize;

console.log(bufferLength);var dataArray = newUint8Array(bufferLength);

canvasCtx.clearRect(0, 0, WIDTH, HEIGHT);

draw= function() {

drawVisual=requestAnimationFrame(draw);

analyser.getByteTimeDomainData(dataArray);

canvasCtx.fillStyle= '#000';

canvasCtx.fillRect(0, 0, WIDTH, HEIGHT);

canvasCtx.lineWidth= 2;

canvasCtx.strokeStyle= '#4aeb46';

canvasCtx.beginPath();var sliceWidth = WIDTH * 1.0 /bufferLength;var x = 0;for (var i = 0; i < bufferLength; i++) {var v = dataArray[i] / 128.0;var y = v * HEIGHT / 2;if (i === 0) {

canvasCtx.moveTo(x, y);

}else{

canvasCtx.lineTo(x, y);

}

x+=sliceWidth;

}

canvasCtx.lineTo(canvas.width, canvas.height/ 2);

canvasCtx.stroke();

};

draw();

}

//circle

else if (visualSetting == "circle") {//analyser.fftSize = 1024;

//var bufferLength = analyser.fftSize;

//var dataArray = new Uint8Array(bufferLength);

analyser.fftSize = 128;var frequencyData = newUint8Array(analyser.frequencyBinCount);var count =analyser.frequencyBinCount;var circles =[];var circleMaxWidth = (HEIGHT*0.66) >> 0;

canvasCtx.clearRect(0, 0, WIDTH, HEIGHT);

canvasCtx.lineWidth= 1;for(var i = 0; i < count; i++){

circles.push(i/count*circleMaxWidth)

}

draw= function() {

canvasCtx.clearRect(0, 0, WIDTH, HEIGHT);

analyser.getByteFrequencyData(frequencyData);

drawVisual=requestAnimationFrame(draw);for(var i = 0; i < circles.length; i++) {var v = frequencyData[i] / 128.0;var y = v * HEIGHT / 2;var circle =circles[i];

canvasCtx.beginPath();

canvasCtx.arc(WIDTH/2,HEIGHT/2, y/2, Math.PI * 2, false);

canvasCtx.stroke()

}

};

draw();

}

//柱形条

else if (visualSetting == "bar") {

analyser.fftSize= 256;var bufferLength =analyser.frequencyBinCount;

console.log(bufferLength);var dataArray = newUint8Array(bufferLength);

canvasCtx.clearRect(0, 0, WIDTH, HEIGHT);var gradient = canvasCtx.createLinearGradient(0, 0, 0, 200);

gradient.addColorStop(1, '#0f0');

gradient.addColorStop(0.5, '#ff0');

gradient.addColorStop(0, '#f00');var barWidth = 10;var gap = 2; //间距

var capHeight = 2;//顶部高度

var capStyle = '#fff';var barNum = WIDTH / (barWidth + gap); //bar个数

var capYPositionArray =[];var step = Math.round(dataArray.length /barNum);

draw= function() {

drawVisual=requestAnimationFrame(draw);

analyser.getByteFrequencyData(dataArray);

canvasCtx.clearRect(0, 0, WIDTH, HEIGHT);for (var i = 0; i < barNum; i++) {var value = dataArray[i *step];if (capYPositionArray.length

capYPositionArray.push(value);

};

canvasCtx.fillStyle=capStyle;//顶端帽子

if (value

canvasCtx.fillRect(i* 12, HEIGHT - (--capYPositionArray[i]), barWidth, capHeight);

}else{

canvasCtx.fillRect(i* 12, HEIGHT -value, barWidth, capHeight);

capYPositionArray[i]=value;

};

canvasCtx.fillStyle= gradient;//渐变

canvasCtx.fillRect(i * 12 , HEIGHT - value + capHeight, barWidth, HEIGHT-2); //绘制bar

}

};

draw();

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值