最近应该发现我的博客左下角有一个音乐播放器(https://blog.codelabo.cn):
这是如何实现的?让我们一起看看
一名球员
首先,我们需要一个音频播放器。这里我用的是Aplayer(http://Aplayer . js . org),它是来自bilibili的前端神DIy god(https://github . com/DIy god)的开源播放器。有兴趣可以去TA的主页(https://diygod.me),很神奇。我在这里
我们来看看APlayer的官方文档。方法很简单。
<link rel="stylesheet" href="APlayer.min.css"><div id="aplayer"></div>< src="APlayer.min.js"></>const ap = new APlayer({container: document.getElementById('aplayer'),audio: [{name: 'name',artist: 'artist',url: 'url.mp3',cover: 'cover.jpg'}]});音频这里是一个音频列表,可以是一个对象,也可以是一个对象数组。对象的具体参数如下:
名称描述name音频名称artist音频艺术家url音频链接cover音频封面lrc音频歌词LRC有三种方法可以把歌词传递给一个播放器。详细信息,请参考https://aplayer.js.org/#/home?身份证=lrc,在这里我们选择最方便的一个,并直接链接到lrc。
网易云音乐API
这一部分,我在网上找到了一些人分享的API。官方不可能公开API,要谨慎使用。也许有一天会被修改。
http://moonlib.com/606.html
现在其实要两个,一个是歌单,一个是歌词。
# 歌单https://music.163.com/api/playlist/detail?id=37880978id是歌单ID
# 歌词https://music.163.com/api/song/lyric?os=pc&id=93920&lv=-1&kv=-1&tv=-1Id为歌曲IDlv:值为-1,我猜应该判断是否搜索歌词格式kv:值为-1,这个值似乎不影响结果,含义未知tv:值为-1,是否搜索Triric格式。
接口实现虽然我们已经找到了网易云音乐API,但是返回的数据并不是我们需要的。比如这个歌单的界面:
# Requesthttps://music.163.com/api/playlist/detail?id=2119983629# Response{"result":{"subscribers":[],"subscribed": false,"creator":{...},"artists": null,"tracks":[{album: {name: "メトロノーム",id: 36787278, type: "专辑",size: 12, picId:18419018788768520,}alias: [],artists: [{name: "MACO", id: 901025, picId: 0, img1v1Id: 0, briefDesc: "",…}],audition: null,bMusic: {...},commentThreadId: "R_SO_4_515573221",copyFrom: "",copyright: 1,copyrightId: 7003,crbt: null,...}]}}里面有很多字段。以上我只列举了其中的一部分。曲目是一个歌曲列表,但很明显,它远远不是我们需要的格式。那么如何转换成我们需要的数据格式呢?
[{name: 'name',artist: 'artist',url: 'url.mp3',cover: 'cover.jpg',lrc: 'a.lrc'}]这里我们需要在服务器端完成。思路很简单。在服务器上请求https://music.163.com/api/playlist/detail? Id = 2119983629,然后得到结果,然后手动处理,最后返回给客户端,相当于一次传输。
我这里的服务器是用koa实现的,其他框架应该也差不多。
服务端发起请求熟悉的提取也可以用于在服务器上启动请求,但是您需要首先安装库节点提取(https://www.npmjs.com/package/node-fetch):
yarn add node-fetch然后你可以像前端一样提出请求:
const fetch = require('node-fetch');//...const getPlayList = (id) => {return fetch(`http://music.163.com/api/playlist/detail?id=${id}`).then((response) => {if (response.ok) {return response.json();}}).catch((err) => {console.warn(err);})} 接口定义现在我们需要添加一个接口来处理歌曲列表,并返回我们需要的格式。
//获取音乐列表router.get('/playlist/:id', async (ctx, next) => {const responseData = {"success": false,"data":[],"message": "",}const { id } = ctx.params;try {const data = await getPlayList(id);if(data.code===200){const playList = data.result.tracks.map(item=>({id: item.id,name: item.name,artist: item.artists.map(el=>el.name).join(','),//由于歌手是一个数组,这里我们把它转换成字符串拼接url: `https://music.163.com/song/media/outer/url?id=${item.id}.mp3`,//歌曲地址cover: item.album.picUrl.replace(/http:/,'https:'),lrc:null}))responseData.success = true;responseData.message = '操作成功';responseData.data = playList;ctx.body = responseData;}} catch (error) {responseData.success = false;responseData.message = error.message;responseData.data = [];ctx.body = responseData;}});请注意此处歌曲链接的url,它没有包含在原始返回信息中,只有歌曲Id,但我们发现通过https://music.163.com/song/media/outer/url?, ID = ID可以直接指定在线播放中带有ID的歌曲,所以我们直接在此处返回的结果上写它。
歌词处理
另一个问题是歌词。在上面的界面中,歌词返回结果不是我们需要的格式:
# Requesthttps://music.163.com/api/song/lyric?os=pc&id=93920&lv=-1&kv=-1&tv=-1# Response{"sgc": true,"sfy": false,"qfy": false,"lrc": {"version": 7,"lyric": "[00:29.620]细雨带风湿透黄昏的街道n[00:35.050]抹去雨水双眼无帮地仰望n[00:40.240]望向孤单的晚灯是那伤感的记忆n[00:48.630]再次泛起心里无数的思念n[00:54.000]以往片刻欢笑仍挂在脸上n[00:58.770]愿你此刻可会知是我衷心的说声n[01:06.310]喜欢你n[01:08.940]那双眼动人笑声更迷人n[01:14.330]愿再可轻抚你那可爱面容n[01:22.490]挽手说梦话象昨天你共我n[01:42.970]满带理想的我曾经多冲动n[01:48.340]埋怨与她相爱难有自由n[01:53.040]愿你此刻可会知是我衷心的说声n[02:00.420]喜欢你n[02:03.230]那双眼动人笑声更迷人n[02:08.540]愿再可轻抚你那可爱面容n[02:16.750]挽手说梦话象昨天你共我n[02:24.740]每晚夜里自我独行n[02:27.670]随处荡 多冰冷n[02:35.070]以往为了自我挣扎从不知她的痛苦n[02:49.380]喜欢你n[02:52.020]那双眼动人笑声更迷人n[02:57.420]愿再可轻抚你那可爱面容n[03:05.590]挽手说梦话象昨天你共我n[03:13.870]挽手说梦话象昨天你共我n"},"klyric": {...},"code": 200}反正很全面,但我们需要的只是里面的内容。比如我只需要上面这一段:
[00:29.620]细雨带风湿透黄昏的街道[00:35.050]抹去雨水双眼无帮地仰望[00:40.240]望向孤单的晚灯是那伤感的记忆[00:48.630]再次泛起心里无数的思念[00:54.000]以往片刻欢笑仍挂在脸上[00:58.770]愿你此刻可会知是我衷心的说声...所以我们需要再次成为中间人:
const getLyric = (id) => {return fetch(`http://music.163.com/api/song/lyric?os=pc&id=${id}&lv=-1&kv=-1&tv=-1`).then((response) => {if (response.ok) {return response.json();}}).catch((err) => {console.warn(err);})}//获取音乐歌词router.get('/lyric/:id', async (ctx, next) => {const { id } = ctx.params;try {const lyric = await getLyric(id);ctx.body = lyric.lrc.lyric;//返回指定部分} catch (error) {ctx.body = '';}});这样就可以直接使用/API/抒情/:ID在上面的歌词列表中获取歌词:
//...{id: item.id,name: item.name,artist: item.artists.map(el=>el.name).join(','),url: `https://music.163.com/song/media/outer/url?id=${item.id}.mp3`,cover: item.album.picUrl.replace(/http:/,'https:'),lrc:`/api/lyric/${item.id}`//这里歌词写上我们定义的接口地址}//... 测试一下吧通过以上处理,我们的界面返回到我们自定义的数据格式:
# Requesthttps://localhost:3000/api/playlist/2119983629# Response{"success": true,"data": [{"id": 515573221,"name": "Sweet Memory","artist": "MACO","url": "https://music.163.com/song/media/outer/url?id=515573221.mp3","cover": "https://p1.music.126.net/-U7mfaIjENUu8G_O0Dhv8g==/18419018788768520.jpg","lrc": "/api/lyric/515573221"},{"id": 488388942,"name": "願い~あの頃のキミへ~","artist": "當山みれい","url": "https://music.163.com/song/media/outer/url?id=488388942.mp3","cover": "https://p1.music.126.net/kbLlBkGfEcA3RJyC5JhkDA==/18346451021830743.jpg","lrc": "/api/lyric/488388942"},...],"message": "操作成功"} 添加到博客其实界面的数据转换是关键,所以在下面加到自己的页面就很简单了。
如果你是传统的HTML页面,可以在文章开头直接引用:
<link rel="stylesheet" href="APlayer.min.css"><div id="aplayer"></div>< src="APlayer.min.js"></>const ap = new APlayer({container: document.getElementById('aplayer'),audio: [{name: 'name',artist: 'artist',url: 'url.mp3',cover: 'cover.jpg'}]});如果使用模块管理器:
import 'APlayer/dist/APlayer.min.css';import APlayer from 'APlayer';const ap = new APlayer(options);如果是react项目,可以使用封装的REACT-A播放器(罗/REACT-A播放器):
import React from 'react';import ReactAplayer from 'react-aplayer';export default class App extends React.Component {// event binding exampleonPlay = () => {console.log('on play');};onPause = () => {console.log('on pause');};// example of access aplayer instanceonInit = ap => {this.ap = ap;};render() {const props = {theme: '#F57F17',lrcType: 3,audio: [{name: '光るなら',artist: 'Goose house',url: 'https://moeplayer.b0.upaiyun.com/aplayer/hikarunara.mp3',cover: 'https://moeplayer.b0.upaiyun.com/aplayer/hikarunara.jpg',lrc: 'https://moeplayer.b0.upaiyun.com/aplayer/hikarunara.lrc',theme: '#ebd0c2'}]};return (<div><ReactAplayer{...props}onInit={this.onInit}onPlay={this.onPlay}onPause={this.onPause}/>{/* example of access aplayer instance API */}<button onClick={() => this.ap.toggle()}>toggle</button><div>);}}在vue项目中,您可以使用vue-a播放器(https://github.com/sevenoutman/vue-a播放器):
<aplayer autoplay:music="{title: 'secret base~君がくれたもの~',artist: 'Silent Siren',src: 'https://moeplayer.b0.upaiyun.com/aplayer/secretbase.mp3',pic: 'https://moeplayer.b0.upaiyun.com/aplayer/secretbase.jpg'}"/>更多信息请参考Aplayer Ecology(https://Aplayer . js . org/#/zh-Hans/ecologs)。
小事
在这里的歌单里,我选择了自己的歌曲集。每次用网易云音乐客户端播放听歌,我喜欢的歌都能在博客上同步更新。
差不多就是这样。可能对于专业的后端开发来说,这些都是小学生的操作,但是对于一个前端来说,做这些事情感觉就像是闯了一个新世界,还是有很多感悟的。现在nodeJS可以帮我们解决很多以前前端做不到的事情,进一步打开了前端和后端的天然屏障,离整个栈越来越近
如果你喜欢我的博客(https://blog.codelabo.cn),可以多关注一下。
声明:文章版权归作者所有。如有侵权,请联系边肖删除。
1.《网易云官网音乐 给自己的网站添加网易云音乐歌单吧 ^ ^》援引自互联网,旨在传递更多网络信息知识,仅代表作者本人观点,与本网站无关,侵删请联系页脚下方联系方式。
2.《网易云官网音乐 给自己的网站添加网易云音乐歌单吧 ^ ^》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。
3.文章转载时请保留本站内容来源地址,https://www.lu-xu.com/guonei/1030897.html