js音频插件实践应用

说明
应用于微信中,详情页播放音频,列表页循环播放多个音频
1、单个音频
仿微信公众号语音框插件weixinAudio.js
1)实践示例代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>音频</title>
    <meta name="description" content="音频">
    <meta name="keywords" content="音频">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no" />
    <style>
        .db {
            display: block; }
        .weixinAudio {
            line-height: 1.5;
            margin: 20px 0; }
        .audio_area {
            display: inline-block;
            width: 100%;
            vertical-align: top;
            margin: 0px 1px 0px 0;
            font-size: 0;
            position: relative;
            font-weight: 400;
            text-decoration: none;
            -ms-text-size-adjust: none;
            -webkit-text-size-adjust: none;
            text-size-adjust: none; }

        .audio_wrp {
            /* border: 1px solid #ebebeb;*/
            background-color: #fff;
            overflow: hidden;
            padding: 0 15px;
            box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.5);
            -webkit-box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.5); }

        .audio_play_area {
            float: left;
            margin: 9px 22px 10px 5px;
            font-size: 0;
            width: 18px;
            height: 25px; }

        .playing .audio_play_area .icon_audio_default {
            display: block; }

        .audio_play_area .icon_audio_default {
            background: transparent url(img/iconloop.png) no-repeat 0 0;
            width: 18px;
            height: 25px;
            vertical-align: middle;
            display: inline-block;
            -webkit-background-size: 54px 25px;
            background-size: 54px 25px;
            background-position: -36px center; }

        .audio_play_area .icon_audio_playing {
            background: transparent url(img/iconloop.png) no-repeat 0 0;
            width: 18px;
            height: 25px;
            vertical-align: middle;
            display: inline-block;
            -webkit-background-size: 54px 25px;
            background-size: 54px 25px;
            -webkit-animation: audio_playing 1s infinite;
            background-position: 0px center;
            display: none; }

        .audio_area .pic_audio_default {
            display: none;
            width: 18px; }

        .tips_global {
            color: #8c8c8c; }

        .audio_area .audio_length {
            float: right;
            font-size: 14px;
            margin-top: 11px;
            margin-left: 1em; }

        .audio_info_area {
            overflow: hidden;
            margin-top: 5px; }

        .audio_area .audio_title {
            font-weight: 400;
            font-size: 13px;
            margin-top: -2px;
            margin-bottom: -3px;
            width: auto;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
            word-wrap: normal; }

        .audio_area .audio_source {
            font-size: 12px;
            color: #b5b5b6; }

        .audio_area .progress_bar {
            position: absolute;
            left: 0;
            bottom: 0;
            background-color: #f88974;
            height: 2px; }

        .playing .audio_play_area .icon_audio_default {
            display: none; }

        .playing .audio_play_area .icon_audio_playing {
            display: inline-block; }

        @-webkit-keyframes audio_playing {
            30% {
                background-position: 0px center; }
            31% {
                background-position: -18px center; }
            61% {
                background-position: -18px center; }
            61.5% {
                background-position: -36px center; }
            100% {
                background-position: -36px center; } }
    </style>
</head>
<body>
    <p class="weixinAudio">
        <audio src="test.mp3" id="media" width="1" height="1" preload></audio>
        <span id="audio_area" class="db audio_area">
            <span class="audio_wrp db">
                <span class="audio_play_area">
                    <i class="icon_audio_default"></i>
                    <i class="icon_audio_playing"></i>
                </span>
                <span id="audio_length" class="audio_length tips_global">00:00</span>
                <span class="db audio_info_area">
                    <strong class="db audio_title">Title/标题</strong>
                    <span class="audio_source tips_global">From/来源</span>
                </span>
                <span id="audio_progress" class="progress_bar" style="width: 0%;"></span>
            </span>
        </span>
    </p>
    <script src="js/jquery-3.0.0.min.js" type="text/javascript" charset="utf-8"></script>
    <script src="js/weixinAudio.js" type="text/javascript" charset="utf-8"></script>
    <script type="text/javascript">
        //初始化音频插件
        $('.weixinAudio').weixinAudio();
        // Assume "video" is the video node
        window.onload = function(){
            var video = $('#media')[0];
            //实时更新音频播放时长---优化
            video.addEventListener("timeupdate",function(){

                var minutes = parseInt(this.currentTime / 60, 10);
                var seconds = this.currentTime % 60;
                if(minutes < 10){
                    minutes = '0' + minutes;
                }
                if(seconds < 10){
                    seconds = '0' + parseInt(seconds);
                }
                else{
                    seconds = parseInt(seconds)
                }
                var Time = minutes +':'+seconds;
                $('#audio_length').text(Time);
                /*console.log(this.currentTime);*/
            });
        }
    </script>
</body>
</html>

2)效果如下图
这里写图片描述
3)插件示例代码:http://www.jq22.com/jquery-info14740

