可控制进度的音频播放器

功能

  1. 上一曲下一曲
  2. 显示进度与时间
  3. 能够快进和后退
  4. 调节音量大小
  5. 实际情况样式需求可调
  6. 后期可能补充歌词功能

实现

HTML

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"/>
    <link rel="stylesheet" href="../css/myreset.min.css">
    <link rel="stylesheet" href="../css/swiper.min.css">
    <link rel="stylesheet" href="../css/index.css">
</head>
<body>
<section class="pages">
    <div class="swiper-container">
        <ul class="swiper-wrapper">
            <li class="swiper-slide">
                <section class="topBtn clearfix">
                    <div class="voice"></div>
                    <div class="progressWrap">
                        <p>在线听宪法</p>
                        <p>科大讯飞提供语音合成</p>
                        <div class="progress">
                            <div class="bar"></div>
                        </div>
                        <div class="current">00:00</div>
                        <div class="duration">36:12</div>
                    </div>
                </section>
            </li>
            <li class="swiper-slide">
                <section class="topBtn clearfix">
                    <div class="voice"></div>
                    <div class="progressWrap">
                        <p>在线听宪法</p>
                        <p>科大讯飞提供语音合成</p>
                        <div class="progress">
                            <div class="bar"></div>
                        </div>
                        <div class="current">00:00</div>
                        <div class="duration">36:12</div>
                    </div>
                </section>
            </li>
        </ul>
        <!--底部按钮-->
        <section class="butBtn">
            <div class="swiper-pagination swiper-pagination-fraction" id="swiper-pagination"><span
                    class="swiper-pagination-current">1</span> / <span class="swiper-pagination-total">3</span></div>
            <button class="getPoster">分享</button>
            <div class="swiper-button-next"></div>
            <div class="swiper-button-prev"></div>
        </section>
    </div>
</section>
<script src="../js/common.js"></script>//兼容移动端处理rem的js
<script src="../js/jquery.js"></script>
<script src="../js/swiper.js"></script>
<script src="../js/index.js"></script>//下文中的js
</body>
</html>

css(实际用less写,抛弃传统的css写法)

