给自己的网站添加网易云音乐歌单吧^ ^

news/2024/4/27 18:28:12/文章来源:https://blog.csdn.net/weixin_34183910/article/details/88715653

最近应该发现,我的博客https://blog.codelabo.cn左下角多了一个音乐播放器

aplayer

这个是怎么实现的?一起来看看吧

APlayer

首先我们需要一个音频播放器,这里我用到了APlayer,这是由bilibili前端大神DIYgod开源的播放器,有兴趣的可以去TA的主页看看,非常惊艳,这里我就不多说了

我们看一下APlayer的官方文档,方法很简单

<link rel="stylesheet" href="APlayer.min.css">
<div id="aplayer"></div>
<script src="APlayer.min.js"></script>
const ap = new APlayer({container: document.getElementById('aplayer'),audio: [{name: 'name',artist: 'artist',url: 'url.mp3',cover: 'cover.jpg'}]
});

这里的audio是一个音频列表,可以是一个对象或对象数组

对象具体的参数如下

名称描述
name音频名称
artist音频艺术家
url音频链接
cover音频封面
lrc音频歌词

LRC一共有三种方式来给 APlayer 传递歌词,详情可参考https://aplayer.js.org/#/home?id=lrc,

这里我们选择最方便的一种,直接给LRC链接

网易云音乐API

这部分我找到了网上有人分享的API,这种官方不可能给公开API,所以还是要小心使用,说不定哪天就被修改了

http://moonlib.com/606.html

我们现在其实想要两个,一个是歌单的列表,还有一个是歌词。

# 歌单https://music.163.com/api/playlist/detail?id=37880978
id为歌单ID
# 歌词https://music.163.com/api/song/lyric?os=pc&id=93920&lv=-1&kv=-1&tv=-1
id为歌曲ID
lv:值为-1,我猜测应该是判断是否搜索lyric格式
kv:值为-1,这个值貌似并不影响结果,意义不明
tv:值为-1,是否搜索tlyric格式

接口实现

虽然我们已经找到了网易云音乐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,...}]}
}

里面字段很多,我上面只列举了一部分,tracks就是歌单列表,但是很显然,和我们需要的格式还差很多

那么怎么来转换一下,变成我们需要的数据格式呢?

[{name: 'name',artist: 'artist',url: 'url.mp3',cover: 'cover.jpg',lrc: 'a.lrc'
}]

这里我们就需要在服务端来完成了,思路很简单,在服务器上请求https://music.163.com/api/playlist/detail?id=2119983629这个接口,然后拿到结果后手动处理一下,最后再返给客户端,相当于做了一次中转

我这里服务端是用koa实现的,其他框架应该差不多

服务端发起请求

在服务端发起请求也可以用我们熟悉的fetch,不过你需要先安装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/lyric/: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>
<script src="APlayer.min.js"></script>
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-aplayer

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-aplayer

<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生态

小节

这里的歌单,我选择了自己收藏的歌曲。每次用网易云音乐客户端播放听歌的时候,收藏的歌曲,在我的博客上也可以同步进行更新。

差不多就这些了,可能对于专业后端开发来说,这些完全就是小学生操作,但是对于一个前端来说,做这些事就感觉闯入了一片新天地,还是有很多感悟的。很多以前前端做不了的事,现在nodeJS也能帮我们解决,进一步打通了前后端的天然屏障,离全栈也越来越近了 ^ ^

大家如果喜欢我的博客,可以多多关注一下

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_711203.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

优化网站设计:减少DOM元素的数量

2019独角兽企业重金招聘Python工程师标准>>> 网站设计的优化是一个很大的话题,有一些通用的原则,也有针对不同开发平台的一些建议。这方面的研究一直没有停止过&#xff0c;我在不同的场合也分享过这样的话题。 作为通用的原则&#xff0c;雅虎的工程师团队曾经给出…

阿里云服务器搭配宝塔面板安装Redis为网站提速

一、Redis是什么&#xff1f; 按照网络上的解释&#xff1a;Redis是一款内存高速缓存数据库。Redis全称为&#xff1a;Remote Dictionary Server&#xff08;远程数据服务&#xff09;Redis以内存作为数据存储介质&#xff0c;所以读写数据的效率极高&#xff0c;远远超过数据库…

如何利用URLOS和云存储打造一个不惧怕宕机的网站环境

现今大多数企业都具备开通网络业务的能力&#xff0c;不管是创建企业网站、企业在线服务、或者是交易平台、商城等等&#xff0c;这些技术都已经非常普及&#xff0c;只要投入相应的研发成本即可。所谓开国容易守国难&#xff0c;没有稳定在线能力&#xff0c;往往会让企业在关…

一步步构建大型网站架构

之前我简单向大家介绍了各个知名大型网站的架构&#xff0c;亿万用户网站MySpace的成功秘密、Flickr架构、YouTube网站架构、PlentyOfFish 网站架构学习、WikiPedia技术架构学习笔记。这几个都很典型&#xff0c;我们可以从中获取很多有关网站架构方面的知识&#xff0c;看了之…

大型网站技术架构(一)大型网站架构演化

看完了有一本书&#xff0c;就应该有所收获&#xff0c;有所总结&#xff0c;最近把《大型网站技术架构》一书给看完了&#xff0c;给人的印象实在深刻&#xff0c;再加上之前也搞过书本上讲的反向代理和负载均衡以及session独立存储和缓存&#xff0c;因此书本看起来还是挺通俗…

大型网站技术架构(四)网站的高性能架构

