音频(audio)自定义样式以及控制操作面板

简介

audio为html5中的新属性。定义声音,比如音乐或者其他的音频流。在ie8(包括)以及更早的版本并不支持。

我的自以为

一直以为自定义样式,就要添加相应的控制js代码,所以是望而却步。此次项目中正好出现了这一题目,而jacques同学则完美的呈现了这个音频效果。so决定学习一下,并且记录一下,有理解错误或者不能理解的地方还希望jacques给指教一下。

样式

audio默认提供一个控制面板,这个控制面板则可以由我们自己来定义其显示状态
html代码

<div class="Audio">
    <audio id="audioTag" src="http://cdn.xxtao.com/cms/audio/yesterday once more.mp3" ></audio>
    <div class="pgs">
        <div class="pgs-play" id="progress" style="width: 20%;"></div>
        <img src="images/progress.png">
    </div>
    <div class="controls">
        <span class="played-time">00:00</span>
        <button class="play-pause" id="playPause">
            <span class="icon-btn icon-play"></span>
        </button>
        <span class="audio-time" id="audioTime">0</span>
    </div>
</div>

css代码

.Audio{position: relative; width: 500px; margin: 0 auto;}
.pgs{width: 326px; margin: 0 auto 30px; background-color: #E3E8EE; text-align: center; position: relative; overflow: hidden; height: 35px;}
.pgs-play{position: absolute; top:0; left: 4.65%; width: 0; height: 100%; background-color: #4785f9; z-index: 1;}
.pgs img{width: 100%; position: relative; z-index: 2;}
.audio-name{position: absolute; top: 0; width: 100%; left: 0;text-align: center; color: #666; font-size: 12px;}
.controls{width: 100%; height: 40px; padding: 0; text-align: center;}
.play-pause{border: 0; outline: 0; padding: 0; width: 40px; height: 40px; margin: 0 28px; background: none; display: inline-block; vertical-align: middle;}
.icon-play{width: 40px; height: 40px; background: url(images/play.png) no-repeat; display: block; color: #478f59;}
.icon-pause{width: 40px; height: 40px; background: url(images/pruse.png) no-repeat; display: block; color: #478f59;}
.controls span{color: #b3b5b7; font-size: 12px; display: inline-block; width: 34px;}
.audio-time{display: inline-block; vertical-align: middle;}

呈现的页面

自定义音频页面

html和css上面没什么太多可说的。进度条那里主要运用的就是position定位,我以为灰色的进度和蓝色的进度分别用了两张图片,控制蓝色图片的宽度即可。然而我在查看样式的时候只发现了一张图片,原来灰色的进度图片中由灰色的线条组成,每一个组成的竖条都是透明的,因此能透过它下面的背景,设置进度时需要控制下面背景div的宽度。

js(重点来了)

一、首先要获取元素
var audio = $('#audioTag').get(0);

为什么要加0?因为js操作获得的是audio对象,jquery获得的是jquery对象,[0]对象才是对应的节点对象,所以不能直接用jquery对象操作。

二、控制按钮暂停和播放
pause/play控制按钮
$('#playPause').click(function(){
        //改变暂停/播放icon
        if(audio.paused){
            audio.play();
            $('.icon-btn').removeClass('icon-play').addClass('icon-pause')
        } else{
            audio.pause();
            $('.icon-btn').removeClass('icon-pause').addClass('icon-play')
        }
    })

paused为音频的暂停事件,play为音频的播放事件

三、获取音频的总时长
音频总时长
 $('#audioTag').on("loadedmetadata",function () {
        //alert(audio.duration)
        $('#audioTime').text(transTime(this.duration));
    });
!注意:此处的$('#audioTag')加载loadedmetadata事件不需要get(0);

loadedmetadata事件为音频/视频文件加载完数据后触发
duration 获取音频的时长,单位为s
transTime为封装好的一个函数,目的是将秒转换为几分几秒的格式

//转换音频时长显示
function transTime(time) {
    var duration = parseInt(time);
    var minute = parseInt(duration/60);
    var sec = duration%60+'';
    var isM0 = ':';
    if(minute == 0){
        minute = '00';
    }else if(minute < 10 ){
        minute = '0'+minute;
    }
    if(sec.length == 1){
        sec = '0'+sec;
    }
    return minute+isM0+sec
}

parseInt(duration/60) 是将秒转换为整分
duration%60 是取余,也就是整分后剩余的秒
minute+isM0+sec 就是分:秒(02:14)的格式

四、监听音频播放时间并更新进度条
进度条和播放时间
audio.addEventListener('timeupdate',updateProgress,false);

timeupdate 事件是在播放位置改变时触发
updateProgress为封装好的一个函数,里面处理了进度条的位置和当前播放时间

//更新进度条
function updateProgress() {
    var audio =document.getElementsByTagName('audio')[0]; //js获取的方式
    var value = Math.round((Math.floor(audio.currentTime) / Math.floor(audio.duration)) * 100, 0);
    $('.pgs-play').css('width', value * 0.907 + '%');
    $('.played-time').html(transTime(audio.currentTime));
}

value是由当前时间/总长 再乘以一个100变成百分数
0.907来源:因为进度条的长度和音频的背景图片不相同,才有的这么一个比例(进度条div的宽度除以背景img的宽度)。如果他们俩的长度一样,就直接value就可以。
currentTime 获得当前播放时间,一般和timeupdate事件联合使用

五、点击进度条跳到指定播出位置
 var pgsWidth = $('.pgs img').width()*0.907; //此0.907同上一个0.907
    $('.pgs img').click(function (e) {
        var rate = (e.offsetX - ($(this).width()-pgsWidth)/2)/pgsWidth;
        audio.currentTime = audio.duration * rate;
        updateProgress();
    });

rate 原理待定

六、播放完成
 audio.addEventListener('ended',audioEnded,false);

ended 为监听播放完成事件
audioEnded为封装好的一个函数,里面处理了置音频的播放时间等为初始值

//播放完成
function audioEnded() {
    var audio =document.getElementsByTagName('audio')[0];
    audio.currentTime=0;
    audio.pause();
    $('.play-pause>span').removeClass('icon-pause').addClass('icon-play');
}
七、至此,js部分全代码如下:
$(function(){

    var audio = $('#audioTag').get(0);
    //播放暂停控制
    $('#playPause').click(function(){

        //监听音频播放时间并更新进度条
        audio.addEventListener('timeupdate',updateProgress,false);
        //监听播放完成事件
        audio.addEventListener('ended',audioEnded,false);


        //改变暂停/播放icon
        if(audio.paused){
            audio.play();
            $('.icon-btn').removeClass('icon-play').addClass('icon-pause')
        } else{
            audio.pause();
            $('.icon-btn').removeClass('icon-pause').addClass('icon-play')
        }
    })

    //读取视频长度,设置页面时长显示-loadedmetadata:指定视频/音频(audio/video)的元数据加载后触发
    //audio.duration 获取音频的时长,单位为秒
    $('#audioTag').on("loadedmetadata",function () {
        //alert(audio.duration)
        $('#audioTime').text(transTime(this.duration));
    });

    var pgsWidth = $('.pgs img').width()*0.907; //0.907是 进度条这个div和整个进度条图片宽度的比例
    //点击进度条跳到指定点播放
    $('.pgs img').click(function (e) {

        var rate = (e.offsetX - ($(this).width()-pgsWidth)/2)/pgsWidth;
        audio.currentTime = audio.duration * rate;
        updateProgress();
    });

})
//转换音频时长显示
function transTime(time) {
    var duration = parseInt(time);
    var minute = parseInt(duration/60);
    var sec = duration%60+'';
    var isM0 = ':';
    if(minute == 0){
        minute = '00';
    }else if(minute < 10 ){
        minute = '0'+minute;
    }
    if(sec.length == 1){
        sec = '0'+sec;
    }
    return minute+isM0+sec
}

//更新进度条
function updateProgress() {
    var audio =document.getElementsByTagName('audio')[0];
    var value = Math.round((Math.floor(audio.currentTime) / Math.floor(audio.duration)) * 100, 0);
    $('.pgs-play').css('width', value * 0.907 + '%');
    $('.played-time').html(transTime(audio.currentTime));


}
//播放完成
function audioEnded() {
    var audio =document.getElementsByTagName('audio')[0];
    audio.currentTime=0;
    audio.pause();
    $('.play-pause>span').removeClass('icon-pause').addClass('icon-play');
}
End

本文介绍到此结束,其实还有好多别的控制,比如音量大小,快退快进等。原理明白后,一切都好说。有些时候就是这样,感觉是个庞然大物,其实了解之后并没有想象的复杂。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,064评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,606评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,011评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,550评论 1 269
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,465评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,919评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,428评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,075评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,208评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,185评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,191评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,914评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,482评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,585评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,825评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,194评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,703评论 2 339

推荐阅读更多精彩内容