天天看點

微信端音頻插件

/**
 * @Author   SuZ
 * @DateTime 2018-08-01
 * @desc     微信端音頻播放插件(pc、手機)
 * @param    {[Object]}     window    [window]
 * @param    {[Undefined]}  undefined [undefined]
 * @param    {[Jquery]}     $         [Jquery]
 * @param    {[Object]}     change.src [audio修改路徑函數的參數路徑]
 * @param    {[Object]}     change.id  [audio添加或修改路徑的容器]
 * @param    {[Object]}     default.id  [初始化時預設參數的audio容器 傳值則初始化加載音頻  不傳則需要手動加載音頻]
 * @param    {[Object]}     default.src [初始化時預設參數的audio路徑 傳值則初始化  不傳則需要手動修改路徑]
 * @param    {[Function]}   default.del [初始化時特殊需求删除錄音回調函數 非必選]
 * eg1:
 *      //初始化 (多個音頻 )
 *      var wxRecord = WxAudio({
 *          del: function(){
 *              //删除
 *          }
 *      });
 *      //添加或更換錄音
 *      wxRecord.changeSrc({
 *          id:'#***',
 *          src: 'https://jicvps.qingguo.com/Ant/dist/img/audio3.mp3'
 *      });
 *      
 *  eg2:
 *      //初始化 (單個音頻 不初始加載音頻)
 *      var wxRecord = WxAudio({
 *          id:'#***',
 *          del: function(){
 *              //删除音頻
 *          }
 *      });
 *      //添加或更換錄音
 *      wxRecord.changeSrc({
 *          src: 'https://jicvps.qingguo.com/Ant/dist/img/audio3.mp3'
 *      });
 *      
 *  eg3:
 *      //初始化 (音頻 初始加載音頻)
 *      var wxRecord = WxAudio({
 *          id:'#***',
 *          src: 'https://jicvps.qingguo.com/Ant/dist/img/audio3.mp3',
 *          del: function(){
 *              //删除音頻
 *          }
 *      });
 *
 * tip:如果頁面有多個audio需要處理,先執行初始化函數 再次執行 changeSrc 添加函數  無需new多個對象(适用于手動添加;如果是初始渲染多個音頻,有可能出現音頻加載不完全的情況,建議使用eg3循環建立)
 * 
 */