2、多个音频
1)用HTML5的标签制作一个Mp3播放器
2)实践示例代码
html代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>音频</title>
    <meta name="description" content="音频">
    <meta name="keywords" content="音频">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no" />
    <style>
        img {
            border: 0;
            display: block;
        }
        .audioBox {
            display: -webkit-flex; 
            margin: 2% 0 4%;
            background-color: #333;
            width:270px;
            height: 146.25px;
            }
        .audioBox__left {
            display: -webkit-flex;
            -webkit-justify-content: center;
            -webkit-align-items: center;
            -webkit-flex: 1;
            padding: 2%;
            -webkit-flex-direction: column; }
        .audioBox__left img {
            width: 25px;
            height: 25px; }
        .audioBox__left span {
            -webkit-flex: 1;
            margin: 3px 0; }
        .audioBox__right {
            display: -webkit-flex;
            -webkit-justify-content: center;
            -webkit-align-items: center;
            padding: 4% 10%;
            -webkit-box-sizing: border-box;
            -webkit-flex: 1.5;
            }
        .audioBox__right img{
            width:123.13px;
            height:123.13px;
        }
    </style>
</head>
<body>
    <div class="audioBox">
        <div class="audioBox__left">
            <span class="audio__play">
                <img src="img/audio_play.png" alt="">
                <audio src="sound.mp3" class="audio1"></audio>
            </span>
            <span class="audio__prev" onclick="isCollect()"><img src="img/audio_prev.png" alt=""></span>
            <span class="audio__next" onclick="isCollect()"><img src="img/audio_next.png" alt=""></span>
            <span class="audio__like collect" onclick="collectArticle(this, 1);"><img src="img/audio_like.png" alt=""></span>
        </div>
        <div class="audioBox__right">
            <img src="img/audio_img.png" alt="">
        </div>
    </div>
    <h3 class="audio-title" style="display: none;">未知歌曲</h3>
    <script src="js/jquery-3.0.0.min.js" type="text/javascript" charset="utf-8"></script>
    <script src="js/audio.js" type="text/javascript" charset="utf-8"></script>
    <script type="text/javascript">
        var songs = [
            {"src":"test.mp3","title":1},
            {"src":"test2.mp3","title":2},
            {"src":"test3.mp3","title":3},
            {"src":"test4.mp3","title":4}
        ];
        //音频播放器初始化
        var audioFn = audioPlay({
            song : JSON.parse(songs),//将json格式数组转成json对象数组,可用数组遍历方式遍历该对象数组
            autoPlay : false  //是否立即播放第一首,autoPlay为true且song为空,会alert文本提示并退出
        });

        //上、下一首判断用户是否收藏
        function isCollect()
        {
            var url = '/next';
            var data = {
                'id' : parseInt($('.audio-title').html());
            };
            $.post(url, data, function(result) {
                //收藏
                var sHtml = '';
                if (result.success) {
                    sHtml = '<span onclick="collectArticle(this, 0);"><img src="img/audio_liked.png" alt=""></span>';
                } else {//未收藏
                    sHtml = '<span class="audio__like" onclick="collectArticle(this, 1);"><img src="img/audio_like.png" alt=""></span>';
                }
                //相应列表页音频插件收藏图片状态
                $('.collect').html(sHtml);
            }, 'json');
        }

        //收藏文章
        function collectArticle(obj, param)
        {
            var url = '/journey/collect';
            var id = parseInt($('.audio-title').text());
            var data = {
                'id' : id
            };
            //禁止重复点击
            $(obj).removeAttr('onclick');
            $.post(url, data, function(result) {
                if (result.success) {
                    //收藏
                    var sHtml = '';
                    if (param == 1) {
                        sHtml = '<span  onclick="collectArticle(this, 0);"><img src="img/audio_liked.png" alt=""></span>';
                    } else {//未收藏
                        sHtml = '<span class="audio__like" onclick="collectArticle(this, 1);"><img src="img/audio_like.png" alt=""></span>';
                    }
                    $('.collect').html(sHtml);
                } else {
                    swal(result.msg);
                    $(obj).attr('onclick', 'collectArticle(this, ' + param + ', "' + page +'")');
                }
            }, 'json');
        }

        //decode json_encode url
        function URLdecode(str)
        {
            var ret = "";
            for(var i=0;i<str.length;i++) {
                var chr = str.charAt(i);
                if(chr == "+") {
                    ret += " ";
                }else if(chr=="%") {
                    var asc = str.substring(i+1,i+3);
                    if(parseInt("0x"+asc)>0x7f) {
                        ret += decodeURI("%"+ str.substring(i+1,i+9));
                        i += 8;
                    }else {
                        ret += String.fromCharCode(parseInt("0x"+asc));
                        i += 2;
                    }
                }else {
                    ret += chr;
                }
            }
            return ret;
        }
    </script>
