前言

本文主要通过微信小程序的媒体API来实现一个简单的音乐播放器,主要实现的功能有音乐的切换、单曲循环、播放进度条的拖拽、播放与暂停和自定义音乐列表弹窗功能。

效果图

主要目录文件

|--images
|--pages
|  |--index  #页面
|  |  |--index.js
|  |  |--index.json
|  |  |--index.wxml
|  |  |--index.wxss
|--static
|  |--font
|  |  |--iconfont.wxss
|--app.js
|--app.json
|--app.wxss

以上主要列举了一些在编写本项目页面时编辑或可能会进行编辑的文件,其中所有页面文件都放在page目录下,static放置的是外部引入的静态资源。app.jsapp.jsonapp.wxss是全局文件。
app.json是对整个小程序的全局配置。我们可以在这个文件中配置小程序是由哪些页面组成,配置小程序的窗口颜色,配置导航条样式,配置默认标题以及默认首页等等 。
注意: app.json文件中不支持注释,否则会报错。
app.wxss定义整个小程序的公共样式,所有页面都可使用。
app.js为项目入口文件掌控整个小程序的生命周期,同时有一些全局的属性、变量也存放在这个文件中。

准备工作

1. iconfont图标字体库

这里我使用的是CDN导入图标字体库,首先在阿里巴巴字体库找到自己所需的图标,将其添加到自己新建的项目中导入到本地项目中。具体操作如下:
新建项目 在阿里巴巴图标库界面,点击资源管理,进入到我的项目中新建项目。 将选中图标添加到项目
首先将自己选中的图标添加入购物车,再点击购物车选择添加到至项目 复制代码,引入使用 在如下界面可以看到一个链接,点击后将显示页面的代码复制到微信小程序中自己新建的iconont.wxss文件中(不统一,这是我个人所建文件名),最后在app.wxss文件中引用一下–@import "static/font/iconfont.wxss"路径为你自己创建文件的路径.

小程序引入字体库的方式不局限于这一种,根据个人喜好和需求来即可,此处仅为作者个人使用方法。

2. 音乐数据准备

首先,因为此项目主要为音乐播放器的实现,所以作者个人并没有采用请求数据的方式获取音乐资源,作者是通过这以下api来获取网易音乐(不知是否是官方的),只需将所需音乐其中的x替换为自己所需音乐id即可获取该音乐链接,注意: vip音乐无效,更多音乐内容可以取用网易云音乐开源API

http://music.163.com/song/media/outer/url?id=xxxxxxx.mp3

实现代码

页面部分

页面标题

index.json文件

{"usingComponents": {},"navigationBarTitleText": "音乐播放器"
}

播放页面

index.wxml文件

<view class="container"><!-- 当前播放歌曲名 --><view class="title">{{name}}</view><!-- 音乐背景图 --><image class="myImg" src="{{src}}" mode="widthFix"/><!-- 音乐进度条 --><view class="range"><text>{{currentTime}}</text><sliderclass="mySlider"step="0.01"value="{{value}}"max="{{maxValue}}"bindchange="toTime"block-size="12"/><text>{{duration}}</text></view><!-- 功能按钮 --><view class="select"><button size="mini" bindtap="isSingle"><icon class="iconfont {{isSingle ? 'icon-danxunhuan' : 'icon-liebiaoxunhuan'}}"/></button><button size="mini" bindtap="pre"><icon class="iconfont icon-shangyishoushangyige"/></button><button size="mini" class="mid" bindtap="isPlay"><icon class="iconfont {{isPlay ? 'icon-zanting' : 'icon-bofangsanjiaoxing'}}"/></button><button size="mini" bindtap="next"><icon class="iconfont icon-xiayigexiayishou"/></button><button size="mini" catchtap="showActionSheet"><icon class="iconfont icon-liebiao"/></button></view>
</view>
<!-- 蒙层 -->
<view wx:if="{{showAlert}}" class="{{showAlert ? 'mask' : ''}}"  bindtap="closeAlert"></view>
<!-- 播放列表 -->
<view wx:if="{{showAlert}}"><scroll-view scroll-y="true" class="myalert"><view class="headline">播放列表</view><view wx:for="{{list}}" wx:key="index" class="option {{index==currentInd ? 'active' : ''}}" catchtap="change"data-ind="{{index}}">{{item.name}} - <text class="sub {{index==currentInd ? 'active' : ''}}">{{item.singer}}</text></view></scroll-view>
</view>

效果图

功能部分

声明: 作者的项目没做数据请求所以采用数组下标来进行歌曲的切换。

数据

