温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

使用vue怎么在页面中实现一个音乐播放器

发布时间:2021-04-09 16:07:21 来源:亿速云 阅读:462 作者:Leah 栏目:web开发

这期内容当中小编将会给大家带来有关使用vue怎么在页面中实现一个音乐播放器,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

用css做图标

.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" :></div>

歌曲资源

爬下接口

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

解决跨域问题

因为接口支持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实现

踩了坑

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怎么在页面中实现一个音乐播放器了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注亿速云行业资讯频道。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

vue
AI