微信端音频插件

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/susuzhe123/article/details/81941099
/**
 * @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')[0];
        },
        getAudioSuccess: function(){
            //防止音频加载失败的情况  重新加载
            if(this.duration){
                clearTimeout(this.suaudio);
            }else{
                this.suaudio = setTimeout(function(){
                    this.getAudio();
                    this.getDuration();
                    this.getAudioSuccess();
                }.bind(this),1000);
            }
        },
        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')[0];
        },
        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[0].clientX,  //起始点坐标
                    that = $(this),
                    l = e.target.offsetLeft;   //按钮距离左边距离
                that.bind("touchmove",function(event){
                    var e = event || window.event,
                        //终点坐标
                        thisX = e.touches[0].clientX,
                        //求 滑动的位置
                        btnPosition = Math.min(me.progwidth, Math.max(0, 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(0, 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*100;
            this.par.find('.j-now-time').html(this.getShowTime(curTime)+'/');
            this.$progressed.width(percent+'%');
            if(percent == 100){
                $('.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/3600);
            var m = Math.floor((val - h*3600)/60);
            var s = Math.floor(val - h*3600 - m*60);
            h = h<10?"0"+h:h;
            m = m<10?"0"+m:m;
            s = s<10?"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: .32rem;
    width: .5rem;
    margin: .5rem auto .09rem;
    font-size: 0;
    .react {
        height: 90%;
        width: .04rem;
        display: inline-block;
        margin:0 .025rem;
        border-radius: 1px;
        background: #2695ff;
        animation: stretchdelay 1.2s infinite ease-in-out;
    }
    .rect2 {
        -webkit-animation-delay: -1.1s;
        animation-delay: -1.1s;
    }
    .rect3 {
        animation-delay: -1.0s;
    }
    .rect4 {
        animation-delay: -0.9s;
    }
    .rect5 {
        animation-delay: -0.8s;
    }
} 

.audioCont{
    width: 82%;
    height: .98rem;
    background: #fff;
    margin: .4rem auto 0;
    box-shadow: 0 0 10px #f3f3f5;
    overflow: hidden;
    user-select: none;
    .spinner{
        height: .4rem;
        margin-top: .3rem;
    }
    .audio-play{
        display: block;
        width: .44rem;
        height: .44rem;
        border-radius: .44rem;
        box-shadow: 0 0 8px #b1d7ff;
        margin: .28rem 0 0 .21rem;
        background: url(../img/pause.png) no-repeat .18rem .16rem;
        background-size: .1rem .44rem;
    }
    .audio-play.pause{
        background-position: .18rem -.15rem;
    }
    .progress{
        width: 3.2rem;
        height: 2px;
        background: #e0e0e2;
        margin: .48rem 0 0 .14rem;
        position: relative;
        .progressed{
            position: absolute;
            width: 0;
            height: 2px;
            background: #3496fb;
            em{
                display: block;
                width: 6px;
                position: absolute;
                height: 6px;
                background: #3496fb;
                border-radius: 6px;
                right: -3px;
                top: -2px;
                box-shadow: 0 0 6px #3496fb;
                cursor: pointer;
            }
        }
    }
    .times{
        font-size: .2rem;
        color: #3496fb;
        line-height: .98rem;
        margin-left: .2rem;
    }
    .del{
        display: block;
        width: .35rem;
        height: .34rem;
        background: url(../img/del.png);
        background-size: 100% 100%;
        margin:.32rem .33rem 0 0;
    }
}
@keyframes stretchdelay {
    0%, 40%, 100% {
        transform: scaleY(0.4);
        -webkit-transform: scaleY(0.4);
    }  
    20% {
        transform: scaleY(1.0);-webkit-transform: scaleY(1.0);
    }
}

猜你喜欢

转载自blog.csdn.net/susuzhe123/article/details/81941099