Cette fois, je vais vous présenter JS pour implémenter l'interface du lecteur de musique. Quelles sont les précautions à prendre pour que JS implémente l'interface du lecteur de musique ? Ce qui suit est un cas pratique, jetons un coup d'œil.
Cet article présente un exemple d'implémentation d'un lecteur de musique sur une page Vue et le partage avec tout le monde. Les détails sont les suivants :
L'effet est le suivant :
.
Adresse du projet : https://github.com/ermu592275254/MiniMusicPlayer
Adresse de la démo : https://ermu592275254.github.io /MiniMusicPlayer/(le lien de la chanson a expiré)
Conception avant développement
Interface
Pour réaliser un lecteur de musique, le l'interface doit être cool. C'est tellement bas que je ne ressens rien en écoutant la musique. Il est destiné à être utilisé au travail, j'ai donc réalisé une interface similaire à NetEase Cloud Music avec une taille adaptée. Pas besoin d'être compatible avec les téléphones mobiles.
Utilisez CSS pour créer des icônes
Ceci est basé sur des besoins simples et pratiques. Les icônes peuvent être SVG, url ou CSS. Par rapport à l'url, SVG et CSS sont meilleurs. Par souci de pratique, j'ai finalement choisi le CSS. Faire bon usage de after et before peut réduire considérablement l’imbrication du 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; }
Dessiner un enregistrement
L'enregistrement de NetEase Cloud est très beau, je veux aussi faire un enregistrement. Utilisez bien box-shadow et il peut être fait avec ! un élément Très bel effet de disque.
.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; }
Utiliser la plage comme barre de progression
Le style audio lui-même est moche et les effets présentés par différents navigateurs sont également différents. Bien sûr, vous pouvez modifier le style de l'audio. La méthode traditionnelle consiste à masquer l'audio via l'attribut Controls, puis à utiliser p à la place. C'est maintenant l'ère HTML5. Bien sûr, nous devons utiliser un nouvel élément plus adapté à la scène : 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); }
Filtre de fond flou
C'est génial de définir une image comme arrière-plan. On peut dire que l'arrière-plan fournit la moitié de l'apparence de l'ensemble. joueur. Le paramétrage est également très simple, utilisant des filtres 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; }
L'image d'arrière-plan est contrôlée via js.
<p class="bg-blur" :style="`background-image:url(${currentSong.album_logo})`"></p>
Ressources de chansons
Descendez l'interface
Allez directement sur le site officiel de Xiami pour ouvrir le réseau et copiez l'url au facteur. Entrez et faites la demande. En modifiant les en-têtes, on constate que le Referer sera vérifié. Autrement dit, seuls les noms de domaine autorisés par Xiami peuvent accéder à cette interface. http://api.xiami.com/web?v=2.0&app_key=1&key=aliez&page=1&limit=5&callback=jsonp154&r=search/songs
Résoudre les problèmes inter-domaines
Parce que l'interface prend en charge jsonp. Au début, j'ai essayé de configurer le navigateur Chrome pour qu'il inter-domaine, puis j'ai fait une requête jsonp via $.ajax. Accessible normalement.
Ensuite, il a soudainement cessé de fonctionner. Xiami a-t-il imposé des restrictions
Ensuite, j'ai utilisé un nœud pour démarrer un service, simulé le référent pour lancer une demande, puis transmis la demande à la page. J'ai accidentellement écrit à un agent.
... 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; ...
Défilement des paroles
En tant que lecteur de haute qualité, le défilement des paroles est un must.
Principe
Enregistrez chaque parole en tant qu'objet avec l'heure correspondante. Lorsque la durée actuelle de la chanson est supérieure ou égale à la durée des paroles et inférieure à la durée de la ligne suivante des paroles, faites défiler les paroles jusqu'à la zone visible. Et changez la couleur de la police.
Paroles formatées
Les paroles renvoyées par l'interface étaient déroutantes Après une étude minutieuse, j'ai trouvé qu'elles étaient régulières.
[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; },
Implémentation de la barre de recherche
Monter les sous-composants sous le même fichier
Afin de suivre le développement modulaire , il a été décidé de La barre de recherche est écrite comme un sous-composant. Lors de l'écriture de sous-composants sur la même page, il est important de monter les sous-composants sur le modèle correspondant. Ce modèle ne peut pas être inclus par l'élément de montage du composant parent, sinon le composant parent signalera un état indéfini car il ne peut pas restituer les données dans le composant enfant.
<p id="app" class="main"> ... </p> <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 résout la transmission de données
通过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>
待优化
手动修改进度,偶尔会不生效。
搜索暂不支持分页
不支持建歌单
背景颜色与进度条颜色相近需修改进度条颜色
不支持播放模式选择-单曲循环-随机播放
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!