data: {src: '../../images/beijin.png', // 背景图片isPlay: false, isSingle: false, // 是否单曲循环videoSrc: 'http://music.163.com/song/media/outer/url?id=1951069525.mp3', // 初始音乐链接name: '精卫', // 初始音乐名value: 0, // 进度条当前值maxValue: 0, // 进度条最大值currentTime: '0:00', // 当前歌曲播放进度duration: '0:00', // 当前歌曲总时长index: 0, // 用于切换歌曲currentInd: 0, // 当前播放歌曲下标showAlert: false, // 列表弹窗的显隐videos: [{name:'精卫', singer: '30年前,50年后', videoSrc:'http://music.163.com/song/media/outer/url?id=1951069525.mp3'},{name:'可能', singer: '程响', videoSrc: 'http://music.163.com/song/media/outer/url?id=1950343972.mp3'},{name:'雪 Distance', singer: 'Capper / 罗言', videoSrc: 'http://music.163.com/song/media/outer/url?id=2026224214.mp3'},{name:'我记得', singer: '赵雷', videoSrc: 'http://music.163.com/song/media/outer/url?id=1974443814.mp3'},{name:'梦醒', singer: 'handsome lau / HYPEEZY / 冯泳', videoSrc: 'http://music.163.com/song/media/outer/url?id=1395222212.mp3'},{name:'唯一', singer: '告五人', videoSrc: 'http://music.163.com/song/media/outer/url?id=1807799505.mp3'},{name:'罗生门(Follow)', singer: '梨冻紧 / Wiz_H张子豪', videoSrc: 'http://music.163.com/song/media/outer/url?id=1456890009.mp3'},{name:'还是会想你', singer: '林达浪 / h3R3', videoSrc: 'http://music.163.com/song/media/outer/url?id=1827600686.mp3'},{name:'爱人错过', singer: '告五人', videoSrc: 'http://music.163.com/song/media/outer/url?id=1368754688.mp3'},{name:'达尔文', singer: '林俊杰', videoSrc: 'http://music.163.com/song/media/outer/url?id=2019573476.mp3'},{name:'乐园', singer: '沧桑CangSang / 虎皮蛋 / 曲甲', videoSrc: 'http://music.163.com/song/media/outer/url?id=2021379728.mp3'},{name:'落泪', singer: '康熙 / TOYOKI', videoSrc: 'http://music.163.com/song/media/outer/url?id=2021434589.mp3'},{name:'谁', singer: '王贰浪', videoSrc: 'http://music.163.com/song/media/outer/url?id=2026812798.mp3'},{name:'我的爱如烈火', singer: 'xxxmiracle / mok', videoSrc: 'http://music.163.com/song/media/outer/url?id=2024654768.mp3'},]}

初始化

在页面加载时,小程序使用wx.createInnerAudioContext()创建并返回内部audio上下文对象innerAudioContext,同时调用自定义函数initialAudio()函数初始化音频。

onLoad: function (options) {this.audioCtx = wx.createInnerAudioContext()this.initialAudio()
}

初始化音频

// 初始化音频
initialAudio() {let audioCtx = this.audioCtxaudioCtx.src = this.data.videoSrc // 初始歌曲audioCtx.loop = this.data.isSingle // 是否单曲循环// 当音乐自然播放完成后执行next()audioCtx.onEnded(() => {this.next()})// 获取音乐时长,当前进度audioCtx.onCanplay(() => {audioCtx.durationaudioCtx.currentTimesetTimeout(() => {this.setData({value: audioCtx.currentTime,maxValue: audioCtx.duration,currentTime: this.timeFormat(audioCtx.currentTime),duration: this.timeFormat(audioCtx.duration)})},1000)})// 音频播放进度更新后执行audioCtx.onTimeUpdate(() => {this.setData({value: audioCtx.currentTime,maxValue: audioCtx.duration,currentTime: this.timeFormat(audioCtx.currentTime),duration: this.timeFormat(audioCtx.duration)})})
},

这段代码主要是定义了初始音频,初始默认为列表循环,当音乐自然播放完后,调用next()切换列表下一首,其中onCanplay()监听音频是否进入可执行状态,若是,执行回调函数获取音乐总时长以及当前播放位置。注意: 初始获取时长建议这样写,不然获取不到,具体原因作者也没找到。onTimeUpdate()用于监听音频播放进度的改变,及时更新相关时间数据。其中以audioCtx.调用的属性和方法皆为小程序innerAudioContext对象自带的属性和方法。

时间格式转换

timeFormat(e) {let time = Math.floor(e)const minutes = Math.floor(time / 60)const seconds = time % 60const result = `${this.padTo2Digits(minutes)}:${this.padTo2Digits(seconds)}`return result
},
padTo2Digits(num) {return num.toString().padStart(2, '0');
},

因为通过小程序获取到的时间单位是s,所以我们需要将时间格式转换为mm:ss格式,其中需要使用ES6中的字符串新方法:padStart()用于头部补全,要传入两个参数第一个参数用来指定字符串的最小长度,第二个参数是用来补全的字符串。

切换下一首

next() {let index = this.data.index + 1 // 下一首下标let list = this.data.videos  // 歌曲数组let isPlay = this.data.isPlay let videoSrc = ''let name = ''// 如果超过列表长度,从列表第一首开始if(index>=list.length) {index = 0}videoSrc = list[index].videoSrcname = list[index].nameif(isPlay) {isPlay = !isPlay}this.setData({isPlay,index,currentInd: index,videoSrc: videoSrc,name: name})this.isPlay()
},

修改当前播放音频链接,音频名,当前播放音频下标(用于播放列表的更新),最后调用isPlay()进行歌曲播放。

播放功能

isPlay() {let isPlay = this.data.isPlayif(!isPlay) {this.audioCtx.src = this.data.videoSrcthis.audioCtx.play()} else {this.audioCtx.pause()}this.setData({isPlay: !isPlay,})
},

通过isPlay变量来实现切换歌曲后的自动播放以及手动暂停功能,根据其值来决定是调用播放还是暂停功能。

切换上一首

pre() {let index = this.data.index - 1let list = this.data.videoslet isPlay = this.data.isPlaylet videoSrc = ''let name = ''if(index<0) {index = list.length - 1}videoSrc = list[index].videoSrcname = list[index].nameif(isPlay) {isPlay = !isPlay}this.setData({isPlay,index,currentInd: index,videoSrc: videoSrc,name: name})this.isPlay()
}

基本实现与切换下一首无异,不同在于当下标index小于0时,将下标切换为音频列表最后一首的下标。

单曲循环

isSingle() {let isSingle = this.data.isSinglethis.setData({isSingle: !isSingle})this.audioCtx.loop = this.data.isSingle
}

主要通过小程序innerAudioContext上的loop属性来实现,其用于控制是否循环播放,默认为false。通过修改isSingle变量来控制。

进度条拖拽

toTime(e) {console.log(e.detail);let time = e.detail.valuethis.audioCtx.seek(time)
}
<view class="range">// 当前音频进度<text>{{currentTime}}</text><sliderclass="mySlider"value="{{value}}"max="{{maxValue}}"bindchange="toTime"block-size="12"/>// 当前音频总时长<text>{{duration}}</text>
</view>

其中调用了innerAudioContextseek()方法用于跳转音频进度到指定位置,由于播放进度更新,会执行上文的onTimeUpdate()方法,更新value的值,其中该值为进度条此时进度值,所以进度条进度也会同步更新。maxValue为当前音频总时长。

弹窗列表

展示弹窗

showActionSheet() {let list = this.data.videos.map(x => {return {"name":x.name,"singer": x.singer}})console.log(list);// let that = thisthis.setData({showAlert: true,list})
}

通过map()函数将音频列表的歌手名,音频名组成一个新的对象数组,渲染到弹窗列表。

关闭弹窗

closeAlert() {this.setData({showAlert: false})
}

弹窗列表选择音乐

change(e) {// console.log(e);// console.log(e.currentTarget.dataset.ind);let index = e.currentTarget.dataset.indthis.setData({currentInd: index,index: index,name: this.data.videos[index].name,videoSrc: this.data.videos[index].videoSrc,isPlay: false,showAlert: false})this.audioCtx.stop()this.isPlay()
}

通过点击事件获取被点击列表上的音频下标,修改播放链接和歌手名为选择下标的链接,同时隐藏弹窗。

弹窗列表页面

// 蒙层
<view wx:if="{{showAlert}}" class="{{showAlert ? 'mask' : ''}}"  bindtap="closeAlert"></view>
// 弹窗列表
<view wx:if="{{showAlert}}"><scroll-view scroll-y="true" class="myalert"><view class="headline">播放列表</view><view wx:for="{{list}}" wx:key="index" class="option {{index==currentInd ? 'active' : ''}}" catchtap="change"data-ind="{{index}}">{{item.name}} - <text class="sub {{index==currentInd ? 'active' : ''}}">{{item.singer}}</text></view></scroll-view>
</view>

蒙层当弹窗列表弹出时添加一层背景色,同时给其关闭弹窗功能,点击列表外部时,弹窗会主动关闭,同时data-设置一个变量传递给点击事件用于替换歌曲,currentInd用于判断当前播放歌曲,将列表对应项添加active类,使其呈现红色。

结语

以上便是主要功能的代码实现,这里由于篇幅过长css样式并未给出,如需可以点击源码链接查看,如果觉得还不错的话,请给作者一个小小的赞吧! 源码链接

微信小程序-音乐播放器相关推荐

  1. 微信小程序音乐播放器

    趁周末做一个简单的微信小程序音乐播放器,源码已留. 播放列表首页wxml <swiper class="swiper" indicator-dots='{{swipterSe ...

  2. (附源码)springboot+基于微信小程序音乐播放器的设计与实现 毕业设计271156

    Springboot音乐播放小程序的设计与实现 摘 要 本文设计了一种基于微信小程序的音乐播放器,系统为人们提供了方便快捷.即用即搜的音乐搜索播放服务,包括音乐资讯.音乐库推荐.交流论坛.注册登录.最 ...

  3. springboot+基于微信小程序音乐播放器的设计与实现 毕业设计-附源码271156

    Springboot音乐播放小程序的设计与实现 摘 要 本文设计了一种基于微信小程序的音乐播放器,系统为人们提供了方便快捷.即用即搜的音乐搜索播放服务,包括音乐资讯.音乐库推荐.交流论坛.注册登录.最 ...

  4. 基于微信小程序音乐播放器

    随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,音乐播放器小程序被用户普遍使用,为方便用户能够可以随时 ...

  5. 微信小程序——音乐播放器

    音乐播放器 前言 主页 三个标签页 推荐页 播放器页 播放列表页 逻辑 前言 使用swiper组件完成三个标签页的切换,并且实现轮播图.scroll-view组件完成滚动视图,使用微信小程序提供的音乐 ...

  6. 01. 微信小程序音乐播放器

    项目简介 最近在学微信小程序,所以打算做一个音乐播放器的微信小程序. 项目需求(原型图) 这个是我做的原型图,比较简陋(有些界面直接用了网易云音乐小程序的截图,因为是仿着网易云音乐来做的) 首页 播放 ...

  7. java基于微信小程序音乐播放器分享系统 uniapp 小程序

    音乐播放器小程序的设计主要是对系统所要实现的功能进行详细考虑,确定所要实现的功能后进行界面的设计,在这中间还要考虑如何可以更好的将功能及页面进行很好的结合,方便用户可以很容易明了的找到自己所需要的信息 ...

  8. 计算机实战项目、毕业设计、课程设计之含论文+辩论PPT+源码等]微信小程序音乐播放器小程序+后台管理系统

    音乐播放器平台+后台管理系统|前后分离VUE>该项目含有源码.论文等资料.配套开发软件.软件安装教程.项目发布教程等 本系统包含微信小程序前台和Java做的后台管理系统,该后台采用前后台前后分离 ...

  9. java微信小程序音乐播放器分享系统

    随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,音乐播放器小程序被用户普遍使用,为方便用户能够可以随时 ...

