Files
vs100/src/utils/musicPlayer.js

182 lines
5.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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();