网站性能是客观的指标&#xff0c;可以具体体现到响应时间、吞吐量、并发数、性能计数器等技术指标。 1、性能测试指标 1.1 响应时间 指应用执行一个操作需要的时间&#xff0c;指从发出请求到最后收到响应数据所需要的时间。如下列出了系统常用的操作响应时间表. 操作 响应…

大型网站技术架构(五)网站高可用架构

网站的可用性&#xff08;Avaliability&#xff09;描述网站可有效访问的特性。 1、网站可用性的度量与考核 网站不可用时间&#xff08;故障时间&#xff09;故障修复时间点-故障发现&#xff08;报告&#xff09;时间点 网站年度不可用时间&#xff08;1-网站不可用时间/年度…

大型网站技术架构(六)网站的伸缩性架构

网站系统的伸缩性架构最重要的技术手段就是使用服务器集群功能&#xff0c;通过不断地向集群中添加服务器来增强整个集群的处理能力。“伸”即网站的规模和服务器的规模总是在不断扩大。 1、网站架构的伸缩性设计 网站的伸缩性设计可以分成两类&#xff0c;一类是根据功能进行…

大型网站技术架构(七)网站的可扩展性架构

扩展性是指对现有系统影响最小的情况下&#xff0c;系统功能可持续扩展或提升的能力。 设计网站可扩展架构的核心思想是模块化&#xff0c;并在此基础上&#xff0c;降低模块间的耦合性&#xff0c;提供模块的复用性。模块通过分布式部署&#xff0c;独立的模块部署在独立的服务…

大型网站技术架构(八)网站的安全架构

从互联网诞生起&#xff0c;安全威胁就一直伴随着网站的发展&#xff0c;各种Web攻击和信息泄露也从未停止。常见的攻击手段有XSS攻击、SQL注入、CSRF、Session劫持等。 1、XSS攻击 XSS攻击即跨站点脚本攻击&#xff08;Cross Site Script&#xff09;&#xff0c;指黑客通过篡…

微服务架构:搭建网站扫码登录的功能设计

微服务架构应该是什么样子在这之前先看一看一个微服务架构落地以后应该是什么样子的。平常所有的微服务架构更多的是从框架来讲的像Dubbo&#xff0c;SpringCloud等&#xff0c;从整个SpringCloud的生态来讲它也只包含微服务的一部分。因为微服务的拆分不可避免的造成了系统的复…

Docker学习总结(6)——通过 Docker 化一个博客网站来开启我们的 Docker 之旅

通过 Docker 化一个博客网站来开启我们的 Docker 之旅 这篇文章包含 Docker 的基本概念&#xff0c;以及如何通过创建一个定制的 Dockerfile 来 Docker 化Dockerize一个应用。 Docker 是一个过去两年来从某个 idea 中孕育而生的有趣技术&#xff0c;公司组织们用它在世界上每个…

Nginx学习总结(2)——Nginx手机版和PC电脑版网站配置

考虑到网站的在多种设备下的兼容性&#xff0c;有很多网站会有手机版和电脑版两个版本。访问同一个网站URL&#xff0c;当服务端识别出用户使用电脑访问&#xff0c;就打开电脑版的页面&#xff0c;用户如果使用手机访问&#xff0c;则会得到手机版的页面。 1、判断客户端的设…

wordpress网站换个云服务器,wordpress更换服务器

wordpress更换服务器 内容精选换一换如果Linux操作系统云服务器未安装密码重置插件&#xff0c;可以参见本节内容重新设置密码。本节操作重置的是root用户的密码&#xff0c;您可以重置完root密码后登录云服务器后再更换秘钥或重置非root用户的密码。Windows操作系统请参见重置…

VMware产品演示网站

2015年4月28日, 下午1:19 包括了vClould Suite、Virtual SAN、vSphere with Operations Management、vRealize、vSphere 6.0等。都为幻灯片模式&#xff0c;如下图所示。虽然不是视频&#xff0c;但也能基本了解此些产品的功能及配置界面。 网址&#xff1a;http://featurewa…

定期删除网站日志php_tomcat实现定时删除日志

具体方法&#xff1a;(推荐教程&#xff1a;apache)一、创建脚本vim /root/project/tomcat_logs_task/auto-del-15-days-ago-log.sh# /bin/bash#定期删除tomcat 定期删除15天前的已分割日志#日志路径apache_tomcat_api_8079/root/app/apache-tomcat-job36-api-8079/logsapache_…

c++builder 运行网站的api_欧美音乐网站Python爬虫项目实战

爬虫项目实战0x01 目标分析最近发现一个比较好的欧美音乐下载网站&#xff0c;可以下载大部分高质量欧美音乐。该爬虫项目要实现自动化批量获取用户想要下载的音乐。本文从网站分析、爬虫设计、代码实现三个方面出发&#xff0c;系统介绍该爬虫项目。项目完整代码在Github中可以…

优秀常用网站汇总.txt

一、技术类 http://bbs.51cto.com http://www.epubit.com.cn/ https://www.printfriendly.com/ 浏览器插件&#xff0c;可下载51cto专栏等限制复制等页面为pdf https://www.csdn.net/ 二、Linux https://github.com http://www.ansible.com.cn(Ansible中文权威指南) h…

网站图片全自动加密_外卖优惠平台内容加密参数分析!你见过一块钱买外卖的吗?...

Js 加密的内容其实大同小异&#xff0c;目前咸鱼也在不断学习 APP 逆向的知识&#xff0c;之后会出一部分关于 APP 逆向在爬虫中的应用相关的文章&#xff0c;这部分设计的技能栈较广&#xff0c;大家可以先预习 Java 基础与 Android 基础。抓包与加密定位这个网站的加密部分是…