</body>
</html>

audio.js优化

;(function($){

    var fnName = 'audioPlay';
    var config = {

        view : ".audio-view",

        title : ".audio-title",

        cover : ".audio-cover",

        autoPlay : false,

        volume : {

            volumeView : ".audio-set-volume",
            volumeBox : ".volume-box",
        },

        timeView : {

            thisTime : ".audio-this-time",

            countTime : '.audio-count-time',
        },

        setbacks : {

            setbacks : '.audio-setbacks',

            thisSetbacks : '.audio-this-setbacks',

            cacheSetbacks : ".audio-cache-setbacks",

            volumeSetbacks : ".volume-box > i",

            volumeCircular : ".volume-box > i span"
        },

        button : {

            volume : ".audio-volume",

            backs : ".audio-backs-btn",

            prev : ".audio__prev",

            play : ".audio__play",

            next : ".audio__next",

            menu : ".audio-menu",

            menuClose : ".menu-close"
        },

        menu : {

            menuView : '.audio-list',

            colse : '.close',

            list : '.audio-inline'
        },

        song : null
    };

    var songEq = 0,
        volumeSize = 0.7;

    window[fnName] = function(setConfig){

        //设置属性值
        if(typeof(setConfig) == "object"){

            for( var n in setConfig){

                config[n] = setConfig[n];
            }
        }

        var _this = config,
            playDate;

        var cover = $(_this.cover),
            title = $(_this.title),
            thisTime = $(_this.timeView.thisTime),
            countTime = $(_this.timeView.countTime),
            thisSetbacks = $(_this.setbacks.thisSetbacks),
            cacheSetbacks = $(_this.setbacks.cacheSetbacks),
            setbacks = $(_this.setbacks.setbacks),
            volumeCircular = $(_this.setbacks.volumeCircular),
            volumeSetbacks = $(_this.setbacks.volumeSetbacks),
            volumeBox = $(_this.volume.volumeBox),
            play = $(_this.button.play),
            prev = $(_this.button.prev),
            next = $(_this.button.next),
            menuBtn = $(_this.button.menu),
            volume = $(_this.button.volume),
            menuClose = $(_this.button.menuClose),
            backs = $(_this.button.backs);

        _this.createAudio = function(){

            if(!_this.audio){

                _this.audio = new Audio();
            }

            var song = config.song;
            if(!song){

                swal('当前歌单没有歌曲!!!');
                return false;
            }

            _this.stopAudio();
            //判断当前音频是否存在,不存在播放当前页首个音频
            songEq = (songEq < _this.song.length) ? songEq : 0;
            _this.audio.src = song[songEq].src;

            _this.volumeSet();

            title.text(song[songEq].title || '未知歌曲');
            cover.css({
                'backgroundImage' : 'url('+(song[songEq].cover || '')+')'
            });

            function setDuration(){

                if(isNaN(_this.audio.duration)){

                    setTimeout(setDuration,50);
                }else{

                    countTime.text(_this.conversion(_this.audio.duration));
                }
            }
            setDuration(_this.audio.duration);

            thisTime.text(_this.conversion(_this.audio.currentTime));

            _this.audio.onended = function(){

                setTimeout(function(){

                    ++songEq;
                    songEq = (songEq < _this.song.length) ? songEq : 0;
                    _this.selectMenu(songEq,true);
                },1000);
            }

        }

        var timeAudio;
        _this.playAudio = function(){

            if(_this.audio){

                if(!playDate || (Date.now() - playDate) > 100){

                    playDate = Date.now();

                    (!_this.audio.paused) || _this.audio.pause();
                    //优化代码片段
                    play.removeClass('audio-stop');
                    _this.audio.play();
                    //改变按钮图片
                   play.find('img').attr('src','img/audio_pause.png');

                    play.one('click',function(){
                        _this.stopAudio();
                        $(this).one('click',function(){
                            _this.playAudio();
                        });
                    });

                    timeAudio = setInterval(function(){

                        if(_this.audio.readyState == 4){

                            cacheSetbacks.css({
                                'width' : (_this.audio.buffered.end(0) / _this.audio.duration)*100+"%"
                            });
                        }

                        thisSetbacks.css({
                            'width' : (_this.audio.currentTime / _this.audio.duration)*100+"%"
                        });

                        thisTime.text(_this.conversion(_this.audio.currentTime));
                    },500);
                }else{

                    setTimeout(function(){

                        _this.playAudio();
                    },50);
                }           
            }
        }

        _this.stopAudio = function(){

            if(!playDate || (Date.now() - playDate) > 100){

                playDate = Date.now();
                //停止播放音频,添加停止播放类名
                play.addClass('audio-stop');
                _this.audio.pause();
                //改变按钮图片
                play.find('img').attr('src','img/audio_play.png');
                clearInterval(timeAudio);
            }else{

                setTimeout(function(){

                    _this.stopAudio();
                },50);
            }       
        }

        _this.conversion = function(num){

            function changInt(num){

                return (num < 10) ? '0'+num : num;
            }

            return changInt(parseInt(num/60))+":"+ changInt(Math.floor(num%60));
        }

        _this.upMenu = function(){

            var song = _this.song,
                inline = $(_this.menu.list).empty();

            for(var i in song){

                inline.append("<li><a href='javascript:;'>"+(song[i].title || '未知歌曲')+"</a></li>");
            }

            inline.find(">li").unbind('click').on('click',function(){

                _this.selectMenu($(this).index(),true);
            });
        }

        _this.selectMenu = function(num,_bool){

            songEq = num;
            _this.createAudio();
            //默认上下首暂停播放音频
            // (_bool) && _this.playAudio();
            (_bool) && _this.stopAudio();
        }

        _this.volumeSet = function(){

            _this.audio.volume = volumeSize;
            volumeSetbacks.css({
                'height' : volumeSize*100 + "%"
            });
        }

        _this.newSong = function(_new,_bool){

            if( typeof(_new) == 'object' ){

                if(_new.src){

                    if(_this.song){

                        _this.song.push(_new);
                    }else{

                        _this.song = [_new];
                    }

                    _this.upMenu();
                    (_bool) && _this.selectMenu(_this.song.length-1,true);
                }else{

                    swal('对象缺省src属性');
                }
            }else{

                swal('这不是一个对象');
            }
        }

        _this.forward = function(_time){

            if(!_time) return false;

            _this.stopAudio();

            if(_time > _this.audio.buffered.end(0)){

                _time = _this.audio.buffered.end(0);
            } 
            _this.audio.currentTime = _time;
            _this.playAudio();
        }

        var volumeTime;
        volumeBox.on('mousedown',function(){

            if(_this.audio){
                var Y,EndY = parseInt(volumeBox.css('height')),goY;
                $(document).on('mousemove',function(e){

                    var e = e || window.event;

                    clearTimeout(volumeTime);

                    Y = (e.clientY-(volumeBox.offset().top-$(document).scrollTop()));
                    Y = (Y > 0) ? (Y > EndY) ? EndY : Y : 0;

                    goY = Y/EndY;

                    volumeSize = 1 - goY;

                    _this.volumeSet();
                }).one('mouseup',function(){

                    $(this).unbind('mousemove');
                });
            }
        });


        setbacks.on('mousedown',function(e){

            if(_this.audio){

                $(document).on('mousemove',function(e){

                    setbacksMove(e);
                }).one('mouseup',function(){

                    _this.forward(cuTime);

                    $(this).unbind('mousemove');
                });
            }
        }).on('click',function(e){

            setbacksMove(e);
        });

        var X,EndX = parseInt(setbacks.css('width')),goX,mouseTime,cuTime;
        function setbacksMove(e){

            e = e || window.event;

            X = (e.clientX-setbacks.offset().left);
            X = (X > 0) ? (X > EndX) ? EndX : X : 0;

            goX = X/EndX;
            thisSetbacks.css({
                'width' : goX*100+"%"
            });

            cuTime = parseInt(goX*_this.audio.duration);

            thisTime.text(_this.conversion(cuTime));

        }

        play.one('click',function(){

            _this.playAudio();
        });

        menuBtn.on('click',function(){

            $(_this.menu.menuView).toggleClass('menu-show');
        });

        prev.on('click',function(){
            --songEq;
            songEq = (songEq >= 0) ? songEq :  _this.song.length -1;
            _this.selectMenu(songEq,true);
        });

        next.on('click',function(){
            ++songEq;
            songEq = (songEq < _this.song.length) ? songEq : 0;
            _this.selectMenu(songEq,true);
        });

        menuClose.on('click',function(){

            $(_this.menu.menuView).removeClass('menu-show');
        });

        volume.on('click',function(){

            $(_this.volume.volumeView).toggleClass('audio-show-volume');
        });

        _this.upMenu();

        _this.selectMenu(songEq,_this.autoPlay);

        return _this;
    }
})(jQuery)

3)效果如下图
这里写图片描述
4)插件示例:http://www.jq22.com/jquery-info13806

注:
如何在翻书插件中使用音频插件?
1)单个音频:
– 需要在翻页时初始化音频代码,考虑Android与ios的兼容
2)多个音频:
– 需要在翻页是初始化音频代码
– 暂停当前正在播放的音频播放状态
– 始终保持当前页只初始化一个音频插件
– 注意audio.js需要高版本jquery支持

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值