;(function(window,undefined,$){
    function WxAudio(defaultParam){
        //此時 this指向window 初始參數在init定義挂載
        return new WxAudio.prototype.init(defaultParam);
    }
    WxAudio.prototype = {
        init:function(defaultParam){
            if(typeof defaultParam.del != 'undefined'){
                this.del = defaultParam.del;
            }
            if(typeof defaultParam.id != 'undefined'){
                this.id = defaultParam.id;
            }
            if(typeof defaultParam.src != 'undefined'){
                this.changeSrc(defaultParam);
            }
            return this;
        },
        loadDom: function() {
            var $par = this.par;
            //采用js加載  友善以後直接調用
            var fristDom = '<audio src="'+this.audioSrc+'" class="media" width="1" height="1" preload="metadata"></audio>\
                                <div class="spinner">\
                                    <div class="rect1 react"></div>\
                                    <div class="rect2 react"></div>\
                                    <div class="rect3 react"></div>\
                                    <div class="rect4 react"></div>\
                                    <div class="rect5 react"></div>\
                                </div>';
            $par.html(fristDom);

            //加載完畢dom 擷取audio元素
            this.getAudio();
        },
        getAudio: function(){
            var $par = this.par;
            $par.find('.media').attr('src',this.audioSrc);
            this.audio = $par.find('.media')[];
        },
        getAudioSuccess: function(){
            //防止音頻加載失敗的情況  重新加載
            if(this.duration){
                clearTimeout(this.suaudio);
            }else{
                this.suaudio = setTimeout(function(){
                    this.getAudio();
                    this.getDuration();
                    this.getAudioSuccess();
                }.bind(this),);
            }
        },
        getDuration: function (){
            var me   = this,
                $par = me.par;
            //監聽加載完畢再擷取時間
            this.audio.addEventListener("loadedmetadata", function(){
                //成功後移除事件監聽
                me.audio.removeEventListener("loadedmetadata", function(){me.listen(me,this);})
                me.listen(me,this);
            });
        },
        listen: function(me,audioMe){
            //擷取總時間
            me.duration = audioMe.duration;
            //時間格式化
            var format = me.getShowTime(audioMe.duration);
            //添加操作區域
            var html = ['<audio src="'+me.audioSrc+'" class="media" width="1" height="1" preload="metadata"></audio><em class="audio-play left"></em>',
                            '<div class="progress left">',
                                '<p class="progressed"><em class="proBtn"></em></p>',
                            '</div>',
                            '<p class="left times"><span class="j-now-time">00:00/</span>'+format+'</p>',
                            '<span class="line">|</span>',
                            '<em class="del right"></em>'
                        ].join('');
            me.par.html(html);

            //一切放在audio加載完成後處理
            me.handle();
        },
        setFinger: function($pars){
            //重置指向
            this.$progressed = $pars.find('.progressed');
            this.$progress   = $pars.find('.progress');
            this.progwidth   = this.$progress.width();
            this.audio = $pars.find('audio')[];
        },
        handle: function() {
            var me = this;
            //播放 暫停 操作
            $('.audio-play').unbind('click');
            $('.audio-play').bind('click',function(){
                var that = $(this);
                //改變this父元素指向
                me.par = that.parent();
                me.setFinger(me.par);

                if(that.hasClass('pause')){
                    me.audio.removeEventListener("timeupdate",me.updateData.bind(me),true);
                    that.removeClass('pause');
                    me.audio.pause();
                }else{
                    me.audio.addEventListener("timeupdate",me.updateData.bind(me),true);
                    that.addClass('pause');
                    me.audio.play();
                }
            });

            //删除操作
            $('.del').unbind('click');
            $('.del').bind('click',function(){
                //改變this父元素指向
                me.par = $(this).parent();
                me.setFinger(me.par);
                if(me.del && typeof me.del === 'function'){
                    me.del(me.audio,me.par);
                }
            });

            //進度條(手機端相容 播放微信本地音頻 無需此操作)
            $('.proBtn').unbind("touchstart");
            $('.proBtn').bind("touchstart",function(event){
                //改變自身指向
                me.par = $(this).parents('.progress').parent();
                me.setFinger(me.par);

                var e = event || window.event,
                    x = e.touches[].clientX,  //起始點坐标
                    that = $(this),
                    l = e.target.offsetLeft;   //按鈕距離左邊距離
                that.bind("touchmove",function(event){
                    var e = event || window.event,
                        //終點坐标
                        thisX = e.touches[].clientX,
                        //求 滑動的位置
                        btnPosition = Math.min(me.progwidth, Math.max(, l + (thisX - x)));
                    //時間指派
                    me.audio.currentTime = me.audio.duration * btnPosition / me.progwidth;
                    //進度控制
                    me.updateData();
                });
                //滑鼠彈起後取消滑動事件
                that.bind("touchend",function(e){
                    that.unbind("touchmove"); 
                    that.unbind("touchend"); 
                });
            });
            //進度條(pc相容 播放轉碼後的MP3格式)
            $('.proBtn').unbind("mousedown");
            $('.proBtn').bind("mousedown",function(event){
                //改變自身指向
                me.par = $(this).parents('.progress').parent();
                me.setFinger(me.par);

                var e = event || window.event,
                    x = e.clientX,  //起始點坐标
                    that = $(this),       
                    l = e.target.offsetLeft;   //按鈕距離左邊距離
                //需綁定到外側
                document.onmousemove = function (event) {
                    var e = event || window.event,
                        //終點坐标
                        thisX = e.clientX,
                        //求 滑動的位置
                        btnPosition = Math.min(me.progwidth, Math.max(, l + (thisX - x)));
                    //時間指派
                    me.audio.currentTime = me.audio.duration * btnPosition / me.progwidth;
                    //進度控制
                    me.updateData();
                };
                //滑鼠彈起後取消滑動事件
                document.onmouseup = function () {
                    document.onmousemove = null;
                    document.onmouseup = null;
                };
            });

        },
        updateData: function() {
            var curTime = this.audio.currentTime,
                percent = curTime/this.audio.duration*;
            this.par.find('.j-now-time').html(this.getShowTime(curTime)+'/');
            this.$progressed.width(percent+'%');
            if(percent == ){
                $('.audio-play').removeClass('pause');
            }
        },
        extend: function(defaults,newObj){
            for (var i in newObj) {
              defaults[i] = newObj[i];
            }
            return defaults;
        },
        getShowTime: function (val){
            var h = Math.floor(val/);
            var m = Math.floor((val - h*)/);
            var s = Math.floor(val - h* - m*);
            h = h<?"0"+h:h;
            m = m<?"0"+m:m;
            s = s<?"0"+s:s;

            if(h == "00"){
                return m+":"+s;
            }else{
                return h+":"+m+":"+s;
            }
        },
        changeSrc: function(audioSrc) {
            //改變音頻路徑
            this.par      = this.id == undefined ? audioSrc.id : this.id;
            this.audioSrc = audioSrc.src;
            //全局錄音 重置
            clearTimeout(this.suaudio);
            this.suaudio = null;
            this.duration = null; 
            //加載中
            this.loadDom();
            //展示操作dom
            this.getDuration();
            this.getAudioSuccess();
        }
    };
    WxAudio.prototype.init.prototype = WxAudio.prototype;
    if(!window.WxAudio){
      window.WxAudio = WxAudio;
    }
})(window,undefined,$);

           
<div class="audioCont clearx" id="audioCont">
    <!--音頻插件-->
