分享站又有新功能了:将文件站上的语音文件正确播放出来。效果图:
暂停:
播放:
实现的效果:类似于音乐播放器一般,但是较之更简单一些,可以正常播放语音,有拖动、快进后退效果便可。
思路:
首先想到的便是利用H5中的audio标签来实现
<audio> 标签定义声音,比如音乐或其他音频流。
可是最终却发现原始的H5标签播放的音频效果,有点太牵强,其美观程度远远达不到我们预期的,于是只能摒弃这样的想法,另辟蹊径了。最终想到最完美的解决方案依旧是利用H5的audio标签,但是得重新定义它的滚动条以及前进、快退等事件。
参考资料:
HTML <audio>标签 http://www.w3school.com.cn/tags/tag_audio.asp
HTML 5 视频/音频参考手册 http://www.w3school.com.cn/tags/html_ref_audio_video_dom.asp
拜读:https://segmentfault.com/a/1190000007332028
主要代码:
<div class="container"> <div class="starter-template"> <h1>{{data.title}}</h1> <div class="vicoebox"> <div class="vicoebox-img"> <a href="javascript:void(0)" onclick="audioplay()" class="btn-play"></a> <img src="{{imgSiteUrl}}{{img}}" width="190" height="190"/> </div> <audio id="audio" preload type="audio/mpeg" src="{{imgSiteUrl}}{{data.content}}"></audio> <!-- 语音控制模块开始 --> <div class="g-panel"> <div class="m-progress m-progress-song"> <div id="songprogress" class="progress"></div> <div id="songbar" class="progressbar"></div> <ul class="songtime"> <li class="start" id="start">0:00</li> <li class="end" id="end">0:00</li> </ul> </div> </div> </div> <!-- 语音控制模块结束 --> </div> </div>
js:
<script type="text/javascript"> jQuery('.btn-play').click(function () { if (jQuery(this).hasClass("btn-play")) { audio.play(); jQuery(this).removeClass('btn-play').addClass('btn-pause'); } else { audio.pause(); jQuery(this).removeClass('btn-pause').addClass('btn-play'); } }); //---------------------------------工具方法开始 var Util = function () { // 格式化时间为分:秒的形式 function formatTime(seconds, curS) { var totalS = parseInt(seconds); var minute = Math.floor((totalS / 60)); var second = totalS - minute * 60; second = second < 10 ? ("0" + second) : second; return minute + ":" + second; } // 将时间转化为百分比 function timeToPercent(curS, totalS) { var percent = parseInt((Number(curS) / Number(totalS)) * 100) + "%"; return percent; } // 更新时间 function updateTime(dom, seconds) { var result = formatTime(seconds); dom.html(result); } // 更新进度条 function updateProgress(dom, percent) { dom.css("width", percent); return true; } // 更新进度滑块 function updateBarPos(dom, percent) { dom.css("left", percent); return true; } return { formatTime: formatTime, updateTime: updateTime, updateProgress: updateProgress, updateBarPos: updateBarPos, timeToPercent: timeToPercent, }; }(); //---------------------------------工具方法结束 //更新结束时间 jQuery("#audio")[0].addEventListener("loadedmetadata", function () { duration = this.duration;//获取总时长 formatDuration = Util.formatTime(duration); jQuery('.end').html(formatDuration); }); function audioplay() { var audio = jQuery("#audio")[0]; var start = jQuery('.start');//开始时间 var end = jQuery('.end');//结束时间 var sprocontainer = jQuery(".m-progress-song");//歌曲进度条容器 var sProgress = jQuery("#songprogress"); var songbar = jQuery("#songbar");//歌曲进度条滑块 // 监听歌曲播放时间发生变化事件 audio.addEventListener("timeupdate", function () { var curS = audio.currentTime; var duration = audio.duration; var curPercent = Util.timeToPercent(curS, duration); // 更新歌曲时间,进度条 Util.updateTime(start, curS);//更新开始时间 Util.updateProgress(sProgress, curPercent); Util.updateBarPos(songbar, curPercent); }); //歌曲进度条滑块滑动事件 songbar.on("touchstart", function (e) { e.preventDefault(); e.stopPropagation(); jQuery(audio).off("timeupdate"); audio.pause(); var totalW = jQuery(sprocontainer).width(); //播放条容器总长度 var leftDis = jQuery(sProgress).offset().left; var curS = 0; var curPercent = 0; var percent = ""; var touchMove = e.originalEvent.changedTouches[0].clientX; var dis = e.originalEvent.changedTouches[0].clientX - leftDis; songbar.on("touchmove", function (e) {//当触点在触控平面上移动时触发touchmove事件 e.preventDefault(); e.stopPropagation(); touchMove = e.originalEvent.targetTouches[0].clientX; dis = touchMove - leftDis > totalW ? totalW : touchMove - leftDis; dis = touchMove - leftDis < 0 ? 0 : dis; percent = Math.floor(dis / totalW * 100) + "%"; Util.updateProgress(sProgress, percent); Util.updateBarPos(songbar, percent); }); songbar.on("touchend", function (e) {//当手指从屏幕上离开的时候触发 e.preventDefault(); e.stopPropagation(); if (audio.paused) { audio.play(); jQuery('.btn-play').removeClass('btn-play').addClass('btn-pause'); } percent = Math.floor(dis / totalW * 100) + "%"; Util.updateProgress(sProgress, percent); Util.updateBarPos(songbar, percent); duration = audio.duration; curS = duration * parseInt(percent.replace("%", "")) / 100; audio.currentTime = curS; audio.ontimeupdate = function () { var curS = audio.currentTime; var curPercent = Util.timeToPercent(curS, duration); // 更新歌曲时间,进度条 Util.updateTime(start, curS); Util.updateProgress(sProgress, curPercent); Util.updateBarPos(songbar, curPercent); }; songbar.off("touchmove touchend"); }); }); // 歌曲进度条点击事件 sprocontainer.on("mousedown", function (e) { var totalW = jQuery(sprocontainer).width(); var leftDis = jQuery(sProgress).offset().left; var curS = 0; var curPercent = 0; var dis = e.pageX - leftDis > totalW ? totalW : e.pageX - leftDis; percent = Math.floor(dis / totalW * 100) + "%"; sprocontainer.on("mouseup", function (e) { Util.updateProgress(sProgress, percent); Util.updateBarPos(songbar, percent); duration = audio.duration; curS = duration * parseInt(percent.replace("%", "")) / 100; audio.currentTime = curS; audio.ontimeupdate = function () { var curS = audio.currentTime; var curPercent = Util.timeToPercent(curS, duration); // 更新歌曲时间,进度条 Util.updateTime(start, curS); Util.updateProgress(sProgress, curPercent); Util.updateBarPos(songbar, curPercent); }; sprocontainer.off("mouseup"); }); }); // 歌曲播放完毕事件 audio.onended = function() { jQuery('.btn-pause').removeClass('btn-pause').addClass('btn-play'); }; } </script>
遇到的问题:
1.duration 获取歌曲的总时间:H5中有获取duration的方法,基本在音频播放的事件里,此属性起到了至关重要的作用;
2.移动端的触摸事件:touchstart、touchend、touchmove:
touchstart事件:当手指触摸屏幕时候触发,即使已经有一个手指放在屏幕上也会触发;
touchmove事件:当手指在屏幕上滑动的时候连续地触发。在这个事件发生期间,调用preventDefault()事件可以阻止滚动;
touchend事件:当手指从屏幕上离开的时候触发。
而每个Touch对象包含的属性如下;
clientX:触摸目标在视口中的x坐标;
clientY:触摸目标在视口中的y坐标;
identifier:标识触摸的唯一ID;
pageX:触摸目标在页面中的x坐标;
pageY:触摸目标在页面中的y坐标;
screenX:触摸目标在屏幕中的x坐标;
screenY:触摸目标在屏幕中的y坐标;
target:触目的DOM节点目标。
关于这三个事件,其实挺有意思的:虽然自己之前很少接触过移动端的开发,但是总是被身边同事的各种“神技能”震撼到,而当自己真的将别人手中的“神技能”实现时,还是挺有成就感的,总感觉一切就是那样神奇(哈哈……这也是为什么喜欢这份工作的原因,乐在其中。);
3.鼠标事件中的mousedown、mouseup(这两种事件见得次数多了,也便不赘述了)。
滴答滴答前进中:
乐在其中,还需要永不止步。