irpas技术客

微信小程序开发———音乐播放器_凉沫serendipity_微信小程序音乐播放器

未知 2888

目录

一 小程序主体功能介绍

二 常用组件和API介绍

音频API

常用组件

三 整体布局

数据定义

主体页面

运行效果

四 播放器页面

布局部分

样式部分

运行效果

五 播放列表页面

布局部分

样式部分

运行效果

全部功能实现代码index.js


一 小程序主体功能介绍

本小程序主要实现,音乐的播放、暂停,下一曲的切换,以及播放列表和当前播放歌曲的详细信息查看等。

二 常用组件和API介绍 1.音频API

1.1 介绍

创建音频时需要先创建一个对象实例,从而引用该对象的方法和属性。

var audioCtx=wx.createInnerAudioContext()

1.2 常用属性方法

属性

src:音频资源的地址;

autoplay:是否自动播放,默认false;

loop: 是否循环播放,默认为false;

startTime: 开始播放的位置,默认为0;

currentTime: 当前播放的位置;

duration: 音频的长度;

paused:当前暂停或停止的状态;

方法

play(): 播放;

stop(): 停止,再播放重头开始;

pause(): 暂停,再播放从当前位置开始;

seek():? 跳到指定的位置;

onError(): 音频播放错误事件;

onEnded(): 音频自然播放结束事件;

onPlay(): 音频播放事件;

onTimeUpdate(): 音频播放进度更新事件;

2.常用组件

2.1 swiper组件

介绍

swiper组件是滑块视图容器,经常用于实现轮播图,在音乐播放器小程序中可以实现标签页的切换。

属性

属性类型说明indicator-dotsBoolean是否显示页面的指示点,默认为falseindicator-colorColor指示点的颜色indicator-active-colorColor选中的指示点颜色autoplayBoolean是否自动切换,默认为falsecurrentNumber当前所在滑块的index,默认为0current-item-idString当前所在滑块的item-idintervalNumber自动切换时间间隔(ms)durationNumber滑动动画时长(ms)bindchangeEventHandlecurrent改变时会触发change事件circularBoolean是否采用衔接滑动,默认false

代码使用

<swiper current="1"> <swiper-item >0</swiper-item> <swiper-item >1</swiper-item> <swiper-item >2</swiper-item> </swiper>

2.2 include代码引用

介绍

当一个wxml文件中代码过多,或wxml中有部分相同的代码时,可以将他们分离开,用include进行引入。

代码使用

<include src="header.wxml"/> <view>body</view> <include src="footer.wxml" />

2.3 scroll-view组件

介绍

scroll-view组件用于实现可滚动视图区域。一般来说,当页面高度超出了显示区域的高度时,先设置外层容器高度,使其低于内部容器高度,然后在外层容器样式中设置滚动方向即可。

属性

属性说明scroll-x

允许横向滚动,默认为false

scroll-y允许纵向滚动,默认为falsescroll-top设置竖向滚动条的位置scroll-left设置横向滚动条的位置bindscrolltoupper滚动到顶部/左边触发的事件bindscrolltolower

滚动到底部/右边触发的事件

代码使用

<scroll-view scroll-x scroll-y style="height:200px" bindscroll="scroll"> <view style="width:200%; height:400px; background:#ccc"></view> </scroll-view>

在.js页面中可以添加scroll处理函数,来查看具体数值

scroll:function(e){ console.log(e.detail) }

2.4 slider组件

介绍

slider组件是小程序表单组件中的一种,用于滑动选择某一个值,在本项目中将用来实现播放器的进度条

属性

属性说明min最小值,默认为0max最大值,默认为100step步长,取值大于0value当前取值,默认为0activeColor已选择的颜色,默认为#1aad19backgroundColor背景条颜色,默认为#e9e9e9block-size滑块的大小block-color滑块的颜色,默认为#ffffffshow-value是否显示当前value,默认为falsebindchange完成一次拖动后触发的事件bindchanging拖动过程中触发的事件
三 整体布局 1. 数据定义

1.1 路径

pages/index/index.js? 文件的data对象定义基础数据playlist

1.2 数据

