一 概述
- 常用组件及API介绍
- 播放器页面任务
- 播放器页面任务
- 数据准备
- 音乐播放功能
- 播放器页面
二 常用组件及API介绍
2.1 音频API
介绍
-
微信小程序提供了播放音频的API,掌握这个API的使用方法是实现音乐播放的关键。
-
在使用音频API时,需要通过如下代码创建一个InnerAudioContext实例,audioCtx就是一个InnerAudioContext实例,也就是一个对象,利用这个对象的属性和方法可以完成具体的工作
var audioCtx=wx.createInnerAudioContext()
常用属性和方法
类型 | 名称 | 说明 |
---|---|---|
属性 | src | 音频资源的地址,用于直接播放 |
startTime | 开始播放的位置(s),默认为0 | |
autoplay | 是否自动开始播放,默认为false | |
loop | 是否循环播放,默认为false | |
volume | 音量。范围0~1。默认为1 | |
duration | 音频的长度(s)。在当前有合法的src时返回(只读) | |
currentTime | 音频的播放位置(s)。在当前有合法的src时返回(只读) | |
paused | 当前是否暂停或停止状态(只读) | |
方法 | play() | 播放 |
pause() | 暂停(暂停后的音频再播放会从暂停处开始播放) | |
stop() | 停止(停止后的音频再播放会从头开始播放) | |
seek() | 跳转到指定位置 | |
destroy | 销毁当前实例 | |
onCanPlay() | 音频进入可以播放状态的事件(参数为回调函数) | |
onPlay() | 音频播放事件(参数为回调函数) | |
onPause() | 音频暂停事件(参数为回调函数) | |
onStop() | 音频停止事件(参数为回调函数) | |
onEnded() | 音频自然播放至结束的事件(参数为回调函数) | |
onSeeked() | 音频进行跳转操作的事件(参数为回调函数) | |
onTimeUpdate() | 音频播放进度更新事件(参数为回调函数) | |
onError() | 音频播放错误事件(参数为回调函数) |
如何使用
onReady: function () {
//创建InnerAudioContext实例
var audioCtx=wx.createInnerAudioContext()
//设置音频资源地址
audioCtx.src='http://music.163.com/song/media/outer/url?id=5254524.mp3'
//当开始播放时,输出调试信息
audioCtx.onPlay(function(){
console.log('开始播放')
})
//当发生错误时,输出信息
audioCtx.onError(function(res){
console.log(res.errMsg) //错误信息
console.log(res.errCode) //错误码
})
//开始播放
audioCtx.play()
},
2.2 slider组件
说明
slider组件是小程序表单组件中的一种,用于滑动选择某一个值,在本项目中将用来实现播放器的进度条
常用属性
属性 | 类型 | 说明 |
---|---|---|
min | Number | 最小值,默认为0 |
max | Number | 最大值,默认为100 |
step | Number | 步长,取值大于0,可被(max-min)整除,默认为1 |
value | Number | 当前取值,默认为0 |
activeColor | Color | 已选择的颜色,默认为#1aad19 |
backgroundColor | Color | 背景条的颜色,默认为#e9e9e9 |
block-size | Number | 滑块的大小,取值范围为12~28,默认为28 |
block-color | Color | 滑块的颜色,默认为#ffffff |
show-value | Boolean | 是否显示当前value,默认为false |
bindchange | EventHandle | 完成一次拖动后触发的事件 |
bindchanging | EventHandle | 拖动过程中触发的事件 |
基本使用
布局文件中:
<slider bindchanging="sliderChanging" show-value />
代码中:
sliderChanging:function(e)
{
console.log(e.detail.value)
}
三 播放器页面任务
- 音乐信息:显示当前播放曲目的标题和艺术家
- 专家封面:当音乐播放时,专辑封面会顺时针旋转
- 播放进度:显示当前曲目的播放时长和总时长,并提供一个进度条,当音乐播放时进度条就会增长,用户也可以手动改变进度条的进度来跳转播放进度
四 数据准备
4.1 音乐外链平台
4.2 定义基础数据
路径
pages/index/index.js文件的data对象定义基础数据playlist
数据
data: {
item:0,
tab:0,
playlist:[{
id:1,title:'钢琴协奏曲',singer:'肖邦',
src:'http://music.163.com/song/media/outer/url?id=419485661.mp3',
coverImgUrl:'../../images/music.png'
},{
id:2,title:'奏鸣曲',singer:'莫扎特',
src:'http://music.163.com/song/media/outer/url?id=1394618521.mp3',
coverImgUrl:'../../images/music.png'
},{
id:3,title:'欢乐颂',singer:'贝多芬',
src:'http://music.163.com/song/media/outer/url?id=383064.mp3',
coverImgUrl:'../../images/music.png'
},{
id:4,title:'爱之梦',singer:'李斯特',
src:'http://music.163.com/song/media/outer/url?id=5276814.mp3',
coverImgUrl:'../../images/music.png'
},
],
state:'paused',
playIndex:0,
play:{
currentTime:'00:00',
duration:'00:00',
percent:0,
title:'',
singer:'',
coverImgUrl:'../../images/music.png'
}
},
playlist数据说明
- id:每条记录的唯一标识
- title:曲目标题
- singer:艺术家
- src:网络中的音频文件链接地址
- coverImgUrl:专辑封面图片的链接地址
音乐状态属性
- state:音乐的播放状态,paused表示暂停,running表示播放
- playIndex:当前播放曲目在播放列表数组中的索引值
- play:当前播放曲目的信息
- currentTime:播放时长
- duration:总时长
- percent:播放进度
- title:当前播放的曲目标题
- singer:当前播放的曲目的艺术家
- coverImgUrl:当前播放的曲目的专辑封面
五 音乐播放功能(底部播放器)
5.1 布局文件(pages/index/index.wxml)
<view class="player">
<image class="player-cover" src="{{play.coverImgUrl}}" />
<view class="player-info">
<view class="player-info-title">{{play.title}}</view>
<view class="player-info-singer">{{play.singer}}</view>
</view>
<view class="player-controls">
<!--切换到播放列表-->
<image src="../images/list.png" bindtap="changePage" data-page="2" />
<!--播放-->
<image wx:if="{{state=='paused'}}" src="../images/Play.png" bindtap="play"/>
<image wx:else src="../images/Pause.png" bindtap="pause"/>
<!--下一曲-->
<image src="../images/rewind-right.png" bindtap="next"/>
</view>
5.2 样式文件(pages/index/index.wxss)
.player{
display: flex;
align-items: center;
background: #222;
border-top: 1px solid #252525;
height: 112rpx;
}
.player-cover{
width: 80rpx;
height: 80rpx;
margin-left: 15rpx;
border-radius: 8rpx;
border:1px solid #333;
}
.player-info{
flex:1;
font-size: 10pt;
line-height: 38rpx;
margin-left: 20rpx;
padding-bottom: 8rpx;
}
.player-info-singer{
color: #888;
}
.player-controls image{
width:80rpx;
height: 80rpx;
margin-right: 15rpx;
}
5.3 逻辑文件(pages/index/index.js)
audioCtx:null,
onReady: function () {
this.audioCtx=wx.createInnerAudioContext()
//默认选中第1曲
this.setMusic(0)
},
setMusic:function(index){
var music=this.data.playlist[index]
this.audioCtx.src=music.src
this.setData({
playIndex:index,
'play.title':music.title,
'play.singer':music.singer,
'play.coverImgUrl':music.coverImgUrl,
'play.currentTime':'00:00',
'play.duration':'00:00',
'play.percent':0
})
},
play:function(){
this.audioCtx.play()
this.setData({state:'running'})
},
pause:function(){
this.audioCtx.pause()
this.setData({state:'paused'})
},
next:function(){
var index=this.data.playlist>=this.data.playlist.length-1?0:this.data.playIndex+1
this.setMusic(index)
if(this.data.state=='running'){
this.play()
}
},
5.4 效果
六 播放器页面
6.1 布局文件(pages/index/play.wxml)
<view class="content-play">
<!--显示音乐信息-->
<view class="content-play-info">
<text>{{play.title}}</text>
<view>——{{play.singer}}——</view>
</view>
<!--显示专辑封面-->
<view class="content-play-cover">
<image src="{{play.coverImgUrl}}" style="animation-play-state:{{state}}"/>
</view>
<!--显示播放进度和时间-->
<view class="content-play-progress">
<text>{{play.currentTime}}</text>
<view>
<slider bindchange="sliderChange" activeColor="#d33a31" block-size="12" bindchange="#dadada" value="{{play.percent}}" />
</view>
<text>{{play.duration}}</text>
</view>
</view>
6.2 样式文件(pages/index/index.wxss)
.content-play{
display: flex;
justify-content: space-around;
flex-direction: column;
height: 100%;
text-align: center;
}
.content-play-info>view{
color: #888;
font-size: 11pt;
}
.content-play-cover image{
animation:rotateImage 10s linear infinite;
width: 400rpx;
height: 400rpx;
border-radius: 50%;
border: 1px solid #333;
}
@keyframes rotateImage{
from {
transform:rotate(0deg);
}
to {
transform:rotate(360deg);
}
}
.content-play-progress{
display: flex;
align-items: center;
margin:0 35rpx;
font-size:9pt;
text-align: center;
}
.content-play-progress>view{
flex:1;
}
6.3 逻辑文件(播放进度)
onReady: function () {
this.audioCtx=wx.createInnerAudioContext()
var that=this;
//播放失败检测
this.audioCtx.onError(function(){
console.log('播放失败:'+that.audioCtx.src)
})
//播放完成自动换下一曲
this.audioCtx.onEnded(function(){
that.next()
})
//自动更新播放进度
this.audioCtx.onPlay(function(){ })
this.audioCtx.onTimeUpdate(function(){
that.setData({
'play.duration': formatTime(that.audioCtx.duration),
'play.currentTime': formatTime(that.audioCtx.currentTime),
'play.percent': that.audioCtx.currentTime/that.audioCtx.duration*100
})
})
//默认选择第1曲
this.setMusic(0)
//格式化时间
function formatTime(time){
var minute=Math.floor(time/60)%60;
var second=Math.floor(time)%60
return (minute<10?'0'+minute:minute)+':'+(second<10?'0'+second:second)
}
},
sliderChange:function(e){
var second=e.detail.value*this.audioCtx.duration/100
this.audioCtx.seek(second)
},
6.4 效果图
版权声明:本文为Calvin_zhou原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。