当前位置 : 主页 > 网络编程 > JavaScript >

波形 数据捕获 音频播放器 支持 mp4 mp3 acc flat ....

来源:互联网 收集:自由互联 发布时间:2021-06-28
index.html 波形音乐播放器 选择播放文件: 你这不行啊..不支持canvas style.css html, body { margin: 0; font-family: arial, "Microsoft YaHei"; background-color: #ffffff; color: #000000;}#fileWrapper{transition:all 0.5s ease;
index.html



	
 
	
 
	波形音乐播放器
	
 



	
 
		
   
    
     
     
     
     
    
    
    
      你这不行啊..不支持canvas 
     
    
  
		
  
style.css
html, body {
    margin: 0;
    font-family: arial, "Microsoft YaHei";
    background-color: #ffffff;
    color: #000000;
}
#fileWrapper{
	transition:all 0.5s ease;
}
#fileWrapper:hover{
	opacity: 1!important;
}

#visualizer_wrapper{
	text-align: center;
}
#bg {
	position: absolute;
	width: 1920px;
	height: 1080px;
	background: url(../images/index-bg.jpg);
	margin-left: -960px;
	left:50%;
	margin-top:-540px;
	top:50%;
}
canvas_draw.js
// JavaScript Document


var x = 0; // canvas画布原点x  
var y = 0; // canvas画布原点y  
var x_base = x; // 我们要画的波形图的最后一个点的x坐标  
var y_base = 250; // 我们要画的波形图的最后一个点的y坐标  
var arrPoint = []; // 用于保存已经波形图的轨迹点  
var index = 0; // 这个我是用来打日志用的..下面为了看清除了多少次canvas画布  
var step = 1; // x轴每次走的步长  
var width = 1024; // 这个是画布宽度  
var height = 768; // 这个是画图高度  
(function () {
    // 首先让我们的函数周期调用  
    var canvas = document.getElementById("canvas");
    canvas.setAttribute("style", "border:solid 1px #000000;")
    canvas.width = width + "";
    canvas.height = height + "";
    var context = canvas.getContext("2d");
    context.strokeStyle = "#ccccc";
    context.fileStyle = "#ccccc";
    var itv = setInterval(function () {
        context.clearRect(0, 0, x_base - step, height);
        if (x_base > width) {
            index++;
            context.translate(step * -1, 0);
        }
        var obj = {};
        obj.x = x_base;
        obj.y = y_base;
        if (arrPoint.length > (width / step)) {
            arrPoint.splice(0, 1);
        }
        arrPoint.push(obj);

        context.beginPath();
        for (var i = 0; i < arrPoint.length; i++) {
            context.lineTo(arrPoint[i].x, arrPoint[i].y);

        }
        context.stroke();
        context.closePath();
        x_base += step;
        y_base = 500 - (window.audio.current_data * 2);


    }, 100)
    var a = document.createElement("div");
    document.body.appendChild(a);
    a.setAttribute("style", "height:20px; width:1280px;position:absolute;top:850px;;margin-left:-640px;left:50%;")
    var led = new Array(1024)
    var bor = new Array(1024)




    var b = document.createElement("div");
    document.body.appendChild(b);
    b.setAttribute("style", "height:512px; width:1536px;position:absolute;top:50px;;margin-left:-768px;left:50%;")




    for (var i = 0; i < 1024; i++) {
        led[i] = document.createElement("div");
        a.appendChild(led[i]);
        led[i].setAttribute("style", "width:10px;height:5px;float:left; background:#00ff00;opacity:0.0;border:solid 1px #000000;");

    }




    for (var i = 0; i < 512; i++) {
        bor[i] = document.createElement("div");
        b.appendChild(bor[i]);
        bor[i].setAttribute("style", "width:1px;height:512px;float:left;background:#00ff00;;opacity:1;border:solid 1px #000000;");

    }




    setInterval(function () {
        document.getElementById("sdf").style.height = (window.audio.current_data * 5) + "px"
        for (var i = 0; i < 1024; i++) {
            led[i].style.opacity = ((audio.current_data_array[i] * (100 / 255)) / 100) + "";
            led[i].style.background = 'rgb(' + randomNum(0, 255) + ',' + randomNum(0, 255) + ',' + randomNum(0, 255) + ')'
            if (i % 2 == 0) {
                bor[i / 2].style.height = (audio.current_data_array[i]) + "px"
            }

        }

    }, 100)
    function randomNum(minNum, maxNum) {
        switch (arguments.length) {
            case 1:
                return parseInt(Math.random() * minNum + 1, 10);
                break;
            case 2:
                return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10);
                break;
            default:
                return 0;
                break;
        }
    }
})()
_audio_visualizer.js
window.onload = function() {
    window.audio=[];
	window.audio.current_data_array = new Uint8Array(1024);
	new Visualizer().ini();
	
};
var Visualizer = function() {
    this.file = null; //the current file
    this.fileName = null; //the current file name
    this.audioContext = null;
    this.source = null; //the audio source
    this.info = document.getElementById('info').innerHTML; //used to upgrade the UI information
    this.infoUpdateId = null; //to store the setTimeout ID and clear the interval
    this.animationId = null;
    this.status = 0; //flag for sound is playing 1 or stopped 0
    this.forceStop = false;
    this.allCapsReachBottom = false;
};
Visualizer.prototype = {
    ini: function() {
        this._prepareAPI();
        this._addEventListner();
    },
    _prepareAPI: function() {
        //fix browser vender for AudioContext and requestAnimationFrame
        window.AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext || window.msAudioContext;
        window.requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.msRequestAnimationFrame;
        window.cancelAnimationFrame = window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || window.msCancelAnimationFrame;
        try {
            this.audioContext = new AudioContext();
        } catch (e) {
            this._updateInfo('!Your browser does not support AudioContext', false);
            console.log(e);
        }
    },
    _addEventListner: function() {
        var that = this,
            audioInput = document.getElementById('uploadedFile'),
            dropContainer = document.getElementsByTagName("canvas")[0];
        //listen the file upload
        audioInput.onchange = function() {//打开文件*************************************************************************
            if (that.audioContext===null) {return;};

            //the if statement fixes the file selction cancle, because the onchange will trigger even the file selection been canceled
            if (audioInput.files.length !== 0) {
                //only process the first file
                that.file = audioInput.files[0];
                that.fileName = that.file.name;
                if (that.status === 1) {
                    //the sound is still playing but we upload another file, so set the forceStop flag to true
                    that.forceStop = true;
                };
                document.getElementById('fileWrapper').style.opacity = 1;
                that._updateInfo('Uploading', true);
                //once the file is ready,start the visualizer
                that._start();
            };
        };
        //listen the drag & drop
        dropContainer.addEventListener("dragenter", function() {
            document.getElementById('fileWrapper').style.opacity = 1;
            that._updateInfo('Drop it on the page', true);
        }, false);
        dropContainer.addEventListener("dragover", function(e) {
            e.stopPropagation();
            e.preventDefault();
            //set the drop mode
            e.dataTransfer.dropEffect = 'copy';
        }, false);
        dropContainer.addEventListener("dragleave", function() {
            document.getElementById('fileWrapper').style.opacity = 0.2;
            that._updateInfo(that.info, false);
        }, false);
        dropContainer.addEventListener("drop", function(e) {
            e.stopPropagation();
            e.preventDefault();
            if (that.audioContext===null) {return;};
            document.getElementById('fileWrapper').style.opacity = 1;
            that._updateInfo('Uploading', true);
            //get the dropped file
            that.file = e.dataTransfer.files[0];
            if (that.status === 1) {
                document.getElementById('fileWrapper').style.opacity = 1;
                that.forceStop = true;
            };
            that.fileName = that.file.name;
            //once the file is ready,start the visualizer
            that._start();
        }, false);
    },
    _start: function() {
        //read and decode the file into audio array buffer
        var that = this,
            file = this.file,
            fr = new FileReader();
        fr.onload = function(e) {
            var fileResult = e.target.result;
            var audioContext = that.audioContext;
            if (audioContext === null) {
                return;
            };
            that._updateInfo('正在解码...', true);
            audioContext.decodeAudioData(fileResult, function(buffer) {
                that._updateInfo('解码完成!', true);
                that._visualize(audioContext, buffer);
            }, function(e) {
                that._updateInfo('解码文件失败!', false);
                console.error(e);
            });
        };
        fr.onerror = function(e) {
            that._updateInfo('读取文件失败!', false);
            console.error(e);
        };
        //assign the file to the reader
        this._updateInfo('开始读取文件', true);
        fr.readAsArrayBuffer(file);
    },
    _visualize: function(audioContext, buffer) {
        var audioBufferSouceNode = audioContext.createBufferSource(),
            analyser = audioContext.createAnalyser(),
            that = this;
        //链接资源到 analyser
        audioBufferSouceNode.connect(analyser);
        //链接 analyser 到 destination(the speaker), or we won't hear the sound
        analyser.connect(audioContext.destination);
        //then assign the buffer to the buffer source node
        audioBufferSouceNode.buffer = buffer;
        //play the source
        if (!audioBufferSouceNode.start) {
            audioBufferSouceNode.start = audioBufferSouceNode.noteOn //in old browsers use noteOn method
            audioBufferSouceNode.stop = audioBufferSouceNode.noteOff //in old browsers use noteOff method
        };
        //stop the previous sound if any
        if (this.animationId !== null) {
            cancelAnimationFrame(this.animationId);
        }
        if (this.source !== null) {
            this.source.stop(0);
        }
        audioBufferSouceNode.start(0);
        this.status = 1;
        this.source = audioBufferSouceNode;
        audioBufferSouceNode.onended = function() {
            that._audioEnd(that);
        };
        this._updateInfo('正在播放 ' + this.fileName, false);
        this.info = '正在播放 ' + this.fileName;
        document.getElementById('fileWrapper').style.opacity = 0.2;
        this._drawSpectrum(analyser);
    },
    _drawSpectrum: function(analyser) {
        var that = this,
            meterWidth = 10, //width of the meters in the spectrum
            gap = 2, //gap between meters
            capStyle = '#fff',
            meterNum = 800 / (10 + 2), //count of the meters
            capYPositionArray = []; ////将hte caps的垂直位置存储在数组里面
      
        var drawMeter = function() {//绘图函数
            var array = new Uint8Array(analyser.frequencyBinCount);
            analyser.getByteFrequencyData(array);//获取数据
			//console.info("audio data array:"+array);
			var val_vd=0;
			//平均取值  
			for(var i=0;i<=array.length;i++){
				if(i==array.length){
					val_vd=val_vd/array.length;
				}else{
					val_vd = array[i]+val_vd;
				}
			}
			//保存一帧音频数据
			window.audio.current_data=val_vd;		
			window.audio.current_data_array= array;
			//console.info(val_vd);
            if (that.status === 0) {
                //修正当声音结束时的值仍然不回到
                for (var i = array.length - 1; i >= 0; i--) {
                    array[i] = 0;
                };
                allCapsReachBottom = true;
                for (var i = capYPositionArray.length - 1; i >= 0; i--) {
                    allCapsReachBottom = allCapsReachBottom && (capYPositionArray[i] === 0);
                };
                if (allCapsReachBottom) {
                    cancelAnimationFrame(that.animationId); //由于声音停止,动画完成,停止请求动画以防止潜在的内存泄漏,这是非常重要的!
                    return;
                };
            };
            var step = Math.round(array.length / meterNum); //从总数组中取样有限的数据
			//console.info("step:" +step);
         
            that.animationId = requestAnimationFrame(drawMeter);
        }
        this.animationId = requestAnimationFrame(drawMeter);
    },
    _audioEnd: function(instance) {//音频结束
        if (this.forceStop) {
            this.forceStop = false;
            this.status = 1;
            return;
        };
        this.status = 0;
        var text = 'HTML5 Audio API showcase | An Audio Viusalizer';
        document.getElementById('fileWrapper').style.opacity = 1;
        document.getElementById('info').innerHTML = text;
        instance.info = text;
        document.getElementById('uploadedFile').value = '';
    },
    _updateInfo: function(text, processing) {
        var infoBar = document.getElementById('info'),
            dots = '...',
            i = 0,
            that = this;
        infoBar.innerHTML = text + dots.substring(0, i++);
        if (this.infoUpdateId !== null) {
            clearTimeout(this.infoUpdateId);
        };
        if (processing) {
            //信息文本末端的动画点
            var animateDot = function() {
                if (i > 3) {
                    i = 0
                };
                infoBar.innerHTML = text + dots.substring(0, i++);
                that.infoUpdateId = setTimeout(animateDot, 250);
            }
            this.infoUpdateId = setTimeout(animateDot, 250);
        };
    }
}
网友评论