Android网易歌词json接口,网易云音乐API接口-music
一直以來都在關注nodejs,直到最近空閑下來,才嘗試寫寫nodejs小demo。文章如有錯誤歡迎批評指正!來自一位不知名的前端。
前言(本項目僅供學習使用)
1、本demo剛開始采用koa2開發,后面由于koa2的異步響應不好處理(還在研究中)改用express;后續會嘗試使用koa2改造。
2、http請求(csrf偽造)主要參考netmusic-node;其他部分思路參考NeteaseCloudMusicApi。
3、本項目預覽地址https://music.jeeas.cn/
已實現網易云音樂基礎功能和websocket數據推送
以get方式請求
1、搜索歌曲名 params[s=歌曲名,type,offset,limit]
getApi/search?s=歌曲名
2、單曲播放地址 params[id=歌曲id,br]
getApi/music/url?id=25643093
3、歌詞 params[id]
getApi/lyric?id=25643093
4、單曲詳情 params[id]
getApi/music/detail?id=25643093
5、專輯詳情 params[id]
getApi/album/detail?id=2263164
6、歌單類型列表 params[]
getApi/playlist/catlist
7、歌單類型列表-熱門類型 params[]
getApi/playlist/hot
8、推薦新音樂 params[]
getApi/personalized/newsong
9、搜索hot params[]
getApi/search/hot
10、推薦歌單 params[]
getApi/personalized
package.json主要包說明
"dependencies": {
"apicache": "^1.5.2",
"big-integer": "^1.6.47",
"crypto": "^1.0.1",
"ejs": "^2.7.1",
"express": "^4.17.1",
"express-rate-limit": "^3.5.3",
"fs-extra": "^8.1.0",
"redis": "^2.8.0",
"request": "^2.88.0",
"socket.io": "~2.1.1"
}
apicache:請求cache緩存,防止api調用過于頻繁ip被禁掉
ejs:數據模板
express-rate-limit:express內部封裝api訪問限制
redis:數據臨時存儲到redis中未涉及到數據庫操作
socket.io:socket基礎包
項目主入口
server.js
項目啟動后redis的連接狀態以及soketIo會掛載在整個server下,方便后面調用。
...
var redisClient = false;
var ioSocket = null;
//啟動查看redis狀態
redis.initRedis(function(client) {
redisClient = client && client != '' && client != null ? true : false;
io.redisClient = redisClient;
});
...
socketServer.initServer(io);
//static
//api訪問限制20s內60次
//cache 緩存2分鐘 2 minutes 0.05 minutes=3s
//設置跨域訪問
//使用ejs
//使用路由
app.use(router);
...
server.listen(port, () => {
console.log('Socket Server listening at port %d', port);
console.log('Visit http://127.0.0.1:%d', port);
console.log('Hello, I\'m %s, how can I help?', serverName);
});
http.js
項目http請求簡單封裝
var http = require('http');
...
function WebAPI(options, callback) {
//....
var httpClients = http.request({
hostname: 'music.163.com',
method: method,
path: options.path,
headers: {...}
},function(req, res) {
req.on('error', function(err) {
//請求異常處理...
});
req.on('data', function(chunk) {
//獲取數據...
});
req.on('end', function() {
//網易云api調用有時候會響應為空,為空時重新發起請求
//數據接收完畢處理rsp
//回調之前用websoket向所有clients廣播消息,以及更新redis
callback(rsp);
})
});
//網易云csrf偽造,詳情crypto.js
httpClients.write('params=' + cryptoreq.params + '&encSecKey=' + cryptoreq.encSecKey);
httpClients.end();
}
...
module.exports = {
WebAPI: WebAPI,
}
socket.js
服務端接收clients的消息發送,以及向所有clients廣播消息(api調用數)
function initServer(io,callback) {
if (io) {
io.on('connection', function(socket) {
socket.on('message', function(data) {
console.log(data.message)
});
//console.log('emit所有人推送,broadcast除某個套接字以外的所有人發送消息,eg:connection不推送');
//向所有連接推送news消息
socket.broadcast.emit('news', {
message: 'a new connection',
newsType: 'server-prop'
});
if(callback){
callback(socket)
}
socket.on('disconnect', function() {
//console.log('disconnect')
});
});
}
}
module.exports = {
initServer: initServer
};
redis.js
redis簡單的查詢更新封裝
var redis = require('redis');
var client = null;
function initRedis(callback) {
if (!client) {
client = redis.createClient(6379, '127.0.0.1');
}
client.on('connect', function() {
//redis連接成功
console.log('redis connect success!');
if (callback) {
callback(client);
}
});
let first = true;
client.on('error', function() {
//redis連接失敗
console.log('redis connect error!');
if (callback && first == true) {
first = false;
callback(null);
}
});
};
function hmSet(options, callback) {
if (client) {
client.hmset(options.apiType, options.apiName, options.total);
//redis簡單的使用(設置keys的值)
}
}
function hgetAll(keys, callback, isTotal) {
if (client) {
client.hgetall(keys, function(err, obj) {
//redis簡單的使用(查詢所有keys)
});
}
}
function getApiNumber(res) {
//簡單計算api調用總數
}
module.exports = {
hmSet: hmSet,
hgetAll: hgetAll,
initRedis: initRedis
};
基礎功能了解差不多之后,重點介紹一下routes.js路由內部的API封裝,也是整個demo部署的比較核心部分。外部公開的API以http(GET方式)為主,本次以Socket調用(內部)示例,大體分享一下自己的心得體會。
routes.js路由
routes.js
ejs使用說明需要在server.js入口配置
app.set('views', path.join(__dirname, './views'));
app.set("view engine", "ejs");
const express = require('express');
const router = express.Router();
const version = "/v1";
...
router.get('/music', function(request, response) {
//監聽路由路由/music訪問
//console.log(request.query)
//模板使用ejs,response需要設置type,否則會以ejs源碼展示
response.type('html');
//常用模式 response.render(路由模板,回傳頁面參數)
//此時會查找ejs的配置,view/music.ejs
response.render('music', {
title: '網易云音樂Cloud',
keywords:Tools.randomSongs()//隨機取一首歌曲名稱搜索
})
//在music.ejs模板中可以 使用變量
});
/*
**
** 1、搜索歌曲名
** params[s=歌曲名,type,offset,limit]
** /search?s=大城小愛
**
*/
router.get(version + '/search', function(request, response) {
//type:1: 單曲, 10: 專輯, 100: 歌手, 1000: 歌單, 1002: 用戶, 1004: MV, 1006: 歌詞, 1009: 電臺, 1014: 視頻
//offset : 偏移數量,用于分頁 , 如 : 如 :( 頁數 -1)*20, 其中20為limit的值,默認為0
var data = {
s: decodeURI(request.query.s) || '',
offset: request.query.offset || 0,
limit: request.query.limit || 20,
type: request.query.type || 1
};
var params = {
path: '/weapi/cloudsearch/get/web',
request: request,
response: response,
data: data,
apiType: '1'
};
//在WebAPI內部response.send響應web數據
Tools.WebAPI(params)
});
...
module.exports = router;
然后將router.js掛載在server.js下,整個已配置的路由便可以訪問
demo剛開始使用koa2作為服務端的框架,后續因為router.get(xx,function(request, response) { 內部response異步響應不好處理(初學者才疏學淺,非常抱歉,可以一起探討),改用express處理異步響應。})
網易云API的請求訪問方式,可以抓包或者網易云音樂官網搜索慢慢摸索查看,當然也可以借鑒別人的勞動成果!
心得體會編寫中
總結
以上是生活随笔為你收集整理的Android网易歌词json接口,网易云音乐API接口-music的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 站立会议 2
- 下一篇: Android深度探索(卷一)第四章读书