请忽略下面这段文字
年关将至,时间好歹又多出了些许。却不敢过度消遣。岁月未曾饶过我,我亦不想饶过岁月。且将它塞得膨胀,让这一年看似加更充实。
不曾料想我一个爱些风花雪月、研墨行歌之人,却做起了碼农这一行当。虽做了碼农,却断不了嗜好,日日必听歌。奈何近日,公司限制高流量网络访问。虾米、网易云、QQ甚至酷狗,无一幸免。
没有了歌,变得像挨了锤的牛一样,疲软成一滩烂泥。
所幸还能用用listen 1,可这listen 1却让人味同嚼蜡。歌且无过,想是这界面不合胃口。做一名前端,也沾了对外观挑三检四的毛病。
于是灵光一闪,便想造一个出来。


项目地址:https://github.com/ermu592275...
演示地址:https://ermu592275254.github....(因referer限制,无法搜索歌曲)

开发前构思

界面

做音乐播放器,界面一定要炫酷。太low了听歌没感觉。本身是为了在上班的时候用,于是做成了一个类似网易云音乐的界面,大小合适。不用兼容手机端。

用css做图标

本怀着简单实用的需求去考虑,图标可用SVG、url或者css。相对于url,SVG和css更好一些。为了修炼,最终选择的css。利用好after和before,能减少很多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;
}

画一个唱片

网易云的唱片很好看,我也要弄一个唱片!
用好box-shadow,一个元素便可以做成很好看的唱片效果。

.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;
}

用range做进度条

audio本身的样式很难看,并且不同的浏览器呈现出来的效果也不一样。当然你可以修改audio的样式,传统的做法是通过controls属性来隐藏audio,然后用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>

歌曲资源

爬下接口

直接去虾米官网打开network,将url复制到postman里面去做请求。通过修改headers发现,会校验Referer。也就是说只有虾米允许的域名可以访问此接口。
http://api.xiami.com/web?v=2....

解决跨域问题

因为接口支持jsonp。起初尝试将chrome浏览器设置跨域,然后通过$.ajax去做一个jsonp的请求。可以正常访问。
之后突然不行了,是不是虾米做了限制?
遂改用node启动一个服务,去伪造referer发起请求,再将请求转发到页面。无意中写了一个代理。

...
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;
},

搜索栏实现

同文件下子组件挂载

为了遵循模块化开发,决定将搜索栏写成一个子组件。在同一页面下写子组件,子组件挂载到对应的template就有讲究了。此template不能被父组件的挂载元素包含,否则父组件渲染时会因为无法渲染子组件中的数据而报undefined。

<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去请求数据,需要设置一个callback函数,此callback写成一个全局函数,如果不这样写,而是通过
searchBox.methods.callback的形式,this指向将为methods。而无法直接给searchBox的data赋值。
于是通过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实现

技术补充

滤镜模糊 http://www.zhangxinxu.com/wor...
css图标 http://www.uiplayground.in/cs...
flex 兼容写法: https://www.cnblogs.com/irisz...
flex 布局教程 http://www.ruanyifeng.com/blo...
滑动条样式自定义 http://blog.csdn.net/u0133472...
隐藏滚动条兼容 https://segmentfault.com/q/10...
audio属性 https://developer.mozilla.org...
audio事件 https://developer.mozilla.org...

踩了坑

prop传递数据

使用cdn,vue的prop只支持中线格式,驼峰格式不生效
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>

待优化

手动修改进度,偶尔会不生效。
搜索暂不支持分页
不支持建歌单
背景颜色与进度条颜色相近需修改进度条颜色
不支持播放模式选择-单曲循环-随机播放

vue——一个页面实现音乐播放器相关推荐

  1. Python:通过网络爬虫实现一个简易控制台音乐播放器

    hello,大家好,我是wangzirui32,今天我们来学习如何通过网络爬虫实现一个简易控制台音乐播放器,开始学习吧! 1. 项目结构及库准备 app.py为项目入口程序,download.py为音 ...

  2. 用html制作一个音乐排行榜,使用原生JavaScript制作一个漂亮的音乐播放器

    简单介绍 起初在简书上发现了这篇博客--[html.css.jq]制作一个简洁的音乐播放器.这是一个用jQuery库实现的音乐播放器,界面简约大气. 我在这个基础上,反其道而行,使用原生JavaScr ...

  3. javascript实现一个自制网页音乐播放器

    序 接触简书也有一段日子了,这中间的时光还是比较轻松加愉快的,那种可以和他人分享知识的欣喜和愉悦的确是非常棒.我一向都是觉得专心写自己的文就可以了,不会总是纠结有多少人在看,有多少点击等等.用心写好自 ...

  4. vue使用Howler实现音乐播放器

    vue使用Howler实现音乐播放器 前言 一.引入依赖 二.封装组件 前言 本文使用Howler.js进行播放.使用siriwave做的播放动画具体文档地址如下 名称 地址 Howler https ...

  5. 完整打造一个多功能音乐播放器项目(初步设想跟酷狗类似)

    本人目前准备利用闲暇时间打造一个完整的音乐播放器项目,主要用于学习及分享!原创不易,转载请注明出处. 这是一个什么样的音乐播放器呢?整体的架构跟酷狗差不多吧,我的方式呢,是一个个组件一个个模块先做好, ...

  6. 自制一个简单的音乐播放器

    这两天刚学完了contentprovider和service组件,就综合下所学的,自制了一个简单的音乐播放器. 代码如下: 主activity代码 public class MainActivity ...

  7. HTML+CSS+原生JS写一个简易的音乐播放器(仅播放一首歌)

    用HTML+CSS+原生JS写一个简易的音乐播放器(仅播放一首歌) 效果如下:(鼠标点击按钮可以实现播放或暂停,按钮会旋转,实现了歌词同步,功能还需改进) 代码如下: <!DOCTYPE htm ...

  8. 用Qt写一个简单的音乐播放器(三):增加界面(播放跳转与音量控制)

    一.前言 在用Qt写一个简单的音乐播放器(一):使用QMediaPlayer播放音乐中,我们已经知道如何去使用QMediaPlayer播放音乐. 在用Qt写一个简单的音乐播放器(二):增加界面(开始和 ...

  9. 用Qt写一个简单的音乐播放器(六):显示歌词(正则表达式)

    一.前言 在用Qt写一个简单的音乐播放器(一):使用QMediaPlayer播放音乐中,我们已经知道如何去使用QMediaPlayer播放音乐. 在用Qt写一个简单的音乐播放器(二):增加界面(开始和 ...

最新文章

  1. 资深程序员感叹:表妹成绩好却无奈辍学开理发店,月入6万,上大学没用!网友:那是你没用!...
  2. 使用DRS的维护模式实现单个VM的测试
  3. NFV — 安全策略
  4. python怎么读取txt文件并统计其字数-python计算文件的行数和读取某一行内容的实现方法...
  5. 内存映射文件(File Mapping)API
  6. XGBoost 与 Spark 在广告排序中的应用
  7. java word在线预览_java 生成word文档并且在线预览的问题
  8. 微课|中学生可以这样学Python(1.5节):标准库与扩展库对象的导入
  9. c语言实现可变单链表,c语言实现单链表
  10. kangle 3.4.8 发布,国产开源 Web 服务器
  11. ansys linux运行_如何在linux系统下启动workbench。谢谢啦。 - 仿真模拟 - 小木虫 - 学术 科研 互动社区...
  12. Java class反编译工具
  13. 058线性反馈移位寄存器产生m序列
  14. ati 缺少关键性文件_win10重装系统缺少计算机所需的介质驱动程序的解决方法
  15. Python smtp拟人个性化群发邮件,imap退信批量处理和SuiteCRM结合使用问题
  16. uniapp对接极光推送
  17. MATLAB 中有哪些命令,让人相见恨晚?
  18. XMind8思维导图 破解版
  19. [技术] OIer的C++标准库 : STL入门
  20. 【C++学习笔记】特殊用途语言特性

热门文章

  1. 半生颠沛流离,归来仍是少年。这人生啊,如梦!
  2. 继戴姆勒之后 德国公司Bury就汽车通信相关专利授权投诉诺基亚
  3. 微型计算机硬盘接口有哪些,什么是硬盘(硬盘接口有哪些)
  4. 【远程编辑工具UE】超好用的工具UltraEdit(UE)远程连接Linux的方法,以及FTP Component Failuer连接失败的解决方法
  5. lucene spatial 6.1搜索附近的饭店
  6. 中望CAD教程:如何将PDF转化为DWG格式文件
  7. 渗透之——asp图片木马的制作和使用
  8. storyboard搭建项目_Swift - 使用storyboard创建表格视图(TableViewController)
  9. 「手把手教你」用Python量化海龟交易法则
  10. 2的立方根用计算机怎样摁,用计算器求立方根