upload project
This commit is contained in:
commit
06961cae04
422 changed files with 110626 additions and 0 deletions
161
components/voice-message/voice-message.js
Normal file
161
components/voice-message/voice-message.js
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
|
||||
Component({
|
||||
properties: {
|
||||
// 语音消息数据
|
||||
voiceData: {
|
||||
type: Object,
|
||||
value: {},
|
||||
observer: 'onVoiceDataChange'
|
||||
},
|
||||
|
||||
// 是否为自己发送的消息
|
||||
isSelf: {
|
||||
type: Boolean,
|
||||
value: false
|
||||
},
|
||||
|
||||
// 消息ID
|
||||
messageId: {
|
||||
type: String,
|
||||
value: ''
|
||||
}
|
||||
},
|
||||
|
||||
data: {
|
||||
// 播放状态
|
||||
isPlaying: false,
|
||||
|
||||
// 波形数据
|
||||
waveformData: [],
|
||||
|
||||
// 语音信息
|
||||
voiceUrl: '',
|
||||
voiceDuration: 0
|
||||
},
|
||||
|
||||
lifetimes: {
|
||||
attached() {
|
||||
this.initComponent();
|
||||
},
|
||||
|
||||
detached() {
|
||||
this.cleanup();
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 初始化组件
|
||||
initComponent() {
|
||||
// 生成波形数据
|
||||
this.generateWaveform();
|
||||
|
||||
// 获取全局音频上下文
|
||||
const app = getApp();
|
||||
this.audioContext = app.globalData.audioContext || wx.createInnerAudioContext();
|
||||
|
||||
// 注册音频事件
|
||||
this.setupAudioEvents();
|
||||
},
|
||||
|
||||
// 语音数据变化处理
|
||||
onVoiceDataChange(newData, oldData) {
|
||||
if (!newData || JSON.stringify(newData) === JSON.stringify(oldData)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setData({
|
||||
voiceUrl: newData.url || '',
|
||||
voiceDuration: newData.duration || 0
|
||||
});
|
||||
|
||||
// 重新生成波形
|
||||
this.generateWaveform();
|
||||
},
|
||||
|
||||
// 设置音频事件监听
|
||||
setupAudioEvents() {
|
||||
if (!this.audioContext) return;
|
||||
|
||||
this.audioContext.onPlay(() => {
|
||||
if (this.isCurrentAudio()) {
|
||||
this.setData({ isPlaying: true });
|
||||
}
|
||||
});
|
||||
|
||||
this.audioContext.onPause(() => {
|
||||
if (this.isCurrentAudio()) {
|
||||
this.setData({ isPlaying: false });
|
||||
}
|
||||
});
|
||||
|
||||
this.audioContext.onEnded(() => {
|
||||
if (this.isCurrentAudio()) {
|
||||
this.setData({ isPlaying: false });
|
||||
}
|
||||
});
|
||||
|
||||
this.audioContext.onError((err) => {
|
||||
console.error('语音播放错误:', err);
|
||||
if (this.isCurrentAudio()) {
|
||||
this.setData({ isPlaying: false });
|
||||
wx.showToast({ title: '播放失败', icon: 'none' });
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 检查是否为当前音频
|
||||
isCurrentAudio() {
|
||||
return this.audioContext && this.audioContext.src === this.data.voiceUrl;
|
||||
},
|
||||
|
||||
// 切换播放状态
|
||||
togglePlay() {
|
||||
if (!this.data.voiceUrl) {
|
||||
wx.showToast({ title: '语音地址无效', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (this.data.isPlaying) {
|
||||
this.audioContext.pause();
|
||||
} else {
|
||||
// 停止其他正在播放的音频
|
||||
if (this.audioContext.src !== this.data.voiceUrl) {
|
||||
this.audioContext.src = this.data.voiceUrl;
|
||||
}
|
||||
this.audioContext.play();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('播放语音失败:', error);
|
||||
wx.showToast({ title: '播放失败', icon: 'none' });
|
||||
}
|
||||
},
|
||||
|
||||
// 生成波形数据
|
||||
generateWaveform() {
|
||||
const duration = this.data.voiceDuration || 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 });
|
||||
},
|
||||
|
||||
// 清理资源
|
||||
cleanup() {
|
||||
// 如果当前正在播放,停止播放
|
||||
if (this.data.isPlaying && this.audioContext) {
|
||||
try {
|
||||
this.audioContext.stop();
|
||||
} catch (e) {
|
||||
// 忽略停止错误
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue