APlayer 中文文档 下载 App

根据专辑封面自动提取主题色

效果

封面自适应主题色是指:每首歌曲有自己的封面图,播放器根据封面图的主色调自动设置主题色。当切换歌曲时,主题色会平滑过渡到新封面的主色。

这个功能需要额外引入 color-thief.js 库——它负责从图片中提取主色调。

引入顺序

<!-- 1. APlayer CSS -->
<link rel="stylesheet" href="APlayer.min.css">

<!-- 2. 播放器容器 -->
<div id="aplayer"></div>

<!-- 3. APlayer JS -->
<script src="APlayer.min.js"></script>

<!-- 4. color-thief.js(放在 APlayer 之后) -->
<script src="color-thief.umd.js"></script>

<!-- 5. 初始化代码 -->
<script>
// 见下文完整代码
</script>

完整实现代码

const ap = new APlayer({
    container: document.getElementById('aplayer'),
    theme: '#e9e9e9',  // 默认主题色
    audio: [
        { name: '歌曲一', artist: 'A', url: '1.mp3', cover: '1.jpg' },
        { name: '歌曲二', artist: 'B', url: '2.mp3', cover: '2.jpg' },
        { name: '歌曲三', artist: 'C', url: '3.mp3', cover: '3.jpg' }
    ]
});

// 初始化 ColorThief
const colorThief = new ColorThief();
const image = new Image();
const xhr = new XMLHttpRequest();

function setTheme(index) {
    // 如果这首歌已有手动设置的 theme,优先使用
    if (ap.list.audios[index].theme) return;

    xhr.onload = function() {
        const coverUrl = URL.createObjectURL(this.response);
        image.onload = function() {
            // 从封面图提取主色
            const color = colorThief.getColor(image);
            // 设置为 APlayer 的主题色
            ap.theme(`rgb(${color[0]}, ${color[1]}, ${color[2]})`, index);
            URL.revokeObjectURL(coverUrl);
        };
        image.crossOrigin = 'Anonymous';
        image.src = coverUrl;
    };
    xhr.open('GET', ap.list.audios[index].cover, true);
    xhr.responseType = 'blob';
    xhr.send();
}

// 首次加载时为第一首歌设置主题色
setTheme(ap.list.index);

// 切歌时重新提取
ap.on('listswitch', setTheme);

代码逻辑说明

  1. 初始化一个 ColorThief 实例
  2. 定义 setTheme(index) 函数:下载封面图 → 提取主色 → 设置主题色
  3. 首次加载时为当前播放歌曲(或第一首)提取主题色
  4. 监听 listswitch 事件,每次切歌都重新提取

CORS 注意事项

封面图如果是跨域资源,需要目标服务器允许跨域访问。XMLHttpRequest 会发送跨域请求,如果目标服务器没有返回正确的 CORS 头,请求会失败。

解决方法:

性能考虑

提取颜色需要下载封面图并解码,这是一个有代价的操作。如果图片很大(比如 4000x4000),可以先压缩一下封面图再提取。

APlayer 自己对封面图没有尺寸要求,但 color-thief 处理大图会比较慢。建议封面图控制在 800x800 以内。

简化方案:只为有手动 theme 的歌曲跳过

如果你想让部分歌曲用自动提取的颜色、部分歌曲用手动指定的颜色,代码已经帮你处理了:检查 ap.list.audios[index].theme 是否存在,有则跳过自动提取。

audio: [
    { name: '歌曲一', cover: '1.jpg' },                    // 自动提取颜色
    { name: '歌曲二', cover: '2.jpg', theme: '#333' },     // 强制深色主题
    { name: '歌曲三', cover: '3.jpg' }                     // 自动提取颜色
]