/ 插件 Halo / 14浏览

音乐播放器「每日自动换歌单」2.0

一、前言

很多博主都会给自己的 Halo 博客添加悬浮音乐播放器,但传统播放器只能固定播放单一歌单,长期使用容易审美疲劳、听感单调。

本次在原有毛玻璃悬浮、可拖动、贴边自动隐藏播放器的基础上,进行全方位功能升级,重磅实现按星期自动切换歌单功能,一周七天每天自动更换不同歌单.

二、升级前后功能对比

本次升级100% 兼容旧版所有交互功能,仅新增核心能力、优化播放稳定性,无功能删减。

对比项

旧版固定歌单播放器

新版每日换歌单播放器

核心播放逻辑

固定单一歌单,永久不更换

按星期自动切换7组歌单,每日更新播放内容

播放稳定性

极易受 VIP、版权、地区限制影响,常出现播放卡死、-0:00 无法播放

适配网易云外链规则,可自由配置公开歌单,规避版权拦截,播放稳定

交互体验

支持拖动、贴边隐藏、鼠标悬浮弹出

完全保留全部旧版交互,无学习成本

自定义扩展性

无法修改播放逻辑,功能固定

支持自定义7天歌单,可二次改造为随机播放、日期循环模式

三、新旧代码核心改动详解

为方便大家理解升级逻辑,下面详细拆解本次所有修改点,每一处改动都对应专属功能优化。

1. HTML 结构优化:给播放器添加唯一标识

旧版问题:iframe 播放地址写死,无唯一标识,无法通过代码动态修改歌单。

旧版代码片段

<iframe 
  src="https://music.163.com/outchain/player?type=0&id=12616213453&auto=0&height=100&bg=ffffff&fg=333333&mini=true" 
  width="100%" 
  height="100%" 
  frameborder="0"
  allowfullscreen
  style="border: none; position: relative; z-index: 1;">
</iframe>

新版优化:为 iframe 添加专属 ID music-iframe,让 JS 代码可以精准定位播放器,实现动态换歌单。

<iframe 
  id="music-iframe"
  width="100%" 
  height="100%" 
  frameborder="0"
  allowfullscreen
  style="border: none; position: relative; z-index: 1;">
</iframe>

2. 新增核心配置:7天歌单自定义数组

新版新增可视化歌单配置区,无需懂代码,直接修改数字即可更换每日歌单。

// 核心配置:周日 ~ 周六 每日歌单ID
const dailyPlaylistIds = [
  2561781141, // 周日
  4985993055, // 周一
  12616213453, // 周二
  2561781141, // 周三
  6665830498, // 周四
  3120089590, // 周五
  2561781141  // 周六
];

关键规则(必看)

  • 数组顺序严格对应:周日 → 周一 → 周二 → 周三 → 周四 → 周五 → 周六

  • 仅支持网易云公开歌单,私密歌单、含 VIP/灰色版权歌曲的歌单,外链无法播放

  • 可自由替换为自己的歌单 ID,支持自定义7组不同歌单

3. 新增自动切换核心函数

新增 setDailyPlaylist() 函数,实现「获取当日星期 → 匹配对应歌单 → 自动加载播放」的完整逻辑。

// 根据当天星期几自动加载对应歌单
function setDailyPlaylist() {
  const today = new Date().getDay(); // 0=周日、1=周一 ... 6=周六
  const playlistId = dailyPlaylistIds[today];
  
  // 动态拼接合规网易云外链播放地址
  const src = `https://music.163.com/outchain/player?type=0&id=${playlistId}&auto=1&height=100&bg=ffffff&fg=333333&mini=true`;
  iframe.src = src;
}

// 页面加载自动执行,初始化当日歌单
setDailyPlaylist();

小白通俗解释

  • 网页打开瞬间,代码自动识别今天是星期几

  • 自动调取预设好的当日歌单 ID

  • 自动生成合规播放链接,加载对应歌单

4. 修复播放故障,优化稳定性

针对旧版普遍存在的播放失效问题,做了两点关键修复:

  • 将原静态固定播放地址,改为动态拼接合规外链接口,适配网易云最新外链规则

  • 优化 auto=1 播放参数,平衡浏览器拦截与播放体验,大幅降低播放失败概率

  • 规避 VIP、版权歌曲拦截问题,只要歌单合规即可稳定播放

