0%

MusicFree+loolob搭建自己的音乐应用(二)

扩展歌单功能

查看MusicFree的源码,和其中的plugin.d.ts文件,提取几个关节接口

接口分析

getRecommendSheetTags

1
2
3
4
5
6
7
8
/** 获取热门歌单tag */
getRecommendSheetTags?: () => Promise<IGetRecommendSheetTagsResult>;

interface IGetRecommendSheetTagsResult {
// 固定的tag
pinned?: IMusic.IMusicSheetItemBase[];
data?: IMusic.IMusicSheetGroupItem[];
}

调用逻辑:
这个接口在app打开热门歌单时启用

返回值说明:

  • pinned字段返回固定的标签。这些标签名将直接显示在热门歌单这个界面上。
  • data字段返回分组的普通标签

getRecommendSheetsByTag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/** 歌单列表 */
getRecommendSheetsByTag?: (
tag: ICommon.IUnique,
page?: number,
) => Promise<ICommon.PaginationResponse<IMusic.IMusicSheetItemBase>>;
interface IMusicSheetItemBase {
/** 封面图 */
coverImg?: string;
artwork?: string;
/** 标题 */
title?: string;
/** 作者 */
artist?: string;
/** 歌单id */
id: string;
/** 描述 */
description?: string;
/** 作品总数 */
worksNum?: number;
platform?: string;
[k: string]: any;
}

调用逻辑:

  1. 这个接口在点击热门歌单中的标签时调用,返回包含标签的歌单
  2. 这个接口在点击热门歌单界面后,立即被调用一次。用于获取默认标签的歌单

返回值说明:

  • title 歌单名
  • artist 歌单作者
  • 歌单id

getMusicSheetInfo

1
2
3
4
5
6
7
8
9
/** 获取歌单信息,有分页 */
getMusicSheetInfo?: (
sheetItem: IMusic.IMusicSheetItem,
page: number,
) => Promise<ISheetInfoResult | null>;
/** 歌单项 */
export interface IMusicSheetItem extends IMusicSheetItemBase {
musicList: Array<IMusic.IMusicItem>;
}

调用逻辑:
点击歌单封面时调用,用于获取歌单内的歌曲

返回值说明:

  • musicList 歌单内的歌曲列表,将由getMediaSource接口来获取歌曲内容

插件实现

  1. getRecommendSheetTags,插件直接发起请求,然后返回数据即可。逻辑可交由服务器实现

    1
    await axios.get(`${URL}getrecommendsheettags`)
  2. getRecommendSheetsByTag,同上直接发起请求。逻辑交由服务器实现

    1
    2
    3
    4
    5
    const body = {
    tag,
    page,
    }
    const result = await axios.post(`${URL}getrecommendsheetsbytag`, body)
  3. getMusicSheetInfo,同上直接发起请求。逻辑交由服务器实现

    1
    2
    3
    4
    5
    const body = {
    sheetItem,
    page,
    }
    const result = await axios.post(`${URL}getmusicsheetinfo`, body)

服务器实现

1. getRecommendSheetTags

简单实现,直接返回三个固定即可

1
2
3
4
5
6
7
return {
pinned = {
{ title = "歌手", artist = "歌手", id = "歌手" },
{ title = "翻唱", artist = "翻唱", id = "翻唱" },
{ title = "我喜欢", artist = "我喜欢", id = "我喜欢" }
},
}

2. getRecommendSheetTags

根据标签获取歌单

提前将本地做分类处理

  1. 全部歌曲加入我喜欢歌单。收到我喜欢标签时,返回我喜欢歌单
  2. 按将歌曲按歌手名分组,加入对应歌手歌单。收到歌手标签时,返回所有歌手的歌单
  3. 将同名歌曲按名字分组,加入对应歌名的歌单。收到翻唱标签时,返回所有翻唱歌曲的歌单
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
-- 按歌手分组
function Sheet:InitArtist(MusicList)
self.Artist = {}
for _, item in pairs(MusicList) do
if self.Artist[item.Artist] == nil then
self.Artist[item.Artist] = {}
end
local list = self.Artist[item.Artist]
list[#list + 1] = item
end
local temp = {}
for k, v in pairs(self.Artist) do
if #v <= 1 then
temp[#temp + 1] = v[1]
self.Artist[k] = nil
end
end
for k, v in pairs(self.Artist) do
for i = #temp, 1, -1 do
local item = temp[i]
if (string.includes(item.Artist, k) or string.includes(k, item.Artist)) then
v[#v + 1] = item
table.remove(temp, i)
end
end
end
end
-- 按歌曲名分组
function Sheet:InitTitle(MusicList)
self.Title = {}
for _, item in pairs(MusicList) do
if self.Title[item.Title] == nil then
self.Title[item.Title] = {}
end
local list = self.Title[item.Title]
list[#list + 1] = item
end
for k, v in pairs(self.Title) do
if #v <= 1 then
self.Title[k] = nil
end
end
end

然后根据请求的标签,返回对应的歌单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
function Sheet:getRecommendSheetsByTag(tag, page, PageCount)
local list = nil
if tag.id == "我喜欢" or tag.title == "默认" then
list = { {
title = "我喜欢",
artist = "我喜欢",
id = "我喜欢",
} }
elseif tag.title == "歌手" then
list = array.map(self.Artist, function(v, k)
return {
title = k,
artist = k,
id = k,
}
end)
elseif tag.title == "翻唱" then
list = array.map(self.Title, function(v, k)
return {
title = k,
artist = k,
id = k,
}
end)
end
if list == nil then
return { isEnd = true, data = {} }
end

local start_idx = 1 + math.clamp((page - 1) * PageCount, 0, #list)
local end_idx = 1 + math.clamp(page * PageCount, 0, #list)

return { isEnd = page * PageCount >= #list, data = array.slice(list, start_idx, end_idx) }
end

3. getMusicSheetInfo

根据歌单id,返回歌单内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
function Sheet:getMusicSheetInfo(sheetItem, page, PageCount)
local list = nil
if sheetItem.id == "我喜欢" then
list = self.MusicList
elseif self.Artist[sheetItem.id] ~= nil then
list = self.Artist[sheetItem.id]
elseif self.Title[sheetItem.id] ~= nil then
list = self.Title[sheetItem.id]
end
if list == nil then
return { isEnd = true, musicList = {} }
end

local start_idx = 1 + math.clamp((page - 1) * PageCount, 0, #list)
local end_idx = 1 + math.clamp(page * PageCount, 0, #list)

return {
isEnd = page * PageCount >= #list,
musicList = array.map(array.slice(list, start_idx, end_idx), function(v, k)
return {
title = v.Title,
artist = v.Artist,
duration = v.Duration,
id = v.MD5,
size = v.Size,
}
end)
}
end

开始使用

  1. 编译插件并拷贝进手机,然后通过APP安装

    1
    npm run build
  2. 然后点击热门歌单,选中并播放,大功告成