使用vue实现自己音乐播放器仿网易云 移动端 (audio、播放、暂停、上一首、下一首、展示评论、音量控制、进度条拖拽)
标签: javascript vue es6 Nodejs
最终实现成果展示

1.播放 暂停功能的实现
这是audio标签
<audio @timeupdate="updateTime" @canplay="getDuration" @ended="ended" :src="musicUrl" ref="audio"></audio>
这是播放和暂停图标
<div class="pause" v-show="isPlaying" @click="pauseSong"><i class="fa fa-pause"></i></div>
<div class="play" v-show="!isPlaying" @click="playSong"><i class="fa fa-play"></i></div>
播放和暂停事件我们通过
this.$refs.audio.play()和this.$refs.audio.pause()来进行控制,并切换isPlaying的值来改变图标的显示。设置this.$refs.audio.autoplay= true可实现歌曲自动播放
中间圆形图片的旋转和暂停是通过添加类名控制:
css样式如下:
.cd.rotate img{
animation: rotateIMG 15s linear infinite;
}
.cd.rotatePause img{
animation-play-state:paused;
-webkit-animation-play-state:paused; /* Safari 和 Chrome */
}
@keyframes rotateIMG{
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
html结构如下:
<div class="cd" v-show="show" @click="show = !show" ref="cd">
<img :src="playingSong.blurPicUrl" width="60%">
</div>
js控制如下:
// 播放时
this.$refs.cd.classList.add('rotate')
if (this.$refs.cd.classList.contains('rotatePause')) this.$refs.cd.classList.remove('rotatePause')
// 暂停时
this.$refs.cd.classList.add('rotatePause')
2. 上一首 下一首功能的实现
要实现这个功能我们就要拿到当前歌曲列表的所有数据。我请求的是网易云的接口,将数据存在vuex里面。我们只需通过切换数组索引即可达到切换歌曲。
歌曲列表是通过遍历出来的,所以我们可以给节点加上data-index属性。结果像下面这样
接下来点击的时候我们把当前
data-index存到localStorage里面,之后在上一首/下一首的点击事件里 – 或者 ++进行切换,并做边界值判断 代码如下:
prevSong () { // 播放上一首歌曲
localStorage.curSongPlayIndex--
if (localStorage.curSongPlayIndex < 0) localStorage.curSongPlayIndex = this.$store.state.songPlayList.length - 1
this.playingSong = this.$store.state.songPlayList[JSON.parse(localStorage.curSongPlayIndex)]
this.loadMusic() // 加载音乐地址 加载歌词 加载喜欢状态 加载音乐评论
this.autoPlaySong() // 点击之后歌曲或自动播放
}
3.进度条显示 时间显示 进度条拖拽功能实现
3.1获取音乐总时长
在canplay钩子函数拿到总时长
getDuration () { // canplay时获取音频总时长
this.duration = this.$refs.audio.duration
this.allTime = this.formatTime(this.$refs.audio.duration)
},
注意:时间获取出来是秒。我们要显示的是ss:mm格式。所以 this.duration存的时间是秒 this.allTime存的时间是格式化之后的
formatTime函数代码如下:
formatTime (time) {
if (time === 0) {
this.curTime = '00:00'
return
}
const mins = Math.floor(time / 60) < 10 ? `0${Math.floor(time / 60)}` : Math.floor(time / 60)
const sec = Math.floor(time % 60) < 10 ? `0${Math.floor(time % 60)}` : Math.floor(time % 60)
return `${mins}:${sec}`
}
3.2拿到当前时间 更新进度条
在timeupdate钩子函数获取当前播放时间
updateTime (e) { // timeupdate时获取当前播放时间
const { currentTime } = e.target
this.currentTime = currentTime
this.curTime = this.formatTime(currentTime)
this.updateProgress(this.currentTime, this.duration)
}
这个地方同样的this.currentTime是当前时间(秒),this.curTime是格式之后的分秒格式
下一步我们就要更新进度条了,得到 当前时间和总时间 的比值 来更新进度条的宽度和小圆点距离左边的距离
updateProgress (currentTime, duration) { // 更新进度条
this.precent = `${((currentTime / duration) * 100).toFixed(5)}%`
},
<div class="progress" @click="clickProgress($event)" ref="progress">
<div class="line" :style="{width: `${precent}`}"></div>
<div class="dot" :style="{left: `${precent}`}" @touchstart='dotStart' @touchmove='dotMove' @touchend='dotEnd'></div>
</div>
3.3进度条点击播放 拖拽播放
在 clickProgress方法里这样写
clickProgress (event) { // 点击进度条时 更新音频时间和进度条
const e = event || window.event
const position = e.clientX - e.currentTarget.offsetLeft // 当前点击的位置
const progressWidth = this.$refs.progress.offsetWidth // 进度条总宽度
this.$refs.audio.currentTime = ((position / progressWidth) * this.duration) // 设置当前音频的播放时间
this.updateProgress(((position / progressWidth) * this.duration), this.duration)
}
这样就实现了点击进度条播放。
下面是拖拽功能的实现,使用原生的touchstart touchmove touchend来监听。
在touchmove时,获取小圆点拖动到距离进度条左边的距离,并实施更新进度条
touchMove(e) {
// 移动的距离
let moveX = e.touches[0].pageX - 83 // 83是进度条距离浏览器的距离
// 进度条的宽度
const progressWidth = this.$refs.progress.offsetWidth
if (moveX >= progressWidth) moveX = progressWidth // 边界值判断
this.$refs.audio.currentTime = ((moveX / progressWidth) * this.duration) // 实时更新播放时间
this.updateProgress(((moveX / progressWidth) * this.duration), this.duration) // 更新进度条
}
在touchend时播放歌曲
touchEnd(e) {
this.playSong() //调用播放歌曲方法
this.isPlaying = true
},
4.评论区的展示

比较简单 直接遍历得到的数据然后渲染就行。只是在切换歌曲时要把评论区给隐藏掉
以上就实现了所有功能啦 在线演示地址为 网抑云音乐
感谢你的耐心观看 点个赞吧!再收个藏吧!
智能推荐
Vue-网页版音乐播放器实现(网易云音乐源)
一、页面展示(后续还会完善功能) 二、已完成功能 1、搜索功能 2、音乐列表展示 3、歌曲图片展示和图片背景虚化效果 4、音乐播放动态效果 5、音乐暂停以及上下首切换 6、音乐时长获取及格式化 三、未完成功能 1、歌曲正在播放标识 2、播放模式 3、歌曲播放进度 4、音量调整 5、歌曲评论 四、页面代码 五、Js 代码 六、项目完整代码 完善后会上传GitHub...
vue 移动端 拖拽
创建一个div,因为是移动端的,所以用touchmove事件,触发一个函数。(里边的span标签是为了使用iconfont) 上边div里有一个动态绑定的style样式,是因为给这个div加了定位,之后需要动态设置坐标,为了简单所以使用。 这样就需要在data中定义一个 X轴(left),Y轴(top)初始化的一个位置。 同时上边绑定了一个移动事件触发的函数...
基于React的适配PC端和移动端的轻量音乐播放器
基于React的适配PC端和移动端的轻量音乐播放器 技术:React16 之前基于Vue写了一个播放器,带各种功能,最后把自己绕死了。这次用React重写了个,舍弃了那些没用的功能,只保留了基本功能。并且利用媒体查询适配移动端和手机端。组件之间传值利用props,这个播放器先供自己用,以后会抽离成为一个插件。 点击查看项目演示 (可能因为会资源问题有歌曲播放不出来,如果发现我会及时解决的,目前是好...
Vue学习笔记(利用网易云API实现音乐播放器 实例)
项目包地址 利用axios和网易云提供的API进行连接交互。依然要注意axios的回调函数中的this会发生改变,因此需要额外的变量对this进行保存。 因为文件稍大,因此最好重新新建一个js文件,然后在html进行引入即可 在data中保存数据 在methods中保存对数据的操作,在html进行调用即可 axios调用网易云中的数据格式为 也可以在方法中的参数中设置已经获取的数据,对数据进行调用...
Python_第一天(安装、基本操作、数据类型)
哈哈哈哈,开通后,还是只是简单地记录了两篇SQL学习日记。果然是我任乐的风格。 最近重新捡起了一些统计分析方法,网盘资料不全,学习了一周,还得拿起大学记录的笔记,在那里看,算是捡起了一些,学多学少,算是让自己安心一丢丢,让无处安放的心找到地方。 python总是这学习一点那儿学习一点,久久捡起来用一下,没有系统地好好学习。今天就奋起,再从零捡起来一下。能坚持几天呢,哈哈哈哈,任乐任乐。 一、安装A...
猜你喜欢
java实现自动化测试接口访问(一)
一、前置准备: PostMan 访问的网站:Github 访问的接口: https://api.github.com/search/commits?q=committer-date:2017-11-27..2017-12-01&page=1&per_page=100 实现访问:查找2017-11-27到 2017-12-01的100条数据 二、代码实现 1. 使用PostMan输入...
SQLite 真的很容易编译 | Linux 中国
事实证明,这个过程超麻烦(如通常一样),但是非常有趣! -- Julia Evans 上周,我一直在做一个 SQL 网站(https://sql-steps.wizardzines.com/,一个 SQL 示例列表)。我使用 sqlite 运行网站上的所有查询,并且我想在其中一个例子(这个)中使用窗口函数。 但是我使用的是 Ubuntu 18.04 中的 sqlite 版本,它太旧了,不支持窗口函...
关于VS2015安装Team Explorer for Microsoft Visual Studio 2015问题总结(已解决)
最近不知道怎么,想使用VS2015查看代码,但是打开VS2015的时候却提醒VS2015软件不完整?我记得自己没有动过VS2015呀!按照以往的经验,自己试了以下方法: 一、在控制面板的卸载程序中,点击VS2015的“修复”选项,但是安装到一半就会出现以下问题: 我又查看了软件Log,最后关于Team Explorer出现以下日志: 二、难道真的是安装包有问题? 把VS20...
和v-model一起来理解计算属性的响应式依赖(缓存)的概念
首先,计算属性是一个属性,当却是函数的写法,其实也不难理解,因为是要对数据进行一番操作,避免了都写在模板中,太多的逻辑会让模板过重且难以维护。 其次,计算属性不仅便于维护代码,最大的优点是响应式依赖,意思式依赖的数据只要不发生变化,不管被调用多少次,每次都立即返回之前的结果,只有依赖的数据发生改变,才会重新返回新的结果,先上一段代码说话: 这段代码中,revers是定义在methods的方法,re...
一个页面有多个echarts图形时自适应窗口大小
如上图所示一个页面有四个echarts图形:如果还写为 则只有一个图形可自适应窗口大小,另外一个则不能随窗口大小而改变图形大小, 解决办法: 为在每一个echarts图形页面将上面代码改为如下代码: ...

