mirror of
https://gitlab.com/Binaryify/neteasecloudmusicapi.git
synced 2025-05-23 22:37:41 +08:00
Merge pull request #1677 from kengwang/feat/api/listen-together
[feat]<api/listentogether>: 一起听 API 相关
This commit is contained in:
commit
848f899afe
@ -3574,13 +3574,17 @@ type='1009' 获取其 id, 如`/search?keywords= 代码时间 &type=1009`
|
||||
|
||||
**调用例子 :** `/artist/new/mv?limit=1` `/artist/new/mv?limit=1&before=1602777625000`
|
||||
|
||||
### 一起听状态
|
||||
### 一起听相关
|
||||
|
||||
说明 :登录后调用此接口可获取一起听状态
|
||||
一起听相关参见此 Issue: [#1676](https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1676)
|
||||
|
||||
**接口地址 :** `/listen/together/status`
|
||||
主机模式:
|
||||
|
||||
**调用例子 :** `/listen/together/status`
|
||||
代码可参考: https://github.com/Binaryify/NeteaseCloudMusicApi/blob/master/public/listen_together_host.html
|
||||
|
||||
访问地址: http://localhost:3000/listen_together_host.html
|
||||
|
||||
从机模式: 待整理
|
||||
|
||||
### batch 批量请求接口
|
||||
|
||||
|
20
module/listentogether_end.js
Normal file
20
module/listentogether_end.js
Normal file
@ -0,0 +1,20 @@
|
||||
// 一起听 结束房间
|
||||
|
||||
module.exports = (query, request) => {
|
||||
const data = {
|
||||
roomId: query.roomId
|
||||
}
|
||||
return request(
|
||||
'POST',
|
||||
`http://interface.music.163.com/eapi/listen/together/end/v2`,
|
||||
data,
|
||||
{
|
||||
crypto: 'eapi',
|
||||
cookie: query.cookie,
|
||||
proxy: query.proxy,
|
||||
realIP: query.realIP,
|
||||
url: '/api/listen/together/end/v2'
|
||||
},
|
||||
)
|
||||
}
|
||||
|
23
module/listentogether_heatbeat.js
Normal file
23
module/listentogether_heatbeat.js
Normal file
@ -0,0 +1,23 @@
|
||||
// 一起听 发送心跳
|
||||
|
||||
module.exports = (query, request) => {
|
||||
const data = {
|
||||
roomId: query.roomId,
|
||||
songId: query.songId,
|
||||
playStatus: query.playStatus,
|
||||
progress: query.progress
|
||||
}
|
||||
return request(
|
||||
'POST',
|
||||
`http://interface.music.163.com/eapi/listen/together/heartbeat`,
|
||||
data,
|
||||
{
|
||||
crypto: 'eapi',
|
||||
cookie: query.cookie,
|
||||
proxy: query.proxy,
|
||||
realIP: query.realIP,
|
||||
url: '/api/listen/together/heartbeat'
|
||||
},
|
||||
)
|
||||
}
|
||||
|
27
module/listentogether_play_command.js
Normal file
27
module/listentogether_play_command.js
Normal file
@ -0,0 +1,27 @@
|
||||
// 一起听 发送播放状态
|
||||
|
||||
module.exports = (query, request) => {
|
||||
const data = {
|
||||
roomId: query.roomId,
|
||||
commandInfo: JSON.stringify({
|
||||
commandType: query.commandType,
|
||||
progress: query.progress || 0,
|
||||
playStatus: query.playStatus,
|
||||
formerSongId: query.formerSongId,
|
||||
targetSongId: query.targetSongId,
|
||||
clientSeq: query.clientSeq,
|
||||
}),
|
||||
}
|
||||
return request(
|
||||
'POST',
|
||||
`http://interface.music.163.com/eapi/listen/together/play/command/report`,
|
||||
data,
|
||||
{
|
||||
crypto: 'eapi',
|
||||
cookie: query.cookie,
|
||||
proxy: query.proxy,
|
||||
realIP: query.realIP,
|
||||
url: '/api/listen/together/play/command/report',
|
||||
},
|
||||
)
|
||||
}
|
20
module/listentogether_room_check.js
Normal file
20
module/listentogether_room_check.js
Normal file
@ -0,0 +1,20 @@
|
||||
// 一起听 房间情况
|
||||
|
||||
module.exports = (query, request) => {
|
||||
const data = {
|
||||
roomId: query.roomId
|
||||
}
|
||||
return request(
|
||||
'POST',
|
||||
`http://interface.music.163.com/eapi/listen/together/room/check`,
|
||||
data,
|
||||
{
|
||||
crypto: 'eapi',
|
||||
cookie: query.cookie,
|
||||
proxy: query.proxy,
|
||||
realIP: query.realIP,
|
||||
url: '/api/listen/together/room/check'
|
||||
},
|
||||
)
|
||||
}
|
||||
|
20
module/listentogether_room_create.js
Normal file
20
module/listentogether_room_create.js
Normal file
@ -0,0 +1,20 @@
|
||||
// 一起听创建房间
|
||||
|
||||
module.exports = (query, request) => {
|
||||
const data = {
|
||||
refer: 'songplay_more'
|
||||
}
|
||||
return request(
|
||||
'POST',
|
||||
`http://interface.music.163.com/eapi/listen/together/room/create`,
|
||||
data,
|
||||
{
|
||||
crypto: 'eapi',
|
||||
cookie: query.cookie,
|
||||
proxy: query.proxy,
|
||||
realIP: query.realIP,
|
||||
url: '/api/listen/together/room/create'
|
||||
},
|
||||
)
|
||||
}
|
||||
|
33
module/listentogether_sync_list_command.js
Normal file
33
module/listentogether_sync_list_command.js
Normal file
@ -0,0 +1,33 @@
|
||||
// 一起听 更新播放列表
|
||||
|
||||
module.exports = (query, request) => {
|
||||
const data = {
|
||||
roomId: query.roomId,
|
||||
playlistParam: JSON.stringify({
|
||||
commandType: query.commandType,
|
||||
version: [
|
||||
{
|
||||
userId: query.userId,
|
||||
version: query.version
|
||||
}
|
||||
],
|
||||
anchorSongId: '',
|
||||
anchorPosition: -1,
|
||||
randomList: query.randomList.split(','),
|
||||
displayList: query.displayList.split(',')
|
||||
})
|
||||
}
|
||||
return request(
|
||||
'POST',
|
||||
`http://interface.music.163.com/eapi/listen/together/sync/list/command/report`,
|
||||
data,
|
||||
{
|
||||
crypto: 'eapi',
|
||||
cookie: query.cookie,
|
||||
proxy: query.proxy,
|
||||
realIP: query.realIP,
|
||||
url: '/api/listen/together/sync/list/command/report'
|
||||
},
|
||||
)
|
||||
}
|
||||
|
20
module/listentogether_sync_playlist_get.js
Normal file
20
module/listentogether_sync_playlist_get.js
Normal file
@ -0,0 +1,20 @@
|
||||
// 一起听 当前列表获取
|
||||
|
||||
module.exports = (query, request) => {
|
||||
const data = {
|
||||
roomId: query.roomId
|
||||
}
|
||||
return request(
|
||||
'POST',
|
||||
`http://interface.music.163.com/eapi/listen/together/sync/playlist/get`,
|
||||
data,
|
||||
{
|
||||
crypto: 'eapi',
|
||||
cookie: query.cookie,
|
||||
proxy: query.proxy,
|
||||
realIP: query.realIP,
|
||||
url: '/api/listen/together/sync/playlist/get'
|
||||
},
|
||||
)
|
||||
}
|
||||
|
242
public/listen_together_host.html
Normal file
242
public/listen_together_host.html
Normal file
@ -0,0 +1,242 @@
|
||||
<!-- eslint-disable prettier/prettier -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>一起听 - 主机模式</title>
|
||||
<script src="https://unpkg.com/petite-vue"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/axios@0.26.1/dist/axios.min.js"></script>
|
||||
<link rel="stylesheet" href="https://unpkg.com/mdui@1.0.2/dist/css/mdui.min.css" />
|
||||
<script src="https://unpkg.com/mdui@1.0.2/dist/js/mdui.min.js"></script>
|
||||
</head>
|
||||
|
||||
<body class="mdui-container">
|
||||
<h1>一起听 - 主机模式</h1>
|
||||
<div>消息: {{message}}</div>
|
||||
<audio
|
||||
id="player"
|
||||
autoplay
|
||||
controls>
|
||||
</audio>
|
||||
<br />
|
||||
<br />
|
||||
<button v-if="!account.login" @click="login">获取登录状态</button>
|
||||
<div>您的当前登录账号为: {{account.nickname}}</div>
|
||||
<br />
|
||||
<div v-if="account.login">
|
||||
<button v-if="!roomInfo.roomId" @click="createRoom">创建房间</button>
|
||||
|
||||
<div v-if="roomInfo.roomId">
|
||||
<div>分享链接为:
|
||||
https://st.music.163.com/listen-together/share/?songId=1372188635&roomId={{roomInfo.roomId}}&inviterId={{account.userId}}
|
||||
</div>
|
||||
<br />
|
||||
<button @click="refreshRoom">刷新房间状态</button>
|
||||
<div>在线用户: </div>
|
||||
<ul class="mdui-list">
|
||||
<li v-for="user in roomInfo.roomUsers" class="mdui-list-item mdui-ripple">
|
||||
<div class="mdui-list-item-avatar">
|
||||
<img :src="user.avatarUrl" />
|
||||
</div>
|
||||
<div class="mdui-list-item-content">{{user.nickname}}</div>
|
||||
</li>
|
||||
</ul>
|
||||
<button v-if="roomInfo.roomId" @click="closeRoom">关闭房间</button>
|
||||
</div>
|
||||
</div>
|
||||
<button @click="playTrack">播放</button>
|
||||
<button @click="pauseTrack">暂停</button>
|
||||
<button @click="seekTrack">同步进度</button>
|
||||
<details>
|
||||
<summary>播放列表</summary>
|
||||
<br />
|
||||
<div><span>歌单ID: </span><input v-model="playlistInfo.playlistId" /></div>
|
||||
<button @click="loadPlaylist">加载歌单到播放列表</button>
|
||||
<span>{{playlistInfo.playlistName}}</span>
|
||||
<br />
|
||||
<br />
|
||||
<div>歌单内容: </div>
|
||||
<ul class="mdui-list">
|
||||
<li @click="gotoTrack(track.id)" v-for="track in playlistInfo.playlistTracks"
|
||||
class="mdui-list-item mdui-ripple">
|
||||
<div class="mdui-list-item-avatar">
|
||||
<img :src="track.al.picUrl" />
|
||||
</div>
|
||||
<div class="mdui-list-item-content">{{track.name}}</div>
|
||||
</li>
|
||||
</ul>
|
||||
</details>
|
||||
|
||||
</body>
|
||||
<script>
|
||||
PetiteVue.createApp({
|
||||
message: '请点击获取登录状态',
|
||||
account: {
|
||||
login: false,
|
||||
userId: 0,
|
||||
nickname: '未登录',
|
||||
},
|
||||
roomInfo: {
|
||||
roomId: null,
|
||||
roomUsers: [],
|
||||
},
|
||||
playlistInfo: {
|
||||
playlistId: 0,
|
||||
playlistName: '未获取',
|
||||
playlistTrackIds: [],
|
||||
playlistTracks: [],
|
||||
},
|
||||
playingInfo: {
|
||||
trackId: 0,
|
||||
status: 'PLAY',
|
||||
progress: 1,
|
||||
},
|
||||
clientSeq: 1,
|
||||
login: async function () {
|
||||
const res = await axios({
|
||||
url: `/login/status`,
|
||||
method: 'get',
|
||||
})
|
||||
if (res.data.data.code != 200) {
|
||||
alert('请先使用登录 API 登录到网易云音乐')
|
||||
} else {
|
||||
this.account.userId = res.data.data.profile.userId
|
||||
this.account.nickname = res.data.data.profile.nickname
|
||||
this.account.login = true
|
||||
this.message = '成功登录, 请创建房间'
|
||||
}
|
||||
},
|
||||
createRoom: async function () {
|
||||
const res = await axios({
|
||||
url: 'listentogether/room/create',
|
||||
method: 'get',
|
||||
})
|
||||
console.log(res)
|
||||
if (res.data.code != 200) {
|
||||
this.message = '创建房间出现问题: ' + res.data.message
|
||||
} else {
|
||||
this.message = '创建房间成功: ' + res.data.data.roomInfo.roomId
|
||||
this.roomInfo.roomId = res.data.data.roomInfo.roomId
|
||||
res = await axios({
|
||||
url: 'listentogether/room/check',
|
||||
method: 'post',
|
||||
data: {
|
||||
roomId: this.roomInfo.roomId,
|
||||
},
|
||||
})
|
||||
console.log(res)
|
||||
}
|
||||
},
|
||||
refreshRoom: async function () {
|
||||
const res = await axios({
|
||||
url: '/listentogether/status',
|
||||
})
|
||||
console.log(res)
|
||||
if (res.data.code != 200 || !res.data.data.inRoom) {
|
||||
this.message = '房间状态获取失败, 可能退出了房间'
|
||||
} else {
|
||||
this.roomInfo.roomUsers = res.data.data.roomInfo.roomUsers
|
||||
}
|
||||
},
|
||||
closeRoom: async function () {
|
||||
const res = await axios({
|
||||
url: '/listentogether/end',
|
||||
method: 'post',
|
||||
data: {
|
||||
roomId: this.roomInfo.roomId,
|
||||
},
|
||||
})
|
||||
console.log(res)
|
||||
if (res.data.code != 200 || !res.data.data.success) {
|
||||
this.message = '房间关闭失败'
|
||||
} else {
|
||||
this.message = '房间关闭成功'
|
||||
this.roomInfo.roomId = null
|
||||
}
|
||||
},
|
||||
loadPlaylist: async function () {
|
||||
const res = await axios({
|
||||
url: '/playlist/detail',
|
||||
method: 'post',
|
||||
data: {
|
||||
id: this.playlistInfo.playlistId,
|
||||
},
|
||||
})
|
||||
console.log(res)
|
||||
this.playlistInfo.playlistName = res.data.playlist.name
|
||||
this.playlistInfo.playlistTrackIds = res.data.playlist.trackIds
|
||||
.map((track) => track.id)
|
||||
.join(',')
|
||||
const resa = await axios({
|
||||
url: '/song/detail',
|
||||
method: 'post',
|
||||
data: {
|
||||
ids: this.playlistInfo.playlistTrackIds,
|
||||
},
|
||||
})
|
||||
console.log(resa)
|
||||
this.playlistInfo.playlistTracks = resa.data.songs
|
||||
if (this.roomInfo.roomId) {
|
||||
const resb = await axios({
|
||||
url: 'listentogether/sync/list/command',
|
||||
method: 'post',
|
||||
data: {
|
||||
roomId: this.roomInfo.roomId,
|
||||
commandType: 'REPLACE',
|
||||
userId: this.account.userId,
|
||||
version: this.clientSeq++,
|
||||
playMode: 'ORDER_LOOP',
|
||||
displayList: this.playlistInfo.playlistTrackIds,
|
||||
randomList: this.playlistInfo.playlistTrackIds,
|
||||
},
|
||||
})
|
||||
console.log(resb)
|
||||
}
|
||||
},
|
||||
gotoTrack: async function (trackId) {
|
||||
this.playingInfo.trackId = trackId
|
||||
if (this.roomInfo.roomId) {
|
||||
await this.playCommand('GOTO')
|
||||
}
|
||||
document.getElementById('player').src =
|
||||
'https://music.163.com/song/media/outer/url?id=' + trackId + '.mp3'
|
||||
},
|
||||
playTrack: async function () {
|
||||
this.playingInfo.status = 'PLAY'
|
||||
await this.playCommand('PLAY')
|
||||
document.getElementById('player').play()
|
||||
},
|
||||
pauseTrack: async function () {
|
||||
this.playingInfo.status = 'PAUSE'
|
||||
await this.playCommand('PAUSE')
|
||||
document.getElementById('player').pause()
|
||||
},
|
||||
seekTrack: async function () {
|
||||
this.playingInfo.status = 'PLAY'
|
||||
await this.playCommand('seek')
|
||||
document.getElementById('player').play()
|
||||
},
|
||||
playCommand: async function (action) {
|
||||
const res = await axios({
|
||||
url: 'listentogether/play/command',
|
||||
method: 'post',
|
||||
data: {
|
||||
roomId: this.roomInfo.roomId,
|
||||
progress: Math.floor(
|
||||
document.getElementById('player').currentTime * 1000,
|
||||
),
|
||||
commandType: action,
|
||||
formerSongId: '-1',
|
||||
targetSongId: this.playingInfo.trackId,
|
||||
clientSeq: this.clientSeq++,
|
||||
playStatus: this.playingInfo.status,
|
||||
},
|
||||
})
|
||||
console.log(res)
|
||||
},
|
||||
}).mount()
|
||||
</script>
|
||||
|
||||
</html>
|
Loading…
x
Reference in New Issue
Block a user