说明
应用于微信中,详情页播放音频,列表页循环播放多个音频
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支持