网易云歌单添加到php,给自己的网站添加网易云音乐歌单吧^ ^-程序员宅基地

技术标签: 网易云歌单添加到php  

7c6c9b97ce6677b24a8af407d9882114.png

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

APlayer

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

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

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链接

网易云音乐API

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

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

# 歌单

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,但是返回的数据不是我们所需要的呀

比如这个歌单的接口

# Request

https://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的歌曲,所以我们这里直接写在返回结果上。

歌词处理

还有一个问题就是歌词,上面的接口中,歌词返回结果也不是我们需要的格式

# Request

https://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}`//这里歌词写上我们定义的接口地址

}

//...

测试一下吧

通过以上处理,我们接口就返回我们自定义的数据格式了

# Request

https://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页面,可以直接文章开头的方式引用

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 example

onPlay = () => {

console.log('on play');

};

onPause = () => {

console.log('on pause');

};

// example of access aplayer instance

onInit = 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 (

{...props}

onInit={this.onInit}

onPlay={this.onPlay}

onPause={this.onPause}

/>

{/* example of access aplayer instance API */}

this.ap.toggle()}>toggle

);

}

}

如果是vue项目,可以使用vue-aplayer

: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'

}"

/>

小节

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

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

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

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_42299778/article/details/115199229

智能推荐

Android记录19-朋友圈动态发布时间计算_安卓朋友圈详情显示时间-程序员宅基地

文章浏览阅读1.2k次。转自:IT_xiao小巫,http://blog.csdn.net/wwj_748前面的一篇文章给大家关于时间知识点的分享http://blog.csdn.net/wwj_748/article/details/11536421,本篇博客笔者想给大家分享的事如何通过Calendar来计算我们平时需要用到的年、月、日、时、分、秒等,还有如何计算类似朋友圈动态发布的时间。这里要大家去了解的几个_安卓朋友圈详情显示时间

Linux Journald日志系统_sd_journal_print-程序员宅基地

文章浏览阅读1.6w次,点赞2次,收藏5次。By Toradex 胡珊逢1). 简介长久以来 syslog 是每一个 Unix 系统中的重要部件。在漫长的历史中在各种 Linux 发行版中都有不同的实现去完成类似的工作,它们采取的是逻辑相近,并使用基本相同的文件格式。但是 syslog 也存在诸多的问题,随着新设备的出现以及对安全的重视,这些缺点越发显得突出,例如日志消息内容无法验证、数据格式松散、日志检索低效、有限的元数据保存、无_sd_journal_print

利用autoit自动关闭指定标题窗口_autoit 关闭窗口-程序员宅基地

文章浏览阅读5.4k次。最近使用PL/SQL Developer 比较两个数据库数据差异,因部分表上没有主键,PL/SQL 就会弹出一个确认框提示某某表没有主键。因为有很多表没有不停的弹出,就得不停的点击确认,非常繁琐,情急之中想到了autoit。编写脚本如下:While(True)WinClose("Information")Sleep(2000)WEnd脚本说明:上面的In_autoit 关闭窗口

pdflush内核线程池及其中隐含的竞争-程序员宅基地