</div>
           
.spinner{
    height: .rem;
    width: .rem;
    margin: .rem auto .rem;
    font-size: ;
    .react {
        height: %;
        width: .rem;
        display: inline-block;
        margin: .rem;
        border-radius: px;
        background: #2695ff;
        animation: stretchdelay s infinite ease-in-out;
    }
    .rect2 {
        -webkit-animation-delay: -s;
        animation-delay: -s;
    }
    .rect3 {
        animation-delay: -s;
    }
    .rect4 {
        animation-delay: -s;
    }
    .rect5 {
        animation-delay: -s;
    }
} 

.audioCont{
    width: %;
    height: .rem;
    background: #fff;
    margin: .rem auto ;
    box-shadow:   px #f3f3f5;
    overflow: hidden;
    user-select: none;
    .spinner{
        height: .rem;
        margin-top: .rem;
    }
    .audio-play{
        display: block;
        width: .rem;
        height: .rem;
        border-radius: .rem;
        box-shadow:   px #b1d7ff;
        margin: .rem   .rem;
        background: url(../img/pause.png) no-repeat .rem .rem;
        background-size: .rem .rem;
    }
    .audio-play.pause{
        background-position: .rem -.rem;
    }
    .progress{
        width: rem;
        height: px;
        background: #e0e0e2;
        margin: .rem   .rem;
        position: relative;
        .progressed{
            position: absolute;
            width: ;
            height: px;
            background: #3496fb;
            em{
                display: block;
                width: px;
                position: absolute;
                height: px;
                background: #3496fb;
                border-radius: px;
                right: -px;
                top: -px;
                box-shadow:   px #3496fb;
                cursor: pointer;
            }
        }
    }
    .times{
        font-size: .rem;
        color: #3496fb;
        line-height: .rem;
        margin-left: .rem;
    }
    .del{
        display: block;
        width: .rem;
        height: .rem;
        background: url(../img/del.png);
        background-size: % %;
        margin:.rem .rem  ;
    }
}
@keyframes stretchdelay {
    0%, 40%, 100% {
        transform: scaleY();
        -webkit-transform: scaleY();
    }  
    20% {
        transform: scaleY();-webkit-transform: scaleY();
    }
}