
本文介绍了实现音乐播放器并与您共享的Vue页面示例js实现网页音乐播放器,如下所示:
效果如下:


项目地址:
演示地址: (歌曲链接已过期)
发展之前的构想
接口
要成为音乐播放器,界面必须很酷. 太低而听不到感觉. 它打算在上班时使用,因此它制作了类似于网易云音乐的界面,大小合适. 无需与手机兼容.
使用css作为图标
考虑到简单实用的要求,图标可以是SVG,URL或CSS. 相对于url,SVG和CSS更好. 为了实践,最终选择css. 在前后使用良好可以减少很多dom嵌套.

.next {
position: relative;
display: inline-block;
height: 36px;
width: 36px;
border: 2px solid #fff;
border-radius: 20px;
-webkit-border-radius: 20px;
-moz-border-radius: 20px;
}
.next:before {
content: '';
height: 0;
width: 0;
display: block;
border: 10px transparent solid;
border-right-width: 0;
border-left-color: #fff;
position: absolute;
top: 8px;
left: 10px;
}
.next:after {
content: '';
height: 20px;
width: 4px;
display: block;
background: #fff;
position: absolute;
top: 8px;
left: 22px;
}
绘制记录
网易云的记录非常好,我也想做一个记录!具有良好的阴影效果,一个元素可以产生很好的记录效果.
.disc {
position: relative;
margin-top: 10%;
margin-left: 10%;
width: 300px;
height: 300px;
border-radius: 300px;
transform: rotate(45deg);
background-image: radial-gradient(5em 30em ellipse, #fff, #000);
border: 2px solid #131313;
box-shadow: 0 0 0 10px #343935;
opacity: 0.7;
}
使用范围作为进度条
音频本身的样式很丑陋,不同的浏览器有不同的效果. 当然,您可以修改音频样式. 传统方法是通过controls属性隐藏音频,然后使用div代替. 现在已经是HTML5的时代了,当然,我们必须使用更符合场景----- range的新元素.
input[type=range] {
-webkit-appearance: none;
width: 80%;
height: 8px;
border-radius: 10px;
background-color: #fff;
}
input[type=range]::-webkit-slider-thumb{
-webkit-appearance: none;
}
input[type=range]::-webkit-slider-runnable-track {
height: 8px;
border-radius: 20px;
}
input[type=range]:focus {
outline: none;
}
input[type=range]::-webkit-slider-thumb {
-webkit-appearance: none;
margin-top: -3px;
height: 14px;
width: 14px;
background: #eb7470;
border-radius: 50%;
border: solid 3px #fff;
box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.5);
}
模糊的背景滤镜
将图片设置为背景感觉很好. 可以说整个播放器的背景值提供了背景的一半. 使用css3过滤器,设置也非常简单.
.bg-blur {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 100%;
height: 100%;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
filter: blur(20px);
z-index: -1;
}
背景图片由js控制.

<div class="bg-blur" :style="`background-image:url(${currentSong.album_logo})`"></div>
歌曲资源
下移界面
直接转到Xiami的官方网站以打开网络,并将URL复制到邮递员以进行请求. 通过修改标题,将验证Referer. 换句话说,只有Xiami允许的域名才能访问此界面.
解决跨域问题
因为该接口支持jsonp. 首先,我尝试将Chrome浏览器设置为跨域,然后通过$ .ajax发出jsonp请求. 可以正常访问.
此后突然不再工作,虾被限制了吗?
然后使用节点启动服务,伪造引荐人以发起请求,然后将请求转发到页面. 代理人是无意间写的.
...
case '/song':
let songOptions = {
url: 'http://api.xiami.com/web'+ urlArr[1],
headers: {
'Referer': 'http://m.xiami.com/'
}
};
function callback1(error, response, body) {
if (!error && response.statusCode == 200) {
res.end(body);
}
}
request(songOptions, callback1);
break;
...
歌词滚动
作为一个强迫症的玩家,必须滚动歌词.