文章浏览阅读95次。pdflush内核线程池是Linux为了回写文件系统数据而创建的进程上下文工作环境。它的实现比较精巧,全部代码只有不到250行。 1 /* 2 * mm/pdflush.c - worker threads for writing back filesystem data 3 * 4 *..._pf_flusher

迭代器 生成器_迭代生成器-程序员宅基地

文章浏览阅读72次。1,迭代器(iterable)可迭代对象 list,tuple,dict ,str,set 等类型的数据使用for’…in…的循环语法从其中依次拿到数据进行使用,我们把这样的过程称为遍历,也叫迭代‘class MyList(object):… def init(self):… self.container = []… def add(self, i..._迭代生成器

css3新动_css3新特性之动画使用-程序员宅基地

文章浏览阅读48次。有个朋友N久没有动前端,最近因为需求和人手不得不硬着头皮拾起它。 有个需求是图片放大浏览,因为时间紧没有时间学新的如react等,所以还是用jq,一直在找插件,但是都不太满意。所以问我有没推荐。我想了想,要引入新的插件开销还是有的,可以使用CSS3新特性。transform有个方法scale就是实现缩放的,再配合上animation不要太简单。不过此前还有个问题,图片放大之后不能影响到现有的盒子结..._css3新特性之动画效果

随便推点

Xcode9启动图及icon分辨率、尺寸、大小_xcode appicon 大小-程序员宅基地

文章浏览阅读1.1k次。启动页尺寸大小 *Device* *Portrait* *Landscape size* ------------------------------------------------------------------------------ 12.9" iPad Pro 2048px × 2732px 2732px × 2048px 10.5" ..._xcode appicon 大小

数据科学 IPython 笔记本 7.10 组合数据集:合并和连接_merged.loc-程序员宅基地

文章浏览阅读3.5w次。7.10 组合数据集:合并和连接原文:Combining Datasets: Merge and Join译者:飞龙协议:CC BY-NC-SA 4.0本节是《Python 数据科学手册》(Python Data Science Handbook)的摘录。Pandas 提供的一个基本特性,是内存中的高性能的连接和合并操作。如果你曾经使用过数据库,那么你应该熟悉这种类型的数据交互。它的..._merged.loc

Mysql学习笔记--多表之间约束等详细记录_多表之间锁定同项目-程序员宅基地

文章浏览阅读423次。sql 进阶学习笔记—多表(二)笔记(一)内容回顾Mysql学习笔记(基础)基础sql语句详细记录​ 数据库的创建 : create database 数据库的名 character set 字符集 collate 校对规则​ 数据库的删除: drop database 数据库名​ 修改: alter database 数据库 character set 字符集(utf8)​ 查询:..._多表之间锁定同项目

网优谷告诉你,SEO关键词布局的重要性_关键词的布局 重要性-程序员宅基地

文章浏览阅读426次。网优谷告诉你,SEO关键词布局的重要性一个成熟的网站,会根据关键词优化难度分配到不同的页面上,依次为首页、栏目页、专题页(或聚合页)、文章页面等。若关键词布局有问题,则可能优化许久都没有排名,此时要认真分析关键词是否难度过大,是否需要重新分配关键词。当然,这需要几个月、甚至一年时间来判断,不要因为没有排名而乱修改关键词。温馨提醒:所谓修改关键词,其实就是修改标题,过度频繁可能会被惩罚。修改m..._关键词的布局 重要性

Elasticsearch教程(32) ES 聚合查询后过滤 Distinct Group By Having功能_elasticsearch 桶聚合后的值怎么添加过滤-程序员宅基地

文章浏览阅读8.5k次,点赞7次,收藏36次。一、之前写的关于ES聚合的博客Elasticsearch教程(3) ES聚合查询DSLElasticsearch教程(4) High Level REST Client API 查询 聚合 分组Elasticsearch教程(5) 指标聚合 SQL DSL JavaAPIElasticsearch教程(6) 桶聚合Query DSL-Terms AggregationElasticsearch教程(10) ES term terms prefix 搜索 聚合查询 详细总结Elasticsearc_elasticsearch 桶聚合后的值怎么添加过滤

12.linux系统中的软件管理_下载指定安装包存放于 /mnt-程序员宅基地

文章浏览阅读100次。12.linux系统中的软件管理1.Linux中软件包的类型1.DEB UBlinux DEBlinux2.RPM redhat centOS fadora3.bz2|gz|xz 1.需要源码安装需要编译2.绿色软件,直接可用ntfs-3g_ntfsprogs-2017.3.23.tgz 需要编译 “configure”Firefox-latest-x86_64.tar.bz2 绿色“注意在rhel8中只能使用绿色软件,源码编译软件和rpm软件”2.软件包的名称结构[dh_下载指定安装包存放于 /mnt

推荐文章

热门文章

相关标签