分享站又有新功能了:将文件站上的语音文件正确播放出来。效果图:

暂停:

播放:

实现的效果:类似于音乐播放器一般,但是较之更简单一些,可以正常播放语音,有拖动、快进后退效果便可。

思路:

首先想到的便是利用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(这两种事件见得次数多了,也便不赘述了)。

滴答滴答前进中:

乐在其中,还需要永不止步。

音频——H5 audio的更多相关文章

  1. h5 audio播放音频文件

    h5 audio播放音频文件 注:下面html中样式及不相关的内容去掉了 第一个例子 播放没有防盗链的外网音频文件是可以的 <!doctype html> <html> < ...

  2. H5 <audio> 音频标签自定义样式修改以及添加播放控制事件

    H5 <audio> 音频标签自定义样式修改以及添加播放控制事件 Dandelion_drq 关注 2017.08.28 14:48* 字数 331 阅读 2902评论 3喜欢 3 说明: ...

  3. h5 audio进度条

    h5 audio 播放进度条 效果图: html部分: <div class="audiojindu"> <div class="playcontrol ...

  4. H5 audio标签

    37-audio标签 注意点: audio标签的使用和video标签的使用基本一样, video中能够使用的属性在audio标签中大部分都能够使用, 并且功能都一样 只不过有3个属性不能用, heig ...

  5. H5 audio 通过canplaythrough预加载音乐

    1.背景 微信里做H5活动页面,对音乐使用autoplay, android没问题,IOS半天播不出来,因此考虑对音乐进行预加载(不是preload) <!DOCTYPE html> &l ...

  6. h5 audio播放问题,audio获取缓存进度条

    <!--全局 audio --> <audio id="audio" @playing="audioReady" @timeupdate=&q ...

  7. h5 audio标签在手机上不能自动播放????

    最近在做一个微信端的项目,快到接近尾声的时候,发现还没放入音频,于是乎,放入音频,在电脑端测试一切正常,无阻碍. 后来在手机上测试,发现背景音乐不能播放,于是开始找错,刚开始以为是IIS服务器出错,结 ...

  8. 多媒体音频(audio)

    随着计算机技术的发展,特别是海量存储设备和大容量内存在PC机上的实现,对音频媒体进行数字化处理便成为可能.数字化处理的核心是对音频信息的采样,通过对采集到的样本进行加工,达成各种效果,这是音频媒体数字 ...

  9. 如何让windows版Safari支持H5 audio/video?

    今天在windows版Safari上看效果的时候惊奇地发现它竟然不支持HTML5的audio/video, 这样的话就无法复现不少ios上出现的问题. 在同事提醒下, 发现Safari HTML5 A ...

随机推荐

  1. 两个有序单链表合并成一个有序单链表的java实现

    仅作为备注, 便于自己回顾. import java.util.Arrays; public class MergeSort { public static class LinkedNode<V ...

  2. HashMap的最大容量为什么是2的30次方?

    今天看HashMap的底层实现,发现HashMap的最大容量规定为: // 最大容量(必须是2的幂且小于2的30次方,传入容量过大将被这个值替换) static final int MAXIMUM_C ...

  3. Self20171218_Assert断言使用

     一.Assert用法: assertion(断言)在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制.在实现中,assertion就是在程序中的一条语句,它对一个boolean表达式进行 ...

  4. Axiom3D:Ogre中Mesh文件格式分析(一)

    在Axiom3D,或者说是Ogre的mesh的文件格式我们可能通过代码反推出相关格式,相关过程本来我是直接写的,后面发现相关流程写完后,我自己都看晕了,然后我就把一些过程用Execl整理出来,发现过程 ...

  5. java.sql.SQLException: Value '0000-00-00 00:00:00' can not be represented as java.sql.Date

    架构使用jsp+servlet+java+mysql mysql里time字段类型为datetime java实体类中该字段类型为Date 页面中,时间字段类型为空的信息显示不出来,且报错信息如下: ...

  6. 第三百三十七节,web爬虫讲解2—PhantomJS虚拟浏览器+selenium模块操作PhantomJS

    第三百三十七节,web爬虫讲解2—PhantomJS虚拟浏览器+selenium模块操作PhantomJS PhantomJS虚拟浏览器 phantomjs 是一个基于js的webkit内核无头浏览器 ...

  7. googletest进行单元测试(使用cmake编译)

    一.前提: 1.假定你的系统为centos6系列 2.假定你已经安装了基本的编译环境,gcc,g++4.4.7 3.假定你已经设置了环境变量:KDS_MOBILE_STOCK_HOME 4.假定你已经 ...

  8. HttpURLConnection如何添加请求头?

    1.conn.setRequestProPerty(name,value),两个参数都是字符串.... 2.用httpURLConnection的setRequestProPerty(name,val ...

  9. 父组件中vuex方法更新state,子组件不能及时更新并渲染的解决方法

    场景: 我实际用到的是这样的,我父组件引用子组件related,父组件调用获取页面详情的方法,更新了state值related,子组件根据该related来渲染相关新闻内容,但是页面打开的时候总是先加 ...

  10. virtualbox谨记:win7上只有4.3.x的版本支持ubuntu14.04.3虚拟机安装Oracle Rac,其他的版本3.x和5.0.2(至2015-08-30)均不可以

    virtualbox谨记:win7上只有4.3.x的版本支持ubuntu14.04.3虚拟机安装Oracle Rac,其他的版本3.x和5.0.2(至2015-08-30)均不可以