### Example Implementation of getAlbumInfo Source: https://musicfree.catcat.work/plugin/protocol.html Provides an example implementation for the getAlbumInfo function, handling the first page differently. ```javascript module.exports = { // ... async getAlbumInfo(albumItem, page) { if (page <= 1) { return { isEnd: false, musicList: [], albumItem: { description: "这是专辑的补充说明", }, }; } // 其他页码正常返回 return { isEnd: true, musicList: [], }; }, }; ``` ```javascript module.exports = { // ... async getAlbumInfo(albumItem, page) { if (page <= 1) { return { isEnd: false, musicList: [], albumItem: { description: "这是专辑的补充说明", }, }; } // 其他页码正常返回 return { isEnd: true, musicList: [], }; }, }; ``` -------------------------------- ### Example Implementation of getMusicSheetInfo Source: https://musicfree.catcat.work/plugin/protocol.html Provides an example implementation for the getMusicSheetInfo function, handling the first page differently. ```javascript module.exports = { // ... async getMusicSheetInfo(sheetItem, page) { if (page <= 1) { return { isEnd: false, musicList: [], albumItem: { description: "这是专辑的补充说明", }, }; } // 其他页码正常返回 return { isEnd: true, musicList: [], }; }, }; ``` ```javascript module.exports = { // ... async getMusicSheetInfo(sheetItem, page) { if (page <= 1) { return { isEnd: false, musicList: [], albumItem: { description: "这是专辑的补充说明", }, }; } // 其他页码正常返回 return { isEnd: true, musicList: [], }; }, }; ``` -------------------------------- ### getMusicInfo Example Source: https://musicfree.catcat.work/plugin/protocol.html Example implementation of the getMusicInfo function to supplement music details, such as artwork. ```javascript module.exports = { // 其他属性或方法... async getMusicInfo(musicItem) { // 根据音乐获取音乐详细信息 return { artwork: "https://example.catcat.work/coverimage.png", }; }, }; ``` -------------------------------- ### Example Implementation of getArtistWorks Source: https://musicfree.catcat.work/plugin/protocol.html Provides an example implementation for getArtistWorks, demonstrating how to fetch either music or albums by an artist. ```javascript module.exports = { // ... async getArtistWorks(artistItem, page, type) { // 获取作者的音乐 if (type === "music") { return { isEnd: true, data: [], }; } // 获取作者的专辑 if (type === "album") { return { isEnd: false, data: [], }; } }, }; ``` ```javascript module.exports = { // ... async getArtistWorks(artistItem, page, type) { // 获取作者的音乐 if (type === "music") { return { isEnd: true, data: [], }; } // 获取作者的专辑 if (type === "album") { return { isEnd: false, data: [], }; } }, }; ``` -------------------------------- ### Search Function Implementation Example Source: https://musicfree.catcat.work/plugin/protocol.html Provides a practical example of how to implement the `search` function, handling different media types and returning structured search results. This demonstrates conditional logic based on the `type` parameter. ```javascript module.exports = { // 搜索 async search(query, page, type) { // 搜索音乐 if (type === "music") { return { isEnd: true, data: [], // MusicItem 类型的数组 }; } // 搜索专辑 else if (type === "album") { return { isEnd: true, data: [], // AlbumItem 类型的数组 }; } // 搜索歌单 else if (type === "sheet") { return { isEnd: true, data: [], // MusicSheetItem 类型的数组 }; } // 搜索作者 else if (type === "artist") { return { isEnd: true, data: [], // ArtistItem 类型的数组 }; } // 搜索歌词 else if (type === "lyric") { return { isEnd: true, data: [], // MusicItem 类型的数组 }; } }, }; ``` ```javascript module.exports = { // 搜索 async search(query, page, type) { // 搜索音乐 if (type === "music") { return { isEnd: true, data: [], // MusicItem 类型的数组 }; } // 搜索专辑 else if (type === "album") { return { isEnd: true, data: [], // AlbumItem 类型的数组 }; } // 搜索歌单 else if (type === "sheet") { return { isEnd: true, data: [], // MusicSheetItem 类型的数组 }; } // 搜索作者 else if (type === "artist") { return { isEnd: true, data: [], // ArtistItem 类型的数组 }; } // 搜索歌词 else if (type === "lyric") { return { isEnd: true, data: [], // MusicItem 类型的数组 }; } }, }; ``` -------------------------------- ### getLyric Example Source: https://musicfree.catcat.work/plugin/protocol.html Example implementation of the getLyric function to fetch lyrics and their translations. ```javascript module.exports = { // ... async getLyric(musicItem) { return { rawLrc: "[00:00.00] First Lyric", // 文本格式的歌词 translation: "[00:00.00] 第一句歌词", // 文本格式的歌词 }; }, }; ``` -------------------------------- ### JavaScript Example for getTopListDetail Source: https://musicfree.catcat.work/plugin/protocol.html An example implementation of the getTopListDetail function in JavaScript, returning a placeholder music list. ```javascript module.exports = { // ... async getTopListDetail(topListItem) { // 获取榜单详情 return { musicList: [], }; }, }; ``` -------------------------------- ### Example Implementation of getRecommendSheetTags Source: https://musicfree.catcat.work/plugin/protocol.html Provides an example implementation for fetching recommended sheet tags. This function returns a Promise resolving to an object containing pinned tags and categorized tag groups. ```javascript module.exports = { // ... async getRecommendSheetTags() { // 获取推荐歌单 tag return { pinned: [ { id: "1", title: "纯音乐", }, ], data: [ { title: "年代", data: [ { id: "101", title: "80后", }, { id: "102", title: "90后", }, ], }, ], }; }, }; ``` ```javascript module.exports = { // ... async getRecommendSheetTags() { // 获取推荐歌单 tag return { pinned: [ { id: "1", title: "纯音乐", }, ], data: [ { title: "年代", data: [ { id: "101", title: "80后", }, { id: "102", title: "90后", }, ], }, ], }; }, }; ``` -------------------------------- ### getMediaSource Example Source: https://musicfree.catcat.work/plugin/protocol.html Example implementation of the getMediaSource function to fetch the actual media URL based on media item and quality. ```javascript const axios = require("axios"); // 获取音源 module.exports = { async getMediaSource(mediaItem, quality) { // 根据媒体对象获取源信息 const fakeResult = ( await axios.get("https://example.catcat.work/getMediaUrl", { params: { id: mediaItem.id, quality: quality, }, }) ).data; // 转化为插件可识别的返回值 return { url: fakeResult.sourceUrl, }; }, }; ``` -------------------------------- ### JavaScript Example for getRecommendSheetsByTag Source: https://musicfree.catcat.work/plugin/protocol.html An example implementation of the getRecommendSheetsByTag function, returning a placeholder music sheet list. ```javascript module.exports = { // ... async getRecommendSheetsByTag(tagItem) { // 获取某个 tag 下的所有歌单 return { isEnd: false, data: [ { title: "歌单1", id: "xxxx", artwork: "xxx", playCount: 122220, }, ], }; }, }; ``` -------------------------------- ### JavaScript Example for getRecommendSheetTags Source: https://musicfree.catcat.work/plugin/protocol.html An example implementation of the getRecommendSheetTags function, returning sample pinned and grouped tags. ```javascript module.exports = { // ... async getRecommendSheetTags() { // 获取推荐歌单 tag return { pinned: [ { id: "1", title: "纯音乐", }, ], data: [ { title: "年代", data: [ { id: "101", title: "80后", }, { id: "102", title: "90后", }, ], }, ], }; }, }; ``` -------------------------------- ### Example Implementation of getMusicComments Source: https://musicfree.catcat.work/plugin/protocol.html Provides an example implementation for fetching comments for a given music item. The function returns a Promise with an 'isEnd' flag and an array of comment objects. ```javascript module.exports = { // ... async getMusicComments(musicItem) { // 获取某个歌曲的所有评论 return { isEnd: false, data: [ { id: "评论1", nickName: "https://xxx.jpg", comment: "这是一条评论" }, ], }; }, }; ``` ```javascript module.exports = { // ... async getMusicComments(musicItem) { // 获取某个歌曲的所有评论 return { isEnd: false, data: [ { id: "评论1", nickName: "https://xxx.jpg", comment: "这是一条评论" }, ], }; }, }; ``` -------------------------------- ### Full Plugin Structure Example Source: https://musicfree.catcat.work/plugin/protocol.html This snippet shows the complete structure of a MusicFree plugin, including all required and optional fields and methods. ```javascript module.exports = { // 插件名称 platform: "某插件", // 插件作者 author: "插件作者", // 插件版本号 version: "0.0.0", // 插件更新地址 srcUrl: "https://example.catcat.work/xxx.js", // 主键 primaryKey: ["id", "aid", "bid"], // 缓存策略 cacheControl: "no-cache", // 提示文案 hints: { importMusicItem: [ "1. 导入单曲时注意,输入的 URL 应该符合 xxx 格式", "2. 导入单曲的第二条注意事项", ], importMusicSheet: [ "1. 导入歌单时注意,输入的 URL 应该符合 xxx 格式", "2. 导入歌单的第二条注意事项", ], }, // 搜索 async search(query, page, type) { // 搜索的具体逻辑 }, // 获取音乐的真实 url async getMediaSource(mediaItem, quality) { // ... }, // 获取音乐详情 async getMusicInfo(musicItem) { // ... }, // 获取歌词 async getLyric(musicItem) { // ... }, // 获取专辑详情 async getAlbumInfo(albumItem, page) { // ... }, // 获取歌单详情 async getMusicSheetInfo(sheetItem, page) { // ... }, // 获取作者作品 async getArtistWorks(artistItem, page, type) { // ... }, // 导入单曲 async importMusicItem(urlLike) { // ... }, // 导入歌单 async importMusicSheet(urlLike) { // ... }, // 获取榜单列表 async getTopLists() { // ... }, // 获取榜单详情 async getTopListDetail(topListItem, page) { // ... }, // 获取推荐歌单 tag async getRecommendSheetTags() { // ... }, // 获取某个 tag 下的所有歌单 async getRecommendSheetsByTag(tag, page) { // ... }, // 获取某个音乐的评论 async getMusicComments(musicItem) { // ... } }; ``` -------------------------------- ### Plugin Name (platform) Example Source: https://musicfree.catcat.work/plugin/protocol.html Defines the name of the plugin. The name '本地' will cause the plugin to be disabled. ```javascript module.exports = { // 插件名 platform: "某插件", // ... 其他字段 }; ``` -------------------------------- ### App Version Compatibility (appVersion) Example Source: https://musicfree.catcat.work/plugin/protocol.html Specifies compatibility with Android app versions using semver format. Defaults to '>0.0.0'. If the app version doesn't meet the constraint, the plugin will be unusable. ```javascript module.exports = { // 匹配的安卓版 APP 版本号 appVersion: ">0.0.0", // ...其他字段 }; ``` -------------------------------- ### Plugin Author (author) Example Source: https://musicfree.catcat.work/plugin/protocol.html Specifies the author of the plugin. This field is optional and used for display purposes only. ```javascript module.exports = { // 插件作者 author: "某位大佬", // ...其他字段 }; ``` -------------------------------- ### Plugin Version (version) Example Source: https://musicfree.catcat.work/plugin/protocol.html Sets the plugin's version number, defaulting to '0.0.0'. This field must follow the semver format and is used for automatic updates. ```javascript module.exports = { // 插件版本号 version: "0.0.0", // ...其他字段 }; ``` -------------------------------- ### Get Artist Works Interface Source: https://musicfree.catcat.work/plugin/protocol.html Defines the types for artist media and the signature for the getArtistWorks function. ```typescript type ArtistMediaType = 'music' | 'album'; type getArtistWorks = ( artistItem: ArtistItem, page: number, type: T, ) => Promise>; ``` ```typescript type ArtistMediaType = 'music' | 'album'; type getArtistWorks = ( artistItem: ArtistItem, page: number, type: T, ) => Promise>; ``` -------------------------------- ### Get Album Info Interface Source: https://musicfree.catcat.work/plugin/protocol.html Defines the interface for the result of getAlbumInfo and the function signature. ```typescript interface IGetAlbumInfoResult = { isEnd?: boolean; musicList: IMusicItem[], albumItem?: Partial } type getAlbumInfo = (albumItem: IAlbumItem, page: number) => Promise; ``` ```typescript interface IGetAlbumInfoResult = { isEnd?: boolean; musicList: IMusicItem[], albumItem?: Partial } type getAlbumInfo = (albumItem: IAlbumItem, page: number) => Promise; ``` -------------------------------- ### Plugin Update URL (srcUrl) Example Source: https://musicfree.catcat.work/plugin/protocol.html Provides the direct URL to the plugin's JavaScript file for updates. If present, an 'Update Plugin' button will appear in the app. ```javascript module.exports = { // 插件更新地址 srcUrl: "https://gitee.com/maotoumao/MusicFreePlugins/raw/v0.1/dist/xxx/index.js", // ...其他字段 }; ``` -------------------------------- ### Get Music Sheet Info Interface Source: https://musicfree.catcat.work/plugin/protocol.html Defines the interface for the result of getMusicSheetInfo and the function signature. ```typescript interface IGetSheetInfoResult = { isEnd?: boolean; musicList: IMusicItem[], sheetItem?: Partial } type getMusicSheetInfo = (sheetItem: MusicSheetItem, page: number) => Promise; ``` ```typescript interface IGetSheetInfoResult = { isEnd?: boolean; musicList: IMusicItem[], sheetItem?: Partial } type getMusicSheetInfo = (sheetItem: MusicSheetItem, page: number) => Promise; ``` -------------------------------- ### getRecommendSheetsByTag Source: https://musicfree.catcat.work/plugin/protocol.html Retrieves a list of all music playlists under a specific tag. This method is called when a user clicks on a tag. When a specific playlist is clicked, it navigates to the playlist's detail page and calls `getMusicSheetInfo` to get its information. ```APIDOC ## getRecommendSheetsByTag ### Description Retrieves a list of all music playlists under a specific tag. This method is called when a user clicks on a tag. When a specific playlist is clicked, it navigates to the playlist's detail page and calls `getMusicSheetInfo` to get its information. ### Function Signature ```typescript type getRecommendSheetsByTag = ( tag: ITag, page?: number ) => Promise<{ isEnd: boolean; data: Array; }>; ``` ### Parameters #### Path Parameters - **tag** (ITag) - Required - A specific tag. - **page** (number) - Optional - The page number, starting from 1. **Warning**: The app has a default tag with an empty string ID (this logic might change later). ### Returns Returns a `Promise` object with the following key-value types: - **isEnd** (boolean) - Whether the end of the list has been reached, defaults to `true`. - **data** (IMusicSheetItem[]) - The list of music playlists. ### Example ```javascript module.exports = { // ... async getRecommendSheetsByTag(tagItem) { // Get all playlists under a specific tag return { isEnd: false, data: [ { title: "Playlist 1", id: "xxxx", artwork: "xxx", playCount: 122220, }, ], }; }, }; ``` ``` -------------------------------- ### getLyric Source: https://musicfree.catcat.work/plugin/protocol.html Retrieves the lyrics for a music item. This function is called when switching songs or when searching for lyrics to get the specific lyric content. ```APIDOC ## getLyric ### Description Retrieves the lyrics for a music item. This function is called when switching songs or when searching for lyrics to get the specific lyric content. ### Function Signature ```typescript interface ILyricSource { rawLrc?: string; // Text format lyrics translation?: string; // Text format translation } // Get lyrics function signature type getLyric = (musicItem: IMusicItem) => Promise; ``` ### Parameters #### Parameters - **musicItem** (`IMusicItem`) - Required - The music item for which to get detailed information. ### Return Value Returns a `Promise` object containing: - **rawLrc** (`string`) - Optional - Text format lyrics with timestamps, e.g., `[00:00.00] First Lyric`. - **translation** (`string`) - Optional - Text format translation with timestamps, e.g., `[00:00.00] First Lyric Translation`. ### Example ```javascript module.exports = { // ... async getLyric(musicItem) { return { rawLrc: "[00:00.00] First Lyric", // Text format lyrics translation: "[00:00.00] First Lyric Translation", // Text format lyrics }; }, }; ``` ``` -------------------------------- ### 构建插件 Source: https://musicfree.catcat.work/plugin/introduction.html 使用npm执行构建命令来打包插件。生成的文件通常位于dist/plugin.js。 ```bash npm run build ``` -------------------------------- ### 简单的插件结构示例 Source: https://musicfree.catcat.work/plugin/introduction.html 展示了一个基本的插件结构,包含插件信息属性(如platform, version)和供软件调用的函数(如getMediaSource)。 ```javascript module.exports = { /** 用来说明插件信息的属性 */ platform: "MusicFree 插件", // 插件名 version: "0.0.0", // 插件版本号 /** 供给软件在合适的时机调用的函数 */ getMediaSource: function (musicItem) { // 根据该音源的某个音乐获取真实的播放地址 return { url: "https://", // 音源 URL }; }, }; ``` -------------------------------- ### Implement Search Functionality Source: https://musicfree.catcat.work/plugin/how-to-develop.html This function fetches HTML content from a given URL using axios. It's the initial step in implementing search functionality for a plugin. ```javascript const axios = require("axios"); module.exports = { platform: "FreeSound", // 插件名 version: "0.0.0", // 版本号 cacheControl: "no-store", // 我们可以直接解析出musicItem的结构,因此选取no-store就好了,当然也可以不写这个字段 async search(query, page, type) { if (type === "music") { // 我们能搜索的只有音乐,因此判断下类型 // 获取网站的html const rawHtml = ( await axios.get("https://freesound.org/search", { q: query, page, }) ).data; // TODO: 接下来解析html } }, }; ``` -------------------------------- ### Parse HTML for Music Items Source: https://musicfree.catcat.work/plugin/how-to-develop.html This code snippet demonstrates how to parse fetched HTML content using cheerio to extract music item details like ID, title, artist, artwork, and URL. It assumes the HTML structure is known and uses jQuery-like selectors. ```javascript const axios = require("axios"); const cheerio = require('cheerio'); module.exports = { platform: "FreeSound", // 插件名 version: "0.0.0", // 版本号 cacheControl: "no-store", // 我们可以直接解析出musicItem的结构,因此选取no-store就好了,当然也可以不写这个字段 async search(query, page, type) { if (type === "music") { // 我们能搜索的只有音乐,因此判断下类型 // 获取网站的html const rawHtml = ( await axios.get("https://freesound.org/search", { q: query, page, }) ).data; // 接下来解析html const $ = cheerio.load(rawHtml); // 存储搜索结果 const searchResults = []; // 获取所有的结果 const resultElements = $('.bw-search__result'); // 解析每一个结果 resultElements.each((index, element) => { const playerElement = $(element).find('.bw-player'); // id const id = playerElement.data('sound-id'); // 音频名 const title = playerElement.data('title'); // 作者 const artist = $(element).find('.col-12.col-lg-12.middle a').text(); // 专辑封面 const artwork = playerElement.data('waveform'); // 音源 const url = playerElement.data('mp3'); // 专辑名,这里就随便写个了,不写也没事 const album = '来自FreeSound的音频'; searchResults.push({ // 一定要有一个 id 字段 id, title, artist, artwork, album, url }) }); return { isEnd: true, data: searchResults } } }, }; ``` -------------------------------- ### getRecommendSheetTags Source: https://musicfree.catcat.work/plugin/protocol.html Fetches tag categories for recommended music playlists. This function is called when a user enters the recommended playlist page and clicks on a corresponding plugin. ```APIDOC ## getRecommendSheetTags ### Description Fetches tag categories for recommended music playlists. This function is called when a user enters the recommended playlist page and clicks on a corresponding plugin. ### Function Signature ```typescript type getRecommendSheetTags = () => Promise; ``` ### Parameters This function takes no parameters. ### Returns Returns a `Promise` object with the following key-value types: - **pinned** (ITag[]) - Tags fixed at the top. Each `tag` includes at least `id` and `title` fields. - **data** (ITagGroup[]) - An array of tag groups. Each group can optionally include a title `title`, and all tags of type `ITag` within that group. ### Example ```javascript module.exports = { // ... async getRecommendSheetTags() { // Get recommended sheet tags return { pinned: [ { id: "1", title: "Pure Music", }, ], data: [ { title: "Era", data: [ { id: "101", title: "80s", }, { id: "102", title: "90s", }, ], }, ], }; }, }; ``` ``` -------------------------------- ### getAlbumInfo Source: https://musicfree.catcat.work/plugin/protocol.html Retrieves detailed information about an album, including its music list and supplementary album details. This function is called when a user navigates to an album's detail page. ```APIDOC ## getAlbumInfo ### Description Retrieves detailed information about an album, including its music list and supplementary album details. This function is called when a user navigates to an album's detail page to complete missing properties in `albumItem` and fetch the music list under the album. ### Function Signature ```typescript interface IGetAlbumInfoResult = { isEnd?: boolean; musicList: IMusicItem[]; albumItem?: Partial; } type getAlbumInfo = (albumItem: IAlbumItem, page: number) => Promise; ``` ### Parameters #### Parameters - **albumItem** (`IAlbumItem`) - Required - The album for which to retrieve detailed information. - **page** (`number`) - Required - The page number, starting from 1. ### Return Value A `Promise` object containing the following key-value types: - **isEnd** (`boolean`) - Indicates if the end of the songs in the album has been reached; defaults to `true`. - **musicList** (`IMusicItem[]`) - The list of songs within the album. - **albumItem** (`Partial`) - Partial or full fields of the album, used to supplement other information within the album, such as the introduction. This field is optionally returned only when `page <= 1`; it is not necessary to return this field in other cases. ### Example ```javascript module.exports = { // ... async getAlbumInfo(albumItem, page) { if (page <= 1) { return { isEnd: false, musicList: [], albumItem: { description: "这是专辑的补充说明", }, }; } // Other page numbers return normally return { isEnd: true, musicList: [], }; }, }; ``` ``` -------------------------------- ### getMusicInfo Source: https://musicfree.catcat.work/plugin/protocol.html Retrieves detailed information about a music item. This function is called when a user plays a song and is used to supplement incomplete music details, such as adding an album cover. ```APIDOC ## getMusicInfo ### Description Retrieves detailed information about a music item. This function is called when a user plays a song and is used to supplement incomplete music details, such as adding an album cover. ### Function Signature ```typescript // Get music details function signature type getMusicInfo = ( musicBase: MediaBase ) => Promise | null>; ``` ### Parameters #### Parameters - **musicItem** (`IMusicItem`) - Required - The music item for which to get detailed information. ### Return Value Returns a `Promise>` object, which contains partial or full properties of the music item. ### Example ```javascript module.exports = { // Other properties or methods... async getMusicInfo(musicItem) { // Get music details based on the music item return { artwork: "https://example.catcat.work/coverimage.png", }; }, }; ``` ``` -------------------------------- ### TypeScript Interfaces for Recommendation Tags Source: https://musicfree.catcat.work/plugin/protocol.html Defines the interfaces for tags and tag groups used in fetching recommendation tag classifications. ```typescript interface ITag { // tag 的唯一标识 id: string; // tag 标题 title: string; } interface ITagGroup { // 分组标题 title: string; // tag 列表 data: ITag[]; } interface IGetRecommendSheetTagsResult { // 固定的tag pinned?: ITag[]; // 更多面板中的tag data?: ITagGroup[]; } type getRecommendSheetTags = () => Promise; ``` -------------------------------- ### getMediaSource Source: https://musicfree.catcat.work/plugin/protocol.html Retrieves the actual URL for a music item. This function is called when a user plays or downloads a song within the app. It supports different audio qualities and handles cases where the requested quality is unavailable by attempting a different quality. ```APIDOC ## getMediaSource ### Description Retrieves the actual URL for a music item. This function is called when a user plays or downloads a song within the app. It supports different audio qualities and handles cases where the requested quality is unavailable by attempting a different quality. ### Function Signature ```typescript type getMediaSource = ( mediaItem: IMusicItem, quality?: "low" | "standard" | "high" | "super" ) => Promise; ``` ### Parameters #### Parameters - **mediaItem** (`IMusicItem`) - Required - The media object for which to get the source. - **quality** (`"low" | "standard" | "high" | "super"`) - Optional - The audio quality. Possible values are "low", "standard", "high", "super". Defaults to "standard". ### Return Value Returns a `Promise` object containing: - **url** (`string`) - The actual URL of the media object. - **headers** (`Record`) - Optional - Additional headers required for requesting the actual URL. - **userAgent** (`string`) - Optional - The user agent required for requesting the actual URL. If headers are provided, it's recommended to include userAgent within headers. ### Example ```javascript const axios = require("axios"); // Get media source module.exports = { async getMediaSource(mediaItem, quality) { // Get source information based on the media object const fakeResult = ( await axios.get("https://example.catcat.work/getMediaUrl", { params: { id: mediaItem.id, quality: quality, }, }) ).data; // Convert to plugin-recognizable return value return { url: fakeResult.sourceUrl, }; }, }; ``` ``` -------------------------------- ### IMediaSourceResult Interface and getMediaSource Signature Source: https://musicfree.catcat.work/plugin/protocol.html Defines the structure for media source results and the function signature for retrieving media sources. ```typescript interface IMediaSourceResult { /** 请求URL所需要的headers */ headers?: Record; /** 请求URL所需要的user-agent */ userAgent?: string; /** 音源 */ url: string; } // 获取媒体源函数签名 type getMediaSource = ( mediaItem: IMusicItem, quality?: "low" | "standard" | "high" | "super" ) => Promise; ``` -------------------------------- ### Interface Definition for getMusicComments Source: https://musicfree.catcat.work/plugin/protocol.html Defines the function signature for retrieving comments for a specific music item. It expects a musicItem and returns a Promise with pagination information and a list of comments. ```typescript // 获取某个 tag 下的所有歌单 type getMusicComments = ( musicItem: IMusicItem ) => Promise<{ isEnd: boolean; data: Array; }>; ``` ```typescript // 获取某个 tag 下的所有歌单 type getMusicComments = ( musicItem: IMusicItem ) => Promise<{ isEnd: boolean; data: Array; }>; ``` -------------------------------- ### TypeScript Interface for Top List Detail Result Source: https://musicfree.catcat.work/plugin/protocol.html Defines the structure of the result when fetching top list details, including pagination and music list items. ```typescript interface ITopListInfoResult { isEnd?: boolean; topListItem?: IMusic.IMusicSheetItem; musicList?: IMusic.IMusicItem[]; } // 获取榜单详情 type getTopListDetail = ( topListItem: IMusicSheetItem ) => Promise; ``` -------------------------------- ### Async Arrow Function Syntax Source: https://musicfree.catcat.work/plugin/caution.html Avoid using async arrow functions in this format for Android compatibility. Use standard async functions instead. ```javascript const f = async () => { } ``` -------------------------------- ### getRecommendSheetTags Source: https://musicfree.catcat.work/plugin/protocol.html Retrieves tag classifications for popular playlists. This function is called when a user enters the recommended playlist page and clicks on a corresponding plugin. It returns a list of tags, optionally categorized into groups. ```APIDOC ## getRecommendSheetTags ### Description Retrieves tag classifications for popular playlists. This function is called when a user enters the recommended playlist page and clicks on a corresponding plugin. It returns a list of tags, optionally categorized into groups. ### Method N/A (Function Call) ### Endpoint N/A ### Parameters No input parameters. ### Response #### Success Response - **pinned** (ITag[]) - Optional - Fixed tags at the top. Each tag includes at least `id` and `title`. - **data** (ITagGroup[]) - Optional - Tag group array. Each group can optionally include a `title` and a list of `ITag` objects. ### Request Example ```javascript { // ... async getRecommendSheetTags() { // 获取推荐歌单 tag return { pinned: [ { id: "1", title: "纯音乐", }, ], data: [ { title: "年代", data: [ { id: "101", title: "80后", }, { id: "102", title: "90后", }, ], }, ], }; }, } ``` ``` -------------------------------- ### getMusicInfo Signature Source: https://musicfree.catcat.work/plugin/protocol.html Defines the function signature for retrieving detailed music information. ```typescript // 获取音乐详情函数签名 type getMusicInfo = ( musicBase: MediaBase ) => Promise | null>; ``` -------------------------------- ### TypeScript Signature for getRecommendSheetsByTag Source: https://musicfree.catcat.work/plugin/protocol.html Defines the function signature for fetching music sheets by a given tag, including pagination. ```typescript // 获取某个 tag 下的所有歌单 type getRecommendSheetsByTag = ( tag: ITag, page?: number ) => Promise<{ isEnd: boolean; data: Array; }>; ``` -------------------------------- ### search Function Source: https://musicfree.catcat.work/plugin/protocol.html The search function allows users to query for various media types like music, albums, artists, sheets, and lyrics. It handles pagination and returns search results. ```APIDOC ## search Function ### Description This function is used to search for media content. It is invoked when a user initiates a search, pulls to refresh, or reaches the bottom of the search results in the app. If the `search` function is missing, this plugin will not appear in the software's search results page. If `supportedSearchType` is defined, the `search` function will only process types listed in `supportedSearchType`. ### Method ```javascript type search = ( query: string, page: number, type: T, ) => Promise> ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **query** (`string`) - Required - The search keyword. - **page** (`number`) - Required - The page number, starting from 1. - **type** (`"music" | "album" | "artist" | "sheet" | "lyric"`) - Required - The type of media to search for. The values correspond to: music, album, artist, sheet, lyric. ### Response #### Success Response - **isEnd** (`boolean`) - Optional - Indicates if the search has reached the last page. Defaults to true if not provided. - **data** (`SupportMediaItem[T][]`) - Required - An array of media items. The type of elements in the array depends on the `type` parameter provided in the request. Each element in the `data` array will automatically have a `platform` property added, which will be the plugin name, overriding any existing `platform` value. ### Request Example ```typescript // Example for searching music module.exports = { async search(query, page, type) { if (type === "music") { return { isEnd: true, data: [], // Array of IMusicItem }; } // ... other types }, }; ``` ### Response Example ```json { "isEnd": true, "data": [ // Media items based on the search type ] } ``` ### WARNING - You can extend any serializable fields in the search results or basic media types. These fields will also be passed in the get audio source method, so it is best to keep your plugin based on the "basic media type" with fixed field extensions to prevent incompatibility. ``` -------------------------------- ### ILyricSource Interface and getLyric Signature Source: https://musicfree.catcat.work/plugin/protocol.html Defines the structure for lyric results and the function signature for retrieving lyrics. ```typescript interface ILyricSource { rawLrc?: string; // 文本格式的歌词 translation?: string; // 文本格式的翻译 } // 获取歌词函数签名 type getLyric = (musicItem: IMusicItem) => Promise; ``` -------------------------------- ### getTopListDetail Source: https://musicfree.catcat.work/plugin/protocol.html Retrieves the details of a music list, including the songs within it. This function is called when a user clicks on a specific music list from the list page. ```APIDOC ## getTopListDetail ### Description Retrieves the details of a music list, including the songs within it. This function is called when a user clicks on a specific music list from the list page. ### Function Signature ```typescript type getTopListDetail = ( topListItem: IMusicSheetItem, page?: number ) => Promise; ``` ### Parameters #### Path Parameters - **topListItem** (IMusicSheetItem) - Required - The music list item, which is a specific `IMusicSheetItem` from the list returned by `getTopLists`. - **page** (number) - Optional - The page number, starting from 1. ### Returns Returns a `Promise` object with the following key-value types: - **isEnd** (boolean) - Whether the end of the list has been reached, defaults to `true`. - **topListItem** (IMusicSheetItem) - Supplementary playlist information. - **musicList** (IMusicItem[]) - Songs for the current page. ### Example ```javascript module.exports = { // ... async getTopListDetail(topListItem) { // Get top list details return { musicList: [], }; }, }; ``` ``` -------------------------------- ### Default Network Request Headers (Android) Source: https://musicfree.catcat.work/plugin/caution.html Network requests on Android include default headers. If requests fail in the app but work in Node.js, check if these default headers are causing issues. ```text accept: application/json, text/plain, */* Accept-Encoding: gzip Connection: Keep-Alive User-Agent: okhttp/4.10.0 Host: musicfree.catcat.work If-Modified-Since: Thu, 15 Feb 2024 06:07:49 GMT ``` -------------------------------- ### getMusicSheetInfo Source: https://musicfree.catcat.work/plugin/protocol.html Retrieves detailed information about a music sheet, including its music list and supplementary sheet details. This function is called when a user navigates to a music sheet's detail page. ```APIDOC ## getMusicSheetInfo ### Description Retrieves detailed information about a music sheet, including its music list and supplementary sheet details. This function is called when a user navigates to a music sheet's detail page to complete missing properties in `sheetItem` and fetch the music list under the sheet. ### Function Signature ```typescript interface IGetSheetInfoResult = { isEnd?: boolean; musicList: IMusicItem[]; sheetItem?: Partial; } type getMusicSheetInfo = (sheetItem: MusicSheetItem, page: number) => Promise; ``` ### Parameters #### Parameters - **sheetItem** (`IMusicSheetItem`) - Required - The music sheet for which to retrieve detailed information. - **page** (`number`) - Required - The page number, starting from 1. ### Return Value A `Promise` object containing the following key-value types: - **isEnd** (`boolean`) - Indicates if the end of the songs in the album has been reached; defaults to `true`. - **musicList** (`IMusicItem[]`) - The list of songs within the album. - **sheetItem** (`Partial`) - Partial or full fields of the music sheet, used to supplement other information within the sheet, such as the introduction. This field is optionally returned only when `page <= 1`; it is not necessary to return this field in other cases. ### Example ```javascript module.exports = { // ... async getMusicSheetInfo(sheetItem, page) { if (page <= 1) { return { isEnd: false, musicList: [], albumItem: { description: "这是专辑的补充说明", }, }; } // Other page numbers return normally return { isEnd: true, musicList: [], }; }, }; ``` ``` -------------------------------- ### getArtistWorks Source: https://musicfree.catcat.work/plugin/protocol.html Retrieves an artist's works (songs or albums). This function is called when a user navigates to an artist's detail page to obtain their music or album information. ```APIDOC ## getArtistWorks ### Description Retrieves an artist's works (songs or albums). This function is called when a user navigates to an artist's detail page to obtain their music or album information. ### Function Signature ```typescript type ArtistMediaType = 'music' | 'album'; type getArtistWorks = ( artistItem: ArtistItem, page: number, type: T, ) => Promise>; ``` ### Parameters #### Parameters - **artistItem** (`IArtistItem`) - Required - The artist for whom to retrieve detailed information. - **page** (`number`) - Required - The page number, starting from 1. - **type** (`'music' | 'album'`) - Required - Specifies the type of media to retrieve ('music' for songs, 'album' for albums). ### Return Value A `Promise` object containing the following key-value types: - **isEnd** (`boolean`) - Indicates if the end of the songs or albums for the current artist has been reached; defaults to `true`. - **data** (`IMediaItem[]`) - The type of `data` is related to the search type `type` provided in the parameters. If the search type is `music`, `data` is of type `IMusicItem[]`; if the search type is `album`, `data` is of type `IAlbumItem[]`. ### Example ```javascript module.exports = { // ... async getArtistWorks(artistItem, page, type) { // Get artist's music if (type === "music") { return { isEnd: true, data: [], }; } // Get artist's albums if (type === "album") { return { isEnd: false, data: [], }; } }, }; ``` ```