data: { item:0, tab:0, // 播放列表 playlist:[{ id:1, title:"纪念", singer:"雷心雨", src:"/images/1.mp3", coverImgUrl:"/images/cover.jpg" },{ id:2, title:"雪落下的声音", singer:"郁可唯", src:"/images/2.mp3", coverImgUrl:"/images/cover2.jpg" },{ id:3, title:"只要平凡", singer:"张杰", src:"/images/3.mp3", coverImgUrl:"/images/cover3.jpg" } ,{ id:4, title:"我会很勇敢", singer:"张雅莉", src:"/images/4.mp3", coverImgUrl:"/images/cover4.jpg" } ], state:"paused", // 播放的索引值 playIndex:0, //设置的默认值 play:{ // 当前时间 currentTime:'00.00', // 总时间 duration:'00.00', // 播放进度 percent:0, title:'', singer:'', coverImgUrl:"/images/cover.jpg", } }, 2. 主体页面

2.1 布局页面index.wxml

<!--index.wxml--> <!-- 标签页标题 --> <view class="tab"> <view class="tab-item {{tab==0 ? 'active' : ''}} " bindtap="changeItem" data-item="0">音乐推荐</view> <view class="tab-item {{tab==1 ? 'active' : ''}}" bindtap="changeItem" data-item="1">播放器</view> <view class="tab-item {{tab==2 ? 'active' : ''}} " bindtap="changeItem" data-item="2">播放列表</view> </view> <!-- 内容区域 --> <view class="content" > <swiper current="{{item}}" bindchange="changeTab"> <swiper-item > <include src="info.wxml"></include> </swiper-item> <swiper-item > <include src="play.wxml"></include> </swiper-item> <swiper-item> <include src="playlist.wxml"></include> </swiper-item> </swiper> </view> <!-- 底部播放器 --> <view class="player"> <image class="player-cover" src="{{play.coverImgUrl}}"></image> <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/play-1.jpg" bindtap="changePage" data-page="2"></image> <!-- 播放或暂停 --> <image wx:if="{{state=='paused'}}" src="/images/play-2.jpg" bindtap="play"></image> <image wx:else src="/images/play-4.jpg" bindtap="pause"></image> <!-- 下一曲 --> <image src="/images/play-3.jpg" bindtap="next"></image> </view> </view>

2.2 样式部分

page{ display: flex; flex-direction: column; background-color: #c8f5fd; color: rgb(22, 17, 13); height: 100%; } .tab{ display: flex; } .tab-item{ flex: 1; font-size: 10pt; text-align: center; line-height: 72rpx; border-bottom: 6rpx solid #eee; } .tab-item.active{ color:#584acf; border-bottom-color:#7c6fee; } .content{ flex: 1; } .content>swiper{ height:100%; } .player{ background: rgb(156, 209, 240); border-top: 1rpx solid #a8ddf8; height: 112rpx; } /* 底部播放器 */ .player{ display: flex; align-items: center; background:rgb(117, 185, 224); border-top: 1rpx solid #7c8dec; height: 112rpx; } /* 覆盖图片设置 */ .player-cover{ width:80rpx; height: 80rpx; margin-left: 15rpx; border-radius: 10rpx; border:2rpx solid rgb(204, 200, 200); } /* 歌曲信息设置 */ .player-info{ flex:1; font-size: 10pt; line-height: 38rpx; margin-left: 20rpx; padding-bottom:8rpx; } .player-info-singer{ color:rgb(189, 214, 245); margin-top: 5rpx; font-size:9pt; } /* 控制按钮设置 */ .player-controls image{ width: 80rpx; height: 80rpx; margin-right: 10rpx; }

2.3 底部播放、切换功能函数实现

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() } }, 3. 运行效果

四 播放器页面 1.布局部分 <view class="content-play"> <!-- 显示音乐信息 --> <view class="content-play-info"> <view>{{play.title}}</view> <view>—— {{play.singer}} ——</view> </view> <!-- 显示专辑封面 --> <view class="content-play-cover"> <image src="{{play.coverImgUrl}}" style="animation-play-state:{{state}}"></image> </view> <!-- 显示播放进度 --> <view class="content-play-progress"> <text>{{play.currentTime}}</text> <view> <!-- activeColor已选择的不生效 --> <slider bindchange="sliderChange" activeColor="#d33a31" block-size="12" backgroundColor="#ccc" value="{{play.percent}}"></slider> </view> <text>{{play.duration}}</text> </view> </view> 2. 样式部分 /* 播放器页面设置 */ .content-play{ display: flex; flex-direction: column; justify-content: space-around; height: 100%; text-align: center; background-color: rgb(203, 235, 243); } .content-play-info{ color: rgb(7, 59, 102); font-size: 11pt; } .content-play-cover image{ animation:rotateImage 10s linear infinite ; width: 400rpx; height:400rpx; border-radius: 50%; border:1rpx solid rgb(245, 241, 241); } @keyframes rotateImage{ from{ transform: rotate(0deg); } to{ transform: rotate(360deg); } } /* 进度条设置 */ .content-play-progress{ display: flex; align-items: center; font-size: 9pt; margin: 0 35rpx; text-align: center; } .content-play-progress >view{ flex: 1; } 3. 运行效果

