findme-miniprogram-frontend/utils/voice-message-manager.js
2025-12-27 17:16:03 +08:00

282 lines
7.1 KiB
JavaScript

// 语音消息管理器 - 微信小程序专用
// 仅用于语音播放功能(录音和发送已由 NIM SDK 处理)
/**
* 语音消息播放管理器
* 功能:
* 1. 语音播放和暂停
* 2. 播放状态管理
*/
class VoiceMessageManager {
constructor() {
this.isInitialized = false;
// 播放配置
this.playConfig = {
autoplay: false,
loop: false,
volume: 1.0,
playbackRate: 1.0
};
// 音频上下文实例
this.innerAudioContext = null;
// 播放状态
this.playingState = {
isPlaying: false,
isPaused: false,
currentTime: 0,
duration: 0,
currentVoiceId: null,
playingMessageId: null
};
// 事件监听器
this.eventListeners = new Map();
this.init();
}
// 初始化语音消息管理器
async init() {
if (this.isInitialized) return;
console.log('🎤 初始化语音播放管理器...');
try {
// 初始化音频播放器
this.initAudioPlayer();
this.isInitialized = true;
console.log('✅ 语音播放管理器初始化完成');
} catch (error) {
console.error('❌ 语音播放管理器初始化失败:', error);
}
}
// 初始化音频播放器
initAudioPlayer() {
try {
if (this.innerAudioContext) {
try { this.innerAudioContext.destroy(); } catch (_) {}
}
this.innerAudioContext = wx.createInnerAudioContext();
// 播放开始事件
this.innerAudioContext.onPlay(() => {
this.playingState.isPlaying = true;
this.playingState.isPaused = false;
this.triggerEvent('playStart');
});
// 播放暂停事件
this.innerAudioContext.onPause(() => {
this.playingState.isPaused = true;
this.triggerEvent('playPause');
});
// 播放结束事件
this.innerAudioContext.onEnded(() => {
this.playingState.isPlaying = false;
this.playingState.isPaused = false;
this.playingState.currentTime = 0;
this.playingState.currentVoiceId = null;
this.playingState.playingMessageId = null;
this.triggerEvent('playEnd');
});
// 播放错误事件
this.innerAudioContext.onError((error) => {
console.error('❌ 语音播放错误:', error);
this.playingState.isPlaying = false;
this.playingState.isPaused = false;
this.triggerEvent('playError', error);
});
// 播放进度更新事件
this.innerAudioContext.onTimeUpdate(() => {
this.playingState.currentTime = this.innerAudioContext.currentTime;
this.playingState.duration = this.innerAudioContext.duration;
this.triggerEvent('playTimeUpdate', {
currentTime: this.playingState.currentTime,
duration: this.playingState.duration
});
});
// 音频加载完成事件
this.innerAudioContext.onCanplay(() => {
this.triggerEvent('playCanplay');
});
} catch (e) {
console.error('❌ 初始化音频播放器失败:', e);
}
}
// 🔊 ===== 播放功能 =====
// 播放语音消息
async playVoiceMessage(voiceUrl, messageId = null, options = {}) {
if (!this.isInitialized) {
throw new Error('语音播放管理器未初始化');
}
try {
// 如果正在播放其他语音,先停止
if (this.playingState.isPlaying) {
this.stopPlaying();
}
// 设置播放配置
const playOptions = { ...this.playConfig, ...options };
this.innerAudioContext.src = voiceUrl;
this.innerAudioContext.autoplay = playOptions.autoplay;
this.innerAudioContext.loop = playOptions.loop;
this.innerAudioContext.volume = playOptions.volume;
this.innerAudioContext.playbackRate = playOptions.playbackRate;
// 更新播放状态
this.playingState.currentVoiceId = voiceUrl;
this.playingState.playingMessageId = messageId;
// 开始播放
this.innerAudioContext.play();
} catch (error) {
console.error('❌ 播放语音消息失败:', error);
throw error;
}
}
// 暂停播放
pausePlaying() {
if (!this.playingState.isPlaying || this.playingState.isPaused) return;
try {
this.innerAudioContext.pause();
} catch (error) {
console.error('❌ 暂停播放失败:', error);
}
}
// 恢复播放
resumePlaying() {
if (!this.playingState.isPlaying || !this.playingState.isPaused) return;
try {
this.innerAudioContext.play();
} catch (error) {
console.error('❌ 恢复播放失败:', error);
}
}
// 停止播放
stopPlaying() {
if (!this.playingState.isPlaying) return;
try {
this.innerAudioContext.stop();
// 重置播放状态
this.playingState.isPlaying = false;
this.playingState.isPaused = false;
this.playingState.currentTime = 0;
this.playingState.currentVoiceId = null;
this.playingState.playingMessageId = null;
} catch (error) {
console.error('❌ 停止播放失败:', error);
}
}
// 设置播放进度
seekTo(time) {
if (!this.playingState.isPlaying) return;
try {
this.innerAudioContext.seek(time);
this.playingState.currentTime = time;
} catch (error) {
console.error('❌ 设置播放进度失败:', error);
}
}
// 📊 ===== 状态管理 =====
// 获取播放状态
getPlayingState() {
return { ...this.playingState };
}
// 是否正在播放
isPlaying() {
return this.playingState.isPlaying;
}
// 获取当前播放的消息ID
getCurrentPlayingMessageId() {
return this.playingState.playingMessageId;
}
// 🎧 ===== 事件管理 =====
// 注册事件监听器
on(event, callback) {
if (!this.eventListeners.has(event)) {
this.eventListeners.set(event, []);
}
this.eventListeners.get(event).push(callback);
}
// 移除事件监听器
off(event, callback) {
if (this.eventListeners.has(event)) {
const listeners = this.eventListeners.get(event);
const index = listeners.indexOf(callback);
if (index > -1) {
listeners.splice(index, 1);
}
}
}
// 触发事件
triggerEvent(event, data = null) {
if (this.eventListeners.has(event)) {
const listeners = this.eventListeners.get(event);
listeners.forEach(callback => {
try {
callback(data);
} catch (error) {
console.error(`❌ 事件处理器错误 [${event}]:`, error);
}
});
}
}
// 销毁管理器
destroy() {
// 停止播放
if (this.playingState.isPlaying) {
try { this.stopPlaying(); } catch (_) {}
}
// 销毁音频上下文
if (this.innerAudioContext) {
try { this.innerAudioContext.destroy(); } catch (_) {}
this.innerAudioContext = null;
}
// 清理事件监听器
this.eventListeners.clear();
this.isInitialized = false;
console.log('🎤 语音播放管理器已销毁');
}
}
// 创建全局实例
const voiceMessageManager = new VoiceMessageManager();
module.exports = voiceMessageManager;