97 lines
2.3 KiB
Vue
97 lines
2.3 KiB
Vue
<template>
|
|
<view class="voice-message" @click="playVoice">
|
|
<image
|
|
:src="isPlaying ? audioIcon : recordIcon"
|
|
class="audio-icon flipped"
|
|
mode="aspectFit"
|
|
/>
|
|
<text class="duration">{{ durationText }}</text>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
props: {
|
|
source: {
|
|
type: Object,
|
|
required: true
|
|
}
|
|
},
|
|
computed: {
|
|
durationText() {
|
|
const d = this.source.soundElem && this.source.soundElem.duration;
|
|
return d ? `${d}''` : '';
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
innerAudioContext: null,
|
|
isPlaying: false,
|
|
audioIcon: '/static/images/chating_footer_audio.png',
|
|
recordIcon: '/static/images/chating_footer_recording.png'
|
|
};
|
|
},
|
|
methods: {
|
|
getFixedSourceUrl(url) {
|
|
// 如果 url 以 http://47.117.71.33/api/object/ 开头,则替换为带端口的
|
|
if (typeof url === 'string' && url.startsWith('http://47.117.71.33/api/object/')) {
|
|
return url.replace('http://47.117.71.33/api/object/', 'http://47.117.71.33:15219/api/object/');
|
|
}
|
|
return url;
|
|
},
|
|
playVoice() {
|
|
if (this.innerAudioContext) {
|
|
this.innerAudioContext.stop();
|
|
this.innerAudioContext.destroy();
|
|
this.innerAudioContext = null;
|
|
}
|
|
this.innerAudioContext = uni.createInnerAudioContext();
|
|
const rawUrl = this.source.soundElem && this.source.soundElem.sourceUrl || '';
|
|
this.innerAudioContext.src = this.getFixedSourceUrl(rawUrl);
|
|
this.isPlaying = true;
|
|
this.innerAudioContext.play();
|
|
this.innerAudioContext.onEnded(() => {
|
|
this.innerAudioContext.destroy();
|
|
this.innerAudioContext = null;
|
|
this.isPlaying = false;
|
|
});
|
|
this.innerAudioContext.onStop(() => {
|
|
this.isPlaying = false;
|
|
});
|
|
this.innerAudioContext.onError(() => {
|
|
this.isPlaying = false;
|
|
});
|
|
}
|
|
},
|
|
beforeDestroy() {
|
|
if (this.innerAudioContext) {
|
|
this.innerAudioContext.destroy();
|
|
this.innerAudioContext = null;
|
|
}
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<style scoped>
|
|
.voice-message {
|
|
display: flex;
|
|
align-items: center;
|
|
cursor: pointer;
|
|
background: #f5f6fa;
|
|
border-radius: 18px;
|
|
padding: 8px 16px;
|
|
margin: 4px 0;
|
|
}
|
|
.audio-icon {
|
|
width: 28px;
|
|
height: 28px;
|
|
}
|
|
.flipped {
|
|
transform: rotate(180deg);
|
|
}
|
|
.duration {
|
|
margin-left: 8px;
|
|
color: #666;
|
|
font-size: 15px;
|
|
}
|
|
</style> |