原理
将每个句子保存为具有相应时间的对象. 当歌曲的当前持续时间大于或等于歌词的时间并且小于歌词的下一句子的时间时,则将歌词滚动到可见区域. 并修改字体颜色.
格式化歌词
界面返回的歌词是傻眼的. 如果仔细研究它们,您会发现它们是正常的.
[ti:aLIEz]
[ar:SawanoHiroyuki[nZk]:mizuki]
[al:o1]
[ly:澤野弘之]
[mu:澤野弘之]
[ma:]
[pu:]
[by:ttpod]
[total:268512]
[offset:0]
[00:00.000]<195>aLIEz <199>- <451>SawanoHiroyuki[nZk]:mizuki
[x-trans]彻头彻尾的谎言 - SawanoHiroyuki[nZk]:mizuki
[00:01.095]<201>作<250>詞<200>:<201>澤<200>野<199>弘<300>之
[x-trans]
[00:02.846]<200>作<150>曲<150>:<200>澤<200>野<351>弘<349>之
[x-trans]
[00:20.828]<200>決<250>め<200>つ<201>け<149>ば<201>か<349>り
[x-trans]一直独断专权
[00:23.279]<200>自<200>惚<200>れ<200>を<200>着<400>た
[x-trans]总是自负逞强
[00:24.979]<200>チ<200>ー<200>プ<450>な<550>hokori<350>で
[x-trans]明明只是一文不值的骄傲
......
refactoringLyrics(lyric){
let text = lyric.split('[offset:0]')[1];
let textArr = text.split('\n');
let lyricsArr = [], translate = [];
textArr.forEach((item, index) => {
let time = 0, text = '';
if (item.indexOf('[x-trans]') > -1) {
translate.push(item.split('[x-trans]')[1])
} else if (item.trim() != '') {
time = item.slice(1, 6).split(':');
time = parseInt(time[0]) * 60 + parseInt(time[1]);
text = item.slice(11);
let arr = text.split('>');
let str = arr.reduce((a, b) => {
return a.split('<')[0] + b.split('<')[0]
});
let obj = {
time: time,
text: str
};
lyricsArr.push(obj);
}
});
for (let i in translate) {
lyricsArr[i].text = lyricsArr[i].text + '\n' + translate[i];
}
this.currentLyrics = lyricsArr;
},
搜索栏的实现
在同一文件下安装子组件
为了跟随模块化的发展,决定将搜索栏作为子组件编写. 在同一页面上编写子组件,然后将子组件附加到相应的模板. 该模板不能包含在父组件的mount元素中,否则,当父组件无法在子组件中呈现数据时,该父组件将报告未定义.
<div id="app" class="main">
...
</div>
<template id="search-box">
...
</template>
var searchBox = {
template: '#search-box',
props: {
isShow: Boolean,
openFun: Function
},
data(){
return {
resultList: [],
searchValue: '',
}
},
methods: {
}
};
new Vue({
el: '#app',
components: {
'com-tip': tip,
'search-box': searchBox
},
...
})
eventBus解决了数据传输问题
要通过jsonp请求数据,需要设置一个回调函数. 该回调被编写为全局函数. 如果不是这样写的,它将采用searchBox.methods.callback的形式. 这指向方法. 无法直接将数据分配给searchBox. 它是通过eventBus处理的,易于维护.

var EventBus = new Vue();
var callBack = function(result) {
console.log(result);
EventBus.$emit('callBack', result);
};
...
mounted(){
let self = this;
EventBus.$on('callBack', function(res) {
if (res && res.data) {
self.resultList = res.data.songs;
}
})
}
...
localStrong存储歌曲信息
下次打开时,播放列表应保留最后一个数据. 可以直接通过localstrong实施
踩坑
财产转移数据
使用CDN,vue的道具仅支持中线格式,驼峰格式无效
ps: 可以在webpack打包的项目中使用驼峰. 在包装过程中,将对其进行处理.
// 正确写法
<search-box :is-show="showSearch" :open-fun="openSearch" @push-song="pushNewSong"
@play-song="playSong"></search-box>
// 错误写法
<search-box :isShow="showSearch" :openFun="openSearch" @pushSong="pushNewSong"
@playSong="playSong"></search-box>
要优化
手动修改进度js实现网页音乐播放器,有时不会生效.
搜索尚不支持分页
不支持建立歌曲列表
背景色类似于进度条的颜色,需要修改进度条的颜色
不支持播放模式选择-单循环随机播放
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/bofangqi/article-269852-1.html
早