Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AerMusic Dev

平台开发指南

快速开始

创建新平台只需 3 步:

1. 创建目录

assets/app/contain/your-platform/
└── main.js

2. 编写适配器

// assets/app/contain/your-platform/main.js

const YourPlatform = {
    // 平台信息
    INFO: {
        ID: 'your-platform',           // 唯一标识
        NAME: '你的平台',               // 显示名称
        ICON: '🎵',                     // 图标(或SVG)
        COLOR: '#1DB954',              // 品牌色
        API_BASE: 'https://api.xxx.com', // API地址
        AUTHOR: '作者名',               // 作者
        AUTHOR_URL: 'https://...',      // 作者主页
        DESCRIPTION: '平台描述',         // 平台描述
        API: {
            songPage: 'https://...'     // 歌曲页面URL(可选)
        }
    },
    
    // 搜索
    async search(keyword, options = {}) {
        const limit = options.limit || 30;
        const type = options.type || 1; // 1:单曲, 10:专辑, 100:歌手
        const res = await axios.get(`${this.INFO.API_BASE}/search`, {
            params: { keyword, limit, type }
        });
        return res.data.songs;
    },
    
    // 获取歌曲详情
    async getSongDetail(songId) {
        const res = await axios.get(`${this.INFO.API_BASE}/song/${songId}`);
        return res.data;
    },
    
    // 获取播放URL
    async getSongUrl(songId, options = {}) {
        const quality = options.quality || '320k';
        const res = await axios.get(`${this.INFO.API_BASE}/song/url`, {
            params: { id: songId, quality }
        });
        return res.data.url;
    },
    
    // 获取歌词(可选)
    async getLyric(songId) {
        try {
            const res = await axios.get(`${this.INFO.API_BASE}/lyric/${songId}`);
            return {
                lrc: res.data.lrc,
                yrc: res.data.yrc,
                tlyric: res.data.tlyric
            };
        } catch (e) {
            return null;
        }
    },
    
    // 获取相似歌曲(可选)
    async getSimilar(songId) {
        const res = await axios.get(`${this.INFO.API_BASE}/similar/${songId}`);
        return res.data.songs;
    },
    
    // 获取推荐歌曲(可选)
    async getRecommend() {
        const res = await axios.get(`${this.INFO.API_BASE}/recommend`);
        return res.data.songs;
    },
    
    // 获取歌手详情(可选)
    async getArtistDetail(artistId) {
        const res = await axios.get(`${this.INFO.API_BASE}/artist/detail`, {
            params: { id: artistId }
        });
        return res.data.data;
    },
    
    // 获取歌手歌曲(可选)
    async getArtistSongs(artistId) {
        const res = await axios.get(`${this.INFO.API_BASE}/artists`, {
            params: { id: artistId }
        });
        return res.data.hotSongs;
    },
    
    // 获取歌手专辑(可选)
    async getArtistAlbums(artistId, limit = 30) {
        const res = await axios.get(`${this.INFO.API_BASE}/artist/album`, {
            params: { id: artistId, limit }
        });
        return res.data.hotAlbums;
    },
    
    // 获取专辑歌曲(可选)
    async getAlbum(albumId) {
        const res = await axios.get(`${this.INFO.API_BASE}/album`, {
            params: { id: albumId }
        });
        return res.data.songs;
    },
    
    // 获取搜索建议(可选)
    async getSearchSuggest(keyword) {
        const res = await axios.get(`${this.INFO.API_BASE}/search/suggest`, {
            params: { keywords: keyword }
        });
        return res.data.result;
    }
};

// 注册到 PlatformCore
if (window.PlatformCore) {
    window.PlatformCore.register(YourPlatform);
}

3. 在 index.html 中引入

<script src="./assets/app/contain/your-platform/main.js"></script>

API 方法详解

必需方法

方法 参数 返回值 说明
search keyword, options Promise 搜索歌曲
getSongDetail songId Promise 获取歌曲详情
getSongUrl songId, options Promise 获取播放URL

可选方法

方法 参数 返回值 说明
getLyric songId Promise 获取歌词
getSimilar songId Promise 获取相似歌曲
getRecommend - Promise 获取推荐歌曲
getArtistDetail artistId Promise 获取歌手详情
getArtistSongs artistId Promise 获取歌手歌曲
getArtistAlbums artistId, limit Promise 获取歌手专辑
getAlbum albumId Promise 获取专辑歌曲
getSearchSuggest keyword Promise 获取搜索建议

INFO 配置详解

INFO: {
    ID: 'cloudmusic',        // 必需:唯一标识(小写字母+连字符)
    NAME: '网易云音乐',       // 必需:显示名称
    ICON: '🎵',              // 可选:图标(emoji或SVG字符串)
    COLOR: '#C20C0C',        // 可选:品牌色(用于搜索结果标签)
    API_BASE: 'https://...', // 可选:API基础地址
    AUTHOR: '作者名',         // 可选:作者
    AUTHOR_URL: 'https://...', // 可选:作者主页
    DESCRIPTION: '描述',      // 可选:平台描述
    API: {
        songPage: 'https://...' // 可选:歌曲页面URL
    }
}

数据标准化

PlatformCore 会自动将搜索结果标准化为统一格式。如果平台数据格式特殊,可以在适配器中自定义:

async search(keyword, options = {}) {
    const res = await axios.get(...);
    
    // 自定义标准化
    return res.data.songs.map(song => ({
        id: song.song_id,
        name: song.title,
        artist: song.singers.join(', '),
        album: song.album_name,
        cover: song.cover_url,
        duration: song.length * 1000,
        // 扩展字段(用于歌手/专辑跳转)
        artists: song.singers.map(s => ({ id: s.id, name: s.name })),
        albumId: song.album_id
    }));
}

调试技巧

检查平台注册

console.log(window.PlatformCore.platforms);

测试搜索

const results = await window.PlatformCore.search('测试');
console.log(results);

播放样式开发指南

快速开始

创建新样式只需 3 步:

1. 创建目录

assets/app/playstyle/your-style/
├── theme.js   # 样式逻辑
└── style.css  # 样式定义

2. 编写样式信息

// assets/app/playstyle/your-style/theme.js

const STYLE_INFO = {
    ID: 'your-style',          // 唯一标识
    NAME: '你的样式',           // 样式名称
    DC: '样式描述',             // 样式描述
    VERSION: '1.0.0',          // 版本
    AUTHOR: '作者名',           // 作者
    AUTHOR_URL: 'https://...', // 作者主页(可选)
    BG: '',                    // 封面URL、base64、hex颜色或留空
    FILE: {}                   // 额外资源文件
};

const AerTheme = {
    STYLE_INFO: STYLE_INFO,
    
    renderPage(song, index) {
        return `<div>...</div>`;
    },
    
    getControlsHtml(song, index) {
        return `<div>...</div>`;
    },
    
    updateProgress(currentTime, duration, index) {
        // 更新进度条
    },
    
    updateStatus(isPlaying, loopMode, index) {
        // 更新播放状态
    },
    
    onRendered(song, index, container) {
        // 渲染完成回调
    }
};

if (window.StyleCore) {
    window.StyleCore.register(AerTheme);
}

3. 编写样式

/* assets/app/playstyle/your-style/style.css */
/* 可以通过 @import 引入 main.min.css */

STYLE_INFO 配置详解

const STYLE_INFO = {
    ID: 'your-style',      // 必需:唯一标识
    NAME: '样式名称',       // 必需:显示名称
    DC: '样式描述',         // 可选:描述
    VERSION: '1.0.0',      // 可选:版本
    AUTHOR: '作者名',       // 可选:作者
    AUTHOR_URL: 'https://...', // 可选:作者主页(点击作者名跳转)
    BG: '',                // 可选:预览背景
    FILE: {}               // 可选:额外资源
};

BG 可选值

  • URL: 'https://...'
  • base64: 'data:image/...'
  • hex颜色: '#1a1a1a'
  • rgb颜色: 'rgb(26, 26, 26)'
  • 渐变: 'linear-gradient(180deg, #1a1a2e, #000000)'
  • 留空: 使用默认纯色背景

核心方法

renderPage(song, index)

渲染整个播放页面。

参数:

  • song: 当前歌曲对象
  • index: 当前播放索引

返回:HTML字符串

getControlsHtml(song, index)

生成控制按钮HTML。使用 SVGcfg 获取共享图标。

updateProgress(currentTime, duration, index)

更新播放进度显示。

updateStatus(isPlaying, loopMode, index)

更新播放状态显示。

onRendered(song, index, container)

渲染完成后的回调,用于初始化交互。

与主程序交互

通过 window.app 访问主程序方法:

const app = window.app;

// 播放控制
app.play(song);
app.pause();
app.resume();
app.next();
app.prev();

// 设置
app.setQuality('flac');
app.setLoopMode('random');
app.setPlaybackRate(1.5);
app.setPreservePitch(true);

// 菜单
app.togglePlayModeMenu();
app.toggleSpeedMenu();
app.toggleVolumeMenu();
app.togglePlaylist();
app.toggleQualityMenu();

// 收藏
app.toggleCurrentFavorite();

// 歌手/专辑页
app.openArtistPage(artistId);
app.openAlbumPage(albumId);

SVG 图标

系统提供常用图标(在 style-core.jsSVGcfg 中):

const icons = window.SVGcfg;

icons.play       // 播放
icons.pause      // 暂停
icons.next       // 下一首
icons.prev       // 上一首
icons.volume(vol)// 音量
icons.shuffle    // 随机
icons.repeat     // 列表循环
icons.repeatOne  // 单曲循环
icons.speed      // 速度
icons.playlist   // 播放列表
icons.quality    // 音质
icons.heart      // 收藏
icons.download   // 下载
icons.share      // 分享
icons.add        // 添加
icons.dislike    // 隐藏歌词
icons.forward15  // 前进15秒
icons.backward15 // 后退15秒

弹出菜单

使用 Apple Music 风格弹窗:

app.showAppleModal(
    '标题',
    '<div>内容HTML</div>',
    (modal) => { /* 确定回调 */ },
    () => { /* 取消回调 */ },
    {
        confirmText: '确定',
        cancelText: '取消',
        hideFooter: false,
        width: '90%',
        maxWidth: '400px'
    }
);

响应式设计建议

使用 vh 单位实现等比缩放:

.container {
    width: 80vh;
    padding: 2vh;
    font-size: 1.8vh;
    border-radius: 1vh;
}

About

AerMusic 开发者仓库

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages