Component({properties: {src: {type: String,value: '',observer(newVal, oldVal) {if (newVal !== oldVal && newVal) {if (this.innerAudioContext) {this.innerAudioContext.stop()this.innerAudioContext.destroy()this.innerAudioContext = null}this.initializeAudio()}}}},data: {playStatus: 0, duration: 0, remain: 0 },lifetimes: {attached() {if (this.data.src) {this.initializeAudio()}},detached() {if (this.innerAudioContext) {this.innerAudioContext.stop()this.innerAudioContext.destroy()this.innerAudioContext = null}}},methods: {playBtn() {const { src, playStatus } = this.dataif (!src) {wx.showToast({title: '没有录音文件',icon: 'none'})return}if (!this.innerAudioContext) {this.initializeAudio()}if (playStatus === 1) {this.innerAudioContext.stop()this.setData({playStatus: 0,remain: this.data.duration})return}this.innerAudioContext.src = srcthis.innerAudioContext.play()this.setData({playStatus: 1,remain: this.data.duration})},initializeAudio() {this.innerAudioContext = wx.createInnerAudioContext()this.innerAudioContext.obeyMuteSwitch = falsethis.innerAudioContext.src = this.data.srcthis.innerAudioContext.onCanplay(() => {console.log('音频可以播放')const totalDuration = Math.floor(this.innerAudioContext.duration)if (totalDuration > 0) {this.setData({duration: totalDuration,remain: totalDuration})} else {console.warn('无法获取音频时长')}})this.innerAudioContext.onPlay(() => {console.log('音频开始播放')})this.innerAudioContext.onEnded(() => {console.log('音频播放结束')this.setData({playStatus: 0,remain: this.data.duration})this.triggerEvent('playComplete')})this.innerAudioContext.onError(err => {console.error('播放错误:', err)wx.showToast({title: '播放失败,请重试',icon: 'none'})this.setData({playStatus: 0,remain: this.data.duration})})this.innerAudioContext.onTimeUpdate(() => {const current = Math.floor(this.innerAudioContext.currentTime)const remain = Math.floor(this.innerAudioContext.duration) - currentthis.setData({remain: remain > 0 ? remain : 0})})}}
})
<view class="voice-msg" bindtap="playBtn"><imagesrc="{{ playStatus === 0 ? '/sendingaudio.png' : '/voice.gif' }}"mode="aspectFill"class="voice-icon"/><text class="voice-msg-text"> {{ playStatus === 1 ? (remain + "''") : (duration + "''") }} </text>
</view>
.voice-msg {display: flex;align-items: center;min-width: 200rpx;padding: 0 20rpx;height: 60rpx;background-color: rgba(149, 236, 105, 0.72);border-radius: 10rpx;box-shadow:0 3rpx 6rpx rgba(0, 0, 0, 0.13);.voice-icon {transform: rotate(180deg);width: 22rpx;height: 32rpx;}.voice-msg-text {margin-left: 10rpx;color:#000000 !important;font-size:30rpx !important;}
}