5. 完整保留旧版所有交互功能

本次升级未修改任何拖动、隐藏逻辑

  • 支持任意位置拖动悬浮播放器

  • 贴边自动隐藏、鼠标悬浮自动弹出

  • 播放区域可正常点击操作,拖动与播放互不冲突

四、一键安装配置教程

步骤1:复制新版完整代码

下方为最终成品代码,集成所有升级功能,直接复制即可使用:

<!-- 仅最右侧边缘自动缩回 · 极简毛玻璃网易云悬浮播放器(带每日歌单切换) -->
<div id="music-drag-container" style="position: fixed; bottom: 24px; right: 8px; z-index: 9999; width: 290px; height: 90px; transition: transform 0.3s ease-in-out;">
  <!-- 拖动手柄:默认透明,鼠标移上去时才变为可拖动 -->
  <div id="drag-handle" style="position: absolute; top: 0; left: 0; width: 95%; height: 95%; z-index: 2; pointer-events: none; cursor: default;"></div>
  
  <!-- 播放器本体 -->
  <div style="position: absolute; top: 0; left: 0; width: 90; height: 120%; border-radius: 16px; overflow: hidden; background: rgba(255,255,255,0.95); backdrop-filter: blur(10px); box-shadow: 0 4px 20px rgba(0,0,0,0.08); display: flex; align-items: center; justify-content: center; border: 1px solid rgba(0,0,0,0.05);">
    <iframe 
      id="music-iframe"
      width="100%" 
      height="100%" 
      frameborder="0"
      allowfullscreen
      style="border: none; position: relative; z-index: 1;">
    </iframe>
  </div>
</div>

<script>
const container = document.getElementById('music-drag-container');
const handle = document.getElementById('drag-handle');
const iframe = document.getElementById('music-iframe');
let isDragging = false;
let offsetX, offsetY;
let isHidden = false;
let isOverIframe = false;
let hideTimer = null; // 自动缩回的定时器

// ========== 【核心修改:每日歌单配置】 ==========
// 请把这里的ID替换成你自己的歌单ID,顺序是 周日~周六
const dailyPlaylistIds = [
  111111111, // 周日
  222222222, // 周一
  333333333, // 周二
  444444444, // 周三
  555555555, // 周四
  666666666, // 周五
  777777777  // 周六
];

// 根据当天星期几,设置对应的歌单
function setDailyPlaylist() {
  const today = new Date().getDay(); // 0=周日, 1=周一 ... 6=周六
  const playlistId = dailyPlaylistIds[today];
  
  // 构建网易云播放器链接,auto=1允许自动播放
  const src = `https://music.163.com/outchain/player?type=0&id=${playlistId}&auto=1&height=100&bg=ffffff&fg=333333&mini=true`;
  iframe.src = src;
}

// 页面加载时,立即设置当天的歌单
setDailyPlaylist();

// 1. 鼠标进入播放器区域:取消缩回,启用拖动
container.addEventListener('mouseenter', function(e) {
  // 鼠标进入时,清除自动缩回定时器
  if (hideTimer) clearTimeout(hideTimer);
  
  // 如果是隐藏状态,鼠标进入就自动弹出
  if (isHidden) {
    container.style.transform = 'translateX(0)';
    isHidden = false;
  }
  // 只有鼠标不在iframe区域时,才启用拖动
  if (!isOverIframe) {
    handle.style.pointerEvents = 'auto';
    handle.style.cursor = 'move';
  }
});

// 2. 鼠标离开播放器区域:仅在最右侧(窗口宽度99%以上)自动缩回
container.addEventListener('mouseleave', function() {
  handle.style.pointerEvents = 'none';
  handle.style.cursor = 'default';
  
  const playerRight = container.offsetLeft + container.offsetWidth;
  const windowWidth = window.innerWidth ;
  
  if (playerRight > windowWidth * 0.99) {
    hideTimer = setTimeout(() => {
      if (!isDragging && !isHidden) {
        container.style.transform = `translateX(${windowWidth - playerRight + 180}px)`;
        isHidden = true;
      }
    }, 500); // 延迟500ms缩回,避免误触
  }
});