html {
    font-size: 100px;
    width: 100%;
    height: 100%;
    max-width: 640px;
    margin: 0 auto;
    overflow: hidden;
    background: #fff;
}
body {
    width: 100%;
    height: 100%;
    max-width: 640px;
    background: #fff no-repeat;
    overflow: hidden;
    font-size: .28rem;
    position: relative;
    top: 0;
    left: 0;
}
.pages {
    width: 100%;
    height: 100%;
    position: relative;
}
.pages .swiper-container {
    width: 100%;
    height: 100%;
    position: relative;
}
.pages .swiper-wrapper {
    position: relative;
}
.pages .swiper-slide {
    width: 100%;
    height: 100%;
    position: relative;
    float: left;
    font-size: 18px;
    background: #ffeec6;
}
.pages .topBtn {
    display: block;
    width: 4.6rem;
    height: 1.4rem;
    padding: .05rem .25rem;
    padding-bottom: 0;
    margin: .2rem auto;
    background: #fcfcfc;
}
.pages .voice {
    width: .82rem;
    height: .82rem;
    float: left;
    background: url("../images/pause_03.png") no-repeat;
    background-size: 100%;
    margin-top: .1rem;
}
.pages .progressWrap {
    float: left;
    font-size: .2rem;
    color: #b3b3b3;
    width: 3.4rem;
    margin: .1rem;
    position: relative;
}
.pages .progressWrap p:nth-of-type(1) {
    font-size: .26rem;
    line-height: .26rem;
    color: #b12e29;
}
.pages .progressWrap p:nth-of-type(2) {
    font-size: .2rem;
    margin-top: .1rem;
    line-height: .2rem;
    margin-bottom: .1rem;
    color: #666666;
}
.pages .progressWrap .current {
    position: absolute;
    width: .7rem;
    margin-top: .14rem;
    text-align: center;
    overflow: hidden;
    color: #666666;
}
.pages .progressWrap .progress {
    width: 3.4rem;
    height: .06rem;
    vertical-align: middle;
    display: inline-block;
    border-radius: .03rem;
    background: #efefef;
    position: relative;
}
.pages .progressWrap .progress .bar {
    content: "";
    display: block;
    width: .06rem;
    height: .3rem;
    background: #b12e29;
    position: absolute;
    top: -0.1rem;
}
.pages .progressWrap .duration {
    position: absolute;
    color: #666666;
    right: 0;
    top: .26rem;
    margin-top: .7rem;
    text-align: center;
}
.pages .listsHide {
    position: absolute;
    right: -6.4rem;
    transition: all .5s linear;
}
.butBtn {
    width: 100%;
    height: 1rem;
    position: absolute;
    z-index: 9;
    bottom: 0;
    background: rgba(255,238,198,.8);
    -webkit-tap-highlight-color: transparent;
    -webkit-box-shadow: 20px -20px 30px #ffeec6;
    box-shadow: 20px -20px 30px #ffeec6;
}
.getPoster {
    display: block;
    height: .5rem;
    line-height: .5rem;
    text-align: center;
    width: 2.4rem;
    font-size: .28rem;
    border: none;
    border-radius: .25rem;
    color: #fff;
    -webkit-tap-highlight-color: transparent;
    margin: 0 auto;
    margin-top: .25rem;
    margin-left: 2.5rem;
    background: #333;
    background-size: 100%;
    background: #b12e29;
}
.swiper-pagination {
    width: 1rem;
    height: 1rem;
    line-height: 1rem;
    font-size: .28rem;
    color: #d9000e;
    margin-left: 1rem;
    bottom: 0;
}
.swiper-button-prev {
    width: .52rem;
    height: .52rem;
    background: url("../images/footBtn.png") no-repeat;
    background-size: 100%;
    margin-top: -0.28rem;
}
.swiper-button-prev:hover,
.swiper-button-prev:active {
    background: url("../images/footBtn.png") no-repeat;
    background-size: 100%;
}
.swiper-button-next {
    width: .52rem;
    height: .52rem;
    background: url("../images/footBtn_05.png") no-repeat;
    background-size: 100%;
    margin-top: -0.28rem;
}
.swiper-button-next:hover,
.swiper-button-next:active {
    background: url("../images/footBtn_05.png") no-repeat;
    background-size: 100%;
}

js(定义类)

//初始化swiper
var voiceList = ['0.mp3','1.mp3', '2.mp3', '3.mp3',"4.mp3","5.mp3","6.mp3","7.mp3","8.mp3","9.mp3","10.mp3","11.mp3"];
function swiperInit() {
    var mySwiper=new Swiper('.swiper-container', {
        pagination: '.swiper-pagination',
        paginationClickable: '.swiper-pagination',
        nextButton: '.swiper-button-next',
        prevButton: '.swiper-button-prev',
        paginationType: 'fraction',
        touchAngle : 25,//触发水平角
        touchMoveStopPropagation : false,//阻止touchmove冒泡事件
        threshold : 80,//触发最小距离
        //onlyExternal : true,
        onSlideChangeEnd: changeCallback,
    });
    return mySwiper

}
swiperInit();
//换页回调
function changeCallback() {
    if (myAudio.audio) {
        myAudio.audioInit()
        myAudio.audioProgressContral()
    }
}

function DefinedAudio(voiceList,progressRemW){
    this.voiceList=voiceList;//歌曲列表
    this.timer='';//计时器
    this.ProgressW=progressRemW*document.documentElement.clientWidth/640*100;//进度条长度
    var that=this;
    this.init=(function(){
        that.createAudio();
        that.audioInit();
        that.play();
        that.audioProgressContral();
    })();
}
//创建audio标签
DefinedAudio.prototype.createAudio=function(){//创建audio
    this.audio = document.createElement('audio');
    document.body.appendChild(this.audio);
}
//初始audio
DefinedAudio.prototype.audioInit=function(){//初始化
    var that=this;
    this.audio.pause();
    $('.voice').css('background-image','url(../images/pause_03.png)')
    $('.bar').css('left', 0);
    clearInterval(this.timer);
    $('.current').html('00:00');
    var curIndex = $('.swiper-pagination-current').html() - 1;
    this.audio.src = 'http://microblog.people.com.cn/htmlfile/xfAudio/' + this.voiceList[curIndex]+'?'+Math.random();
    var ua = navigator.userAgent.toLowerCase();
    if (/iphone|ipad|ipod/.test(ua)) {//苹果设备预加载
        this.audio.play()
        this.audio.addEventListener('canplay', function () {
            that.audio.pause();
            var time = that.timeFormat(that.audio.duration);
            $('.duration').html(time);
        }, false);
    } else {
        this.audio.addEventListener('canplay', function () {
            var time = that.timeFormat(that.audio.duration);
            $('.duration').html(time);
        }, false)
    }
}
//时间格式换
DefinedAudio.prototype.timeFormat=function (time) {
    var min = Math.floor(time / 60);
    var sec = Math.floor(time % 60);
    min = min < 10 ? "0" + min : "" + min;
    sec = sec < 10 ? "0" + sec : "" + sec;
    return min + ":" + sec;
}
//手动控制音频进度
DefinedAudio.prototype.audioProgressContral=function (){
    var that=this;
    var bar= $('.bar')[$('.swiper-pagination-current').html()-1];
    bar.addEventListener('touchstart',start,false);
    bar.addEventListener('touchmove',move,false)
    bar.addEventListener('touchend',end,false)
    function start(e){
        that.audio.L=$('.bar').css('left');
        that.audio.X=e.touches[0].clientX
        if(that.audio.paused){
            that.audio.ProgressFlag=1;
        }else{
            that.audio.ProgressFlag=0;
        }
        return false;
    }
    function move(e){
        that.audio.changeX=e.changedTouches[0].clientX-that.audio.X;
        that.audio.changeX=that.audio.changeX+parseFloat(that.audio.L)
        that.audio.endX=that.audio.changeX<0?0:(that.audio.changeX>that.ProgressW?that.ProgressW:that.audio.changeX)
        $('.bar').css('left',that.audio.endX);
        that.audio.currentTime=that.audio.endX/that.ProgressW*that.audio.duration;
        var time = that.timeFormat(that.audio.currentTime);
        $('.current').html(time);
        return false;
    }
    function end(e){
        if(that.audio.ProgressFlag!==1){
            that.audio.play();
        }else{
            that.audio.pause();
        }
        return false;
    }
}
//播放与暂停
DefinedAudio.prototype.play=function () {
    var that=this;
    clearInterval(this.timer);
    if (this.audio.paused) {
        this.audio.play();
        $('.voice').css('background-image','url(../images/play_03.png)')
    } else {
        this.audio.pause();
        $('.voice').css('background-image','url(../images/pause_03.png)')
        clearInterval(this.timer);
        return;
    }
    //进度条
    progress()
    this.timer = setInterval(progress, 1000);
    function progress() {
        if (that.audio.currentTime > that.audio.duration) {
            clearInterval(that.timer);
        }
        var time = that.timeFormat(that.audio.currentTime);
        $('.current').html(time);
        var $bar = $('.bar');
        $bar.css('left', that.audio.currentTime / that.audio.duration * 100 + "%");
    }
}
//控制音量(volume 属性设置或返回音频的音量,从 0.0 (静音) 到 1.0 (最大声)。)
DefinedAudio.prototype.vol=function(n){
    this.volume = n;
}
//实例
var myAudio=new DefinedAudio(voiceList,'3.4');
$('.voice').on('click',function(){
    myAudio.play();
})
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容