最新文章

  1. mysql. Oracle创建视图,Navicat 教程:Oracle 视图
  2. Golang 使用Protocol Buffer 案例
  3. 实现远程调用_远程过程调用(RPC)是怎么实现的?
  4. MYSQL技术连环斩-MYSQL简述
  5. Android Jni 例程
  6. 附录:更多列表操作命令
  7. 编译原理——实验壹预习——TINY语言的词法分析
  8. 飞鸽传书2007绿色版 唯一官方下载地址
  9. 原创-WINDOWS SERVER 2008 WEB服务器安装配置
  10. LINUX获得毫秒时间戳的代码
  11. 联想y430完全拆机图解_联想Y430P笔记本拆机加内存和SSD图文教程
  12. 五子棋c语言编程软件,C语言实现五子棋游戏
  13. 银行卡四要素认证api接口_银行卡实名认证查询-银行卡四要素鉴权
  14. 51单片机定时器时间计算
  15. 视频横竖屏模式切换,如何将多个视频任意转换
  16. 关于微信开发者平台移动应用(android)获取签名问题
  17. 人工智能门槛太高?用这个框架轻松入门深度学习!
  18. 【hadoop生态之Flume】概念【笔记+代码】
  19. Lidar Object detection
  20. 计算机的服务桌面,比较实用的电脑桌面软件值得入手,个个精选

热门文章

  1. 干货 | StarRocks在携程大住宿智能数据平台的应用
  2. BMP文件格式详解(BMP file format)
  3. Jenkins+Gitlab+SonarQube 代码质量管理集成
  4. 安卓Service组件使用系列2:使用Service下载网络图片并存储于sdCard卡上
  5. html怎么在alert中加标题,js重写alert事件(避免alert弹框标题出现网址)
  6. python 操作 excel 百度网盘 资源下载_批量读取excel百度链接转存到自己的百度网盘...
  7. 用户中心登录注册整理
  8. element 合并单元格
  9. 把分钟转化为小时分钟
  10. SIMLock锁卡功能解析