// 3. 鼠标进入iframe区域:禁用拖动,恢复点击播放功能
iframe.addEventListener('mouseenter', function() {
  isOverIframe = true;
  handle.style.pointerEvents = 'none';
  handle.style.cursor = 'pointer';
  if (hideTimer) clearTimeout(hideTimer);
});

// 4. 鼠标离开iframe区域:恢复可拖动状态
iframe.addEventListener('mouseleave', function() {
  isOverIframe = false;
  handle.style.pointerEvents = 'auto';
  handle.style.cursor = 'move';
});

// 拖动开始
handle.addEventListener('mousedown', function(e) {
  isDragging = true;
  offsetX = e.clientX - container.offsetLeft;
  offsetY = e.clientY - container.offsetTop;
  container.style.transition = 'none';
  
  if (isHidden) {
    container.style.transform = 'translateX(0)';
    isHidden = false;
  }
  if (hideTimer) clearTimeout(hideTimer);
});

// 拖动中
document.addEventListener('mousemove', function(e) {
  if (!isDragging) return;
  
  let x = e.clientX - offsetX;
  let y = e.clientY - offsetY;
  
  // 限制在窗口内拖动,避免完全拖出屏幕
  x = Math.max(-container.offsetWidth + 30, Math.min(x, window.innerWidth - 30));
  y = Math.max(0, Math.min(y, window.innerHeight - container.offsetHeight));
  
  container.style.left = x + 'px';
  container.style.bottom = 'auto';
  container.style.top = y + 'px';
});

// 拖动结束,自动判断是否隐藏
document.addEventListener('mouseup', function() {
  if (!isDragging) return;
  isDragging = false;
  container.style.transition = 'transform 0.3s ease-in-out';
  
  const playerRight = container.offsetLeft + container.offsetWidth;
  const windowWidth = window.innerWidth;
  
  if (playerRight > windowWidth - 10) {
    container.style.transform = `translateX(${windowWidth - playerRight + 200}px)`;
    isHidden = true;
  } else {
    container.style.transform = 'translateX(0)';
    isHidden = false;
  }
});
</script>

步骤2:获取并替换自己的歌单ID

  1. 打开网易云音乐(网页端/客户端均可),找到需要的歌单;

  2. 右键歌单,选择「分享」,复制歌单链接;

  3. 链接格式示例:https://music.163.com/#/playlist?id=12616213453

  4. 链接中 id= 后面的纯数字,就是歌单ID

  5. 按「周日~周六」的顺序,替换代码中 dailyPlaylistIds 数组内的数字即可。

步骤3:Halo 后台部署

  1. 登录 Halo 博客后台,依次打开:设置 → 代码注入 → 全局 Head 标签

  2. 删除之前的旧版播放器代码;

  3. 粘贴修改好的新版完整代码;

  4. 点击保存,刷新博客页面即可生效。

五、常见问题排查

问题1:播放器正常显示,但播放卡死,显示 -0:00

  • 歌单为私密歌单,外链无法读取,需改为公开歌单

  • 歌单内包含 VIP、灰色无版权歌曲,外链无法解析播放;

  • 测试方案:替换官方公开测试歌单 ID 19723756,能播放再更换自定义歌单。

问题2:不会自动换歌单,一直播放同一首

  • 检查7个歌单ID是否全部一致,需配置不同ID才可切换;

  • 核对数组顺序是否为「周日到周六」,顺序错误会导致切换异常;

  • 确认未删除 setDailyPlaylist() 初始化代码。

问题3:拖动、贴边隐藏功能失效

  • 未修改播放器容器、手柄的 ID,任意ID修改都会导致交互失效;

  • 代码粘贴不完整,存在缺失、换行错乱问题,建议重新完整粘贴。

六、写在最后

本次升级在保留原有高颜值、高适配交互的基础上,解决了旧版播放器最大的播放兼容问题,新增每日换歌单功能,让博客背景音乐不再单调。全程零代码难度,所有博主均可快速部署。后续会继续持续进行优化

Peregrine
网页悬浮音乐播放器