利用Web Audio API 实现的一个小播放器


作者:朱培鑫

时间:2018-03-19

Web Audio API 提供了在Web上控制音频的一个非常有效通用的系统,允许开发者来自选音频源,对音频添加特效,使音频可视化,添加空间效果 (如平移),等等。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>audio</title>
</head>
<body>
<div><h3>控制台</h3></div>
<div>
    <button id="pause">暂停</button>
    <button id="stop">停止</button>
    <button id="minus">减音量</button>
    <button id="add">加音量</button>
    <button id="quiet">静音</button>    
</div>
<script type="text/javascript" src="./audio.js"></script>
</body>
</html>
function webAudio(options){
    //public
    this.volume =  parseInt(options.volume || 100) ; // 音量控制单元,值为Number类型,范围为0-100
    this.url = options.url || '' ;                   // 音频资源url,值类型为String类型
    this.autoPlay = !!options.autoPlay;              // 是否加载完成自动播放,值类型为Boolean类型
    this.loopPlay = !!options.loopPlay;              // 是否循环播放,值类型为Boolean类型

    //private
    this.buffer = null;
    this.context = null;
    this.sourceAudio = null;
    this.gainNode = null;
    this.loadReady = false;

    //初始化
    this.init = function () {
        window.AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext || window.msAudioContext;
        if(!AudioContext){
            console.error("您的浏览器不支持HTML5 audio API");
            return
        }
        this.context = new AudioContext();
        this.loadResource();
    }

    //下载音频资源
    this.loadResource = function () {
        var _this = this;
        var xhr = new XMLHttpRequest();
        xhr.open('GET',this.url,true);
        xhr.responseType = 'arraybuffer';
        xhr.onload = function () {
            _this.context.decodeAudioData(xhr.response,function (buffer) {
                _this.buffer = buffer;
                _this.prepareAudio();
                this.loadReady = true;
            })
        }
        xhr.send();
    }

    //是否自动播放
    this.prepareAudio = function () {
        this.autoPlay ? this.startAudio() : '';
    }

    //创建音频
    this.createAudio = function () {
        this.sourceAudio = this.context.createBufferSource();//创建一个音频源 相当于是装音频的容器
        this.sourceAudio.buffer = this.buffer;//  告诉音频源 播放哪一段音频
        this.gainNode = this.context.createGain();//调节音量
        this.sourceAudio.connect(this.gainNode);
        this.changeVolume();//声音
        this.sourceAudio.loop = this.loopPlay;//循环
        this.gainNode.connect(this.context.destination);// 连接到输出源
    }

    //重新播放
    this.startAudio = function () {
        this.createAudio();
        this.sourceAudio.start(0);//开始播放
    }

    //改变音量
    this.changeVolume = function (num) {
        num = num || 0;
        this.gainNode.gain.value = (this.volume += num) / 100;
    }

    //播放转为暂停
    this.pauseAudio = function () {
        this.gainNode.disconnect(this.context.destination)
    }

    //暂停转为播放
    this.playAudio = function () {
        this.gainNode.connect(this.context.destination)
    }

    //停止播放
    this.stopAudio = function () {
        this.sourceAudio.stop()
    }

    //减小声音
    this.decVolume = function () {
        if(this.volume >= 10){
            this.changeVolume(-10);
        }
    }

    //增大声音
    this.ascVolume = function () {
        if(this.volume <= 90){
            this.changeVolume(10);
        }
    }

    //静音
    this.quietVolume = function () {
        this.gainNode.gain.value = 0;
    }

    //静音恢复
    this.recoverVolume = function () {
        this.changeVolume()
    }

    //当前音量
    this.getVolume = function () {
        return (this.gainNode.gain.value).toFixed(2) * 100;
    }

    this.init();
    return this;
}
window.test = new webAudio({
    volume:100,
    url:'http://zhupeixin.com/audio/audiotest.mp3',
    autoPlay:true,
    loopPlay:true
});

//控制台事件
var pauseEle = document.getElementById("pause");
var stopEle = document.getElementById("stop");
var minusEle = document.getElementById("minus");
var addEle = document.getElementById("add");
var quietEle = document.getElementById("quiet");
pauseEle.onclick = function(){
    if(pauseEle.innerText === '暂停' ){
        test.pauseAudio();
        pauseEle.innerText = '继续';
    }else{
        test.playAudio();
        pauseEle.innerText = '暂停';
    }
}
stopEle.onclick = function(){
    if(stopEle.innerText === '停止'){
        test.stopAudio()
        stopEle.innerText = '开始';
    }else{
        test.startAudio()
        stopEle.innerText = '停止'
    }
}
minusEle.onclick = function(){
    addEle.disabled = false;
    if(test.getVolume() < 10 ){
        minusEle.disabled = true;
    }else{
        test.decVolume()
    }
}
addEle.onclick = function(){
    minusEle.disabled = false;
    if(test.getVolume() > 90 ){
        addEle.disabled = true;
    }else{
        test.ascVolume()
    }
}
quietEle.onclick = function(){
    if(quietEle.innerText === '静音'){
        test.quietVolume();
        quietEle.innerText = '取消静音'
    } else{
        test.recoverVolume();
        quietEle.innerText = '静音'
    }
}

( 本篇完 )