// 🎤 语音消息组件逻辑 const voiceMessageManager = require('../../utils/voice-message-manager.js'); Component({ properties: { // 语音消息数据 voiceData: { type: Object, value: {}, observer: 'onVoiceDataChange' }, // 是否为自己发送的消息 isSelf: { type: Boolean, value: false }, // 消息ID messageId: { type: String, value: '' } }, data: { // 播放状态 isPlaying: false, isLoading: false, hasError: false, // 播放进度 currentTime: 0, duration: 0, playProgress: 0, // 波形数据 waveformData: [], currentWaveIndex: 0, // 语音信息 voiceUrl: '', voiceDuration: 0 }, lifetimes: { attached() { console.log('🎤 语音消息组件加载'); this.initComponent(); }, detached() { console.log('🎤 语音消息组件卸载'); this.cleanup(); } }, methods: { // 初始化组件 initComponent() { // 注册语音管理器事件 this.registerVoiceEvents(); // 生成波形数据 this.generateWaveform(); // 检查当前播放状态 this.checkPlayingState(); }, // 语音数据变化处理 onVoiceDataChange(newData, oldData) { if (!newData || JSON.stringify(newData) === JSON.stringify(oldData)) { return; } console.log('🎤 语音数据更新:', newData); this.setData({ voiceUrl: newData.url || '', voiceDuration: newData.duration || 0, duration: newData.duration || 0 }); // 重新生成波形 this.generateWaveform(); // 检查播放状态 this.checkPlayingState(); }, // 注册语音管理器事件 registerVoiceEvents() { // 播放开始事件 voiceMessageManager.on('playStart', () => { this.checkPlayingState(); }); // 播放结束事件 voiceMessageManager.on('playEnd', () => { this.setData({ isPlaying: false, currentTime: 0, playProgress: 0, currentWaveIndex: 0 }); }); // 播放进度更新事件 voiceMessageManager.on('playTimeUpdate', (data) => { if (this.isCurrentMessage()) { this.updatePlayProgress(data.currentTime, data.duration); } }); // 播放错误事件 voiceMessageManager.on('playError', (error) => { if (this.isCurrentMessage()) { console.error('🎤 语音播放错误:', error); this.setData({ isPlaying: false, isLoading: false, hasError: true }); } }); // 播放可以开始事件 voiceMessageManager.on('playCanplay', () => { if (this.isCurrentMessage()) { this.setData({ isLoading: false, hasError: false }); } }); }, // 检查是否为当前播放的消息 isCurrentMessage() { const currentMessageId = voiceMessageManager.getCurrentPlayingMessageId(); return currentMessageId === this.properties.messageId; }, // 检查播放状态 checkPlayingState() { const isCurrentlyPlaying = this.isCurrentMessage() && voiceMessageManager.isPlaying(); this.setData({ isPlaying: isCurrentlyPlaying }); }, // 切换播放状态 async togglePlay() { if (this.data.hasError) { return this.retryPlay(); } if (this.data.isLoading) { return; } try { if (this.data.isPlaying) { // 暂停播放 voiceMessageManager.pausePlaying(); this.setData({ isPlaying: false }); } else { // 开始播放 await this.startPlay(); } } catch (error) { console.error('🎤 切换播放状态失败:', error); this.setData({ hasError: true, isLoading: false, isPlaying: false }); } }, // 开始播放 async startPlay() { if (!this.data.voiceUrl) { console.error('🎤 语音URL为空'); return; } try { this.setData({ isLoading: true, hasError: false }); // 播放语音消息 await voiceMessageManager.playVoiceMessage( this.data.voiceUrl, this.properties.messageId ); this.setData({ isPlaying: true, isLoading: false }); console.log('🎤 开始播放语音消息'); } catch (error) { console.error('🎤 播放语音消息失败:', error); this.setData({ hasError: true, isLoading: false, isPlaying: false }); } }, // 重试播放 async retryPlay() { console.log('🎤 重试播放语音消息'); this.setData({ hasError: false, isLoading: false, isPlaying: false }); await this.startPlay(); }, // 更新播放进度 updatePlayProgress(currentTime, duration) { if (!duration || duration <= 0) return; const progress = (currentTime / duration) * 100; const waveIndex = Math.floor((currentTime / duration) * this.data.waveformData.length); this.setData({ currentTime: currentTime, duration: duration, playProgress: progress, currentWaveIndex: Math.max(0, waveIndex) }); }, // 生成波形数据 generateWaveform() { const duration = this.data.voiceDuration || this.data.duration || 1000; const barCount = Math.min(Math.max(Math.floor(duration / 200), 8), 30); // 8-30个波形条 const waveformData = []; for (let i = 0; i < barCount; i++) { // 生成随机高度,模拟真实波形 const height = Math.random() * 60 + 20; // 20-80%的高度 waveformData.push(height); } this.setData({ waveformData: waveformData, currentWaveIndex: 0 }); console.log('🌊 生成波形数据:', waveformData.length, '个波形条'); }, // 格式化时长显示 formatDuration(duration) { if (!duration || duration <= 0) return '0"'; const seconds = Math.floor(duration / 1000); const minutes = Math.floor(seconds / 60); const remainingSeconds = seconds % 60; if (minutes > 0) { return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`; } else { return `${remainingSeconds}"`; } }, // 格式化时间显示 formatTime(time) { if (!time || time <= 0) return '0:00'; const totalSeconds = Math.floor(time); const minutes = Math.floor(totalSeconds / 60); const seconds = totalSeconds % 60; return `${minutes}:${seconds.toString().padStart(2, '0')}`; }, // 获取语音文件大小描述 getFileSizeDescription(fileSize) { if (!fileSize || fileSize <= 0) return ''; if (fileSize < 1024) { return `${fileSize}B`; } else if (fileSize < 1024 * 1024) { return `${(fileSize / 1024).toFixed(1)}KB`; } else { return `${(fileSize / (1024 * 1024)).toFixed(1)}MB`; } }, // 清理资源 cleanup() { // 如果当前正在播放这个消息,停止播放 if (this.isCurrentMessage() && voiceMessageManager.isPlaying()) { voiceMessageManager.stopPlaying(); } // 移除事件监听器 voiceMessageManager.off('playStart'); voiceMessageManager.off('playEnd'); voiceMessageManager.off('playTimeUpdate'); voiceMessageManager.off('playError'); voiceMessageManager.off('playCanplay'); } } });