282 lines
7.1 KiB
JavaScript
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;
|