// src/utils/musicPlayer.js class MusicPlayer { constructor() { this.audio = null; this.isPlaying = false; this.defaultPath = ""; this.enabled = false; this.volume = 0.5; // 默认音量50% } /** * 适配组件调用的 init 方法(核心:复用 initMusicConfig 逻辑) * @param {string} path 音乐文件路径(组件中传入的 musicPath) */ init(path) { // 组件调用 init 时,复用已有的 initMusicConfig,开关状态先传 this.enabled(后续组件会通过配置更新) this.initMusicConfig(path, this.enabled, this.volume); } /** * 原有初始化音乐配置方法(保留,适配动态配置) * @param {string} filePath 音乐路径 * @param {boolean} enabled 播放开关 */ initMusicConfig(filePath, enabled, volume = 0.5) { console.log("初始化音乐配置:", { filePath, enabled, volume }); this.enabled = enabled; // 确保音量是数字类型 this.volume = typeof volume === 'string' ? parseFloat(volume) : volume; console.log("处理后的音量值:", this.volume, "类型:", typeof this.volume); let validPath = this.defaultPath; if (filePath && filePath.endsWith('.mp3')) { validPath = filePath; } else if (filePath) { console.warn(`音乐路径无效(非MP3格式):${filePath},使用兜底路径`); } console.log("使用的音乐路径:", validPath); if (this.audio) { this.audio.pause(); this.audio = null; } this.audio = new Audio(validPath); this.audio.loop = true; this.audio.volume = this.volume; console.log("音频对象创建完成,音量设置为:", this.audio.volume); } /** * 播放音乐(保留原有逻辑,适配开关) */ play() { console.log("调用 play 方法,当前状态:", { enabled: this.enabled, hasAudio: !!this.audio, isPlaying: this.isPlaying }); if (!this.enabled) { console.log("首页播放开关未开启,跳过音乐播放"); return; } if (!this.audio) { console.warn("音频对象未初始化"); this.initMusicConfig(this.defaultPath, false); console.warn("未初始化音乐配置,使用兜底路径且关闭播放开关"); return; } console.log("音频源路径:", this.audio.src); console.log("音频就绪状态:", this.audio.readyState); if (!this.isPlaying) { this.audio.play() .then(() => { this.isPlaying = true; console.log("音乐播放成功,当前路径:", this.getCurrentPath()); }) .catch(err => { console.error("音乐播放失败(浏览器自动播放限制/路径错误):", err); console.error("错误详情:", { name: err.name, message: err.message, code: err.code }); this.isPlaying = false; }); } else { console.log("音乐已在播放中"); } } /** * 暂停音乐(保留原有逻辑) */ pause() { if (this.audio && this.isPlaying) { this.audio.pause(); this.isPlaying = false; console.log("音乐已暂停"); } } /** * 新增:设置静音/取消静音(适配管理员/首页场景) * @param {boolean} muted 是否静音 */ setMuted(muted) { if (this.audio) { this.audio.muted = muted; console.log(muted ? "音乐已静音" : "音乐已取消静音"); } } /** * 设置音量 * @param {number} volume 音量值 (0.0 到 1.0) */ setVolume(volume) { if (this.audio) { // 确保音量是数字类型 const numericVolume = typeof volume === 'string' ? parseFloat(volume) : volume; // 限制音量范围在0.0到1.0之间 this.volume = Math.max(0, Math.min(1, numericVolume)); this.audio.volume = this.volume; console.log(`音乐音量已设置为: ${Math.round(this.volume * 100)}%`); } } /** * 新增:stop 方法(组件 onUnmounted 调用,暂停+重置进度) */ stop() { if (this.audio) { this.audio.pause(); this.audio.currentTime = 0; // 重置播放进度到开头 this.isPlaying = false; console.log("音乐已停止(重置进度)"); } } /** * 新增:destroy 方法(组件 onUnmounted 调用,销毁实例释放内存) */ destroy() { this.stop(); // 先停止播放 if (this.audio) { this.audio = null; // 清空音频实例,释放内存 console.log("音乐实例已销毁,释放内存"); } } /** * 获取当前音乐路径(保留原有逻辑) * @returns {string} 相对路径 */ getCurrentPath() { if (!this.audio) return this.defaultPath; return this.audio.src.split(window.location.origin)[1] || this.defaultPath; } /** * 更新音乐路径(保留原有逻辑) * @param {string} newPath 新路径 */ updateMusicPath(newPath) { if (!newPath || !newPath.endsWith('.mp3')) { console.error("更新的音乐路径无效(非MP3格式):", newPath); return; } this.initMusicConfig(newPath, this.enabled, this.volume); console.log("音乐路径已更新为:", newPath); if (this.enabled && this.isPlaying) { this.pause(); this.play(); } } } // 导出全局唯一实例 export const musicPlayer = new MusicPlayer();