五 播放列表页面 1.布局部分 <scroll-view class="content-playlist" scroll-y> <view class="playlist-item" wx:for="{{playlist}}" wx:key="id" bindtap="change" data-index="{{index}}"> <image class="playlist-cover" src="{{item.coverImgUrl}}"></image> <view class="playlist-info"> <view class="playlist-info-title">{{item.title}}</view> <view class="playlist-info-singer">{{item.singer}}</view> </view> <view class="playlist-controls"> <text wx:if="{{index==playIndex}}">正在播放</text> </view> </view> </scroll-view> 2.样式部分 /* 播放列表 */ .content-playlist{ background-color: rgb(175, 231, 247); } .playlist-item{ /* 每遍历一个会自动换行 */ display: flex; align-items: center; border-bottom: 2rpx solid rgb(253, 250, 250); height: 112rpx; } .playlist-cover{ width:80rpx; height:80rpx; margin-left: 15rpx; border-radius: 10rpx; border: 1rpx solid rgb(248, 245, 245); } .playlist-info{ /* 字体为垂直排列 */ flex: 1; font-size: 10pt; margin-right: 25rpx; margin-left: 10rpx; color: #000; } 3.运行效果

4.全部功能实现代码index.js // index.js // 获取应用实例 const app = getApp() Page({ // 页面初始数据 data: { item:0, //记录当前页的索引 tab:0, // 播放列表 playlist:[{ id:1, title:"纪念", singer:"雷心雨", src:"/images/1.mp3", coverImgUrl:"/images/cover.jpg" },{ id:2, title:"雪落下的声音", singer:"郁可唯", src:"/images/2.mp3", coverImgUrl:"/images/cover2.jpg" },{ id:3, title:"只要平凡", singer:"张杰", src:"/images/3.mp3", coverImgUrl:"/images/cover3.jpg" } ,{ id:4, title:"我会很勇敢", singer:"张雅莉", src:"/images/4.mp3", coverImgUrl:"/images/cover4.jpg" } ], state:"paused", // 播放的索引值 playIndex:0, //设置的默认值 play:{ // 当前时间 currentTime:'00.00', // 歌曲总时间 duration:'00.00', // 播放进度 percent:0, title:'', singer:'', coverImgUrl:"/images/cover.jpg", } }, // 保存在page里面了,音频对象 audioCtx:null, changeItem:function(e){ //设置获取item的值,来实现页面切换 this.setData({ item:e.target.dataset.item }) }, changeTab:function(e){ this.setData({ //当前页的索引 tab:e.detail.current }) }, // 手动控制进度 sliderChange:function(e){ var second=e.detail.value *this.audioCtx.duration / 100 //跳到指定位置 this.audioCtx.seek(second) }, onReady:function(){ //获取音频播放对象 this.audioCtx=wx.createInnerAudioContext() var that=this // 播放失败检测 this.audioCtx.onError(function(){ console.log("播放失败:"+that.audioCtx.src) }) // 播放完成自动转为下一曲 this.audioCtx.onEnded(function(){ that.next() }) // 格式化时间 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) } //自动更新播放进度 // 旧版本里面需要先调用onplay,要不无法启动onTimeUpdate 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 }) }) 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.playIndex >=this.data.playlist.length-1 ? 0 : this.data.playIndex+1 this.setMusic(index) if(this.data.state=="running"){ this.play() } }, // 播放列表中的换曲功能 change:function(e){ this.setMusic(e.currentTarget.dataset.index); this.play(); } })

图片、音乐以及源码资源连接

链接: https://pan.baidu.com/s/1TS2fefu1hb5aEf7FSvqTHA 提取码: ibg5?


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #微信小程序音乐播放器 #目录一 #小程序主体功能介绍二