|
@@ -13,34 +13,35 @@
|
|
|
<audioTwoVue :active-word="activeWord" @play-audio="handlePlay"></audioTwoVue>
|
|
|
</view>
|
|
|
<view class="pin-words-explain-box du-words-explain-box">
|
|
|
- <view class="words-explain-item" v-if="data.jianyi&&data.jianyi.length>0" v-for="(item,index) in data.jianyi" :key="index">
|
|
|
+ <view class="words-explain-item" v-if="data.jianyi&&data.jianyi.length>0"
|
|
|
+ v-for="(item,index) in data.jianyi" :key="index">
|
|
|
{{item}}
|
|
|
</view>
|
|
|
</view>
|
|
|
- </view>
|
|
|
-
|
|
|
+ </view>
|
|
|
+
|
|
|
<view class="mike-play-box">
|
|
|
<view class="mike-play-tip" v-if="isRecording">录音中...</view>
|
|
|
- <view class="mike-play-tip" v-else>长按 读一读</view>
|
|
|
+ <view class="mike-play-tip" v-else>长按 读一读</view>
|
|
|
<!-- <view class="status">{{ recordingStatus }}</view> -->
|
|
|
<!-- <view class="duration" v-if="isRecording">录音时长: {{ Math.floor(duration) }}秒</view> -->
|
|
|
<view class="du-btn-box">
|
|
|
- <button class="play-btn" :class="{ 'playing-btn': isPlaying}" @click="playVoice" v-if="voicePath"></button>
|
|
|
- <button class="mike-btn" :class="{ 'mike-az-btn': isRecording}"
|
|
|
- @touchstart="handleTouchStart" @touchend="handleTouchEnd" @touchcancel="handleTouchEnd"
|
|
|
- :disabled="isPlaying">
|
|
|
+ <button class="play-btn" :class="{ 'playing-btn': isPlaying}" @click="playVoice"
|
|
|
+ v-if="voicePath"></button>
|
|
|
+ <button class="mike-btn" :class="{ 'mike-az-btn': isRecording}" @touchstart="handleTouchStart"
|
|
|
+ @touchend="handleTouchEnd" @touchcancel="handleTouchEnd" :disabled="isPlaying">
|
|
|
<!--{{ isRecording ? '松开结束' : '按住录音' }}
|
|
|
<view v-if="isPlaying" class="disabled-mask">播放中不可录音</view> -->
|
|
|
</button>
|
|
|
</view>
|
|
|
-
|
|
|
+
|
|
|
<!-- <button class="play-btn" :class="{ disabled: isRecording || !voicePath }" @click="playVoice"
|
|
|
:disabled="isRecording || !voicePath">
|
|
|
{{ isPlaying ? '播放中...' : '播放录音' }}
|
|
|
<view v-if="isRecording" class="disabled-mask">录音中不可播放</view>
|
|
|
</button> -->
|
|
|
</view>
|
|
|
-
|
|
|
+
|
|
|
</view>
|
|
|
</template>
|
|
|
|
|
@@ -87,7 +88,7 @@
|
|
|
const recordingStatus = ref('准备就绪')
|
|
|
const startTime = ref(0)
|
|
|
const longPressTimer = ref(null) // 长按计时器
|
|
|
-
|
|
|
+ const isRecorderReady = ref(true) // 新增:录音器就绪状态
|
|
|
|
|
|
// 获取录音和音频播放管理器
|
|
|
const recorderManager = uni.getRecorderManager()
|
|
@@ -98,6 +99,7 @@
|
|
|
recorderManager.onStart(() => {
|
|
|
console.log('recorder start')
|
|
|
isRecording.value = true
|
|
|
+ isRecorderReady.value = true // 录音结束后标记为就绪
|
|
|
// recordingStatus.value = '录音中...'
|
|
|
// startTime.value = Date.now()
|
|
|
// startTimer()
|
|
@@ -105,6 +107,7 @@
|
|
|
recorderManager.onStop((res) => {
|
|
|
// const recordTime = (Date.now() - startTime.value) / 1000 // 计算实际录音时间
|
|
|
isRecording.value = false
|
|
|
+ isRecorderReady.value = true // 录音结束后标记为就绪
|
|
|
// if (recordTime < 3) {
|
|
|
// uni.showToast({
|
|
|
// title: '录音时间太短,需3秒以上',
|
|
@@ -131,11 +134,15 @@
|
|
|
console.error('recorder error', res)
|
|
|
//stopTimer()
|
|
|
isRecording.value = false
|
|
|
+ isRecorderReady.value = true // 出错时也标记为就绪
|
|
|
+ setTimeout(() => {
|
|
|
+ initRecorder()
|
|
|
+ }, 300)
|
|
|
//recordingStatus.value = `录音错误: ${res.errMsg}`
|
|
|
- uni.showToast({
|
|
|
- title: `录音出错: ${res.errMsg}`,
|
|
|
- icon: 'none'
|
|
|
- })
|
|
|
+ // uni.showToast({
|
|
|
+ // title: `录音出错: ${res.errMsg}`,
|
|
|
+ // icon: 'none'
|
|
|
+ // })
|
|
|
})
|
|
|
|
|
|
innerAudioContext.onPlay(() => {
|
|
@@ -209,11 +216,12 @@
|
|
|
}
|
|
|
// 开始录音
|
|
|
const startRecording = () => {
|
|
|
- if (isRecording.value) return
|
|
|
+ if (isRecording.value || !isRecorderReady.value) return
|
|
|
|
|
|
console.log('开始录音')
|
|
|
//recordingStatus.value = '准备录音...'
|
|
|
isRecording.value = true // 提前设置状态,避免延迟
|
|
|
+ isRecorderReady.value = false
|
|
|
// startTime.value = Date.now()
|
|
|
// startTimer()
|
|
|
|
|
@@ -226,7 +234,17 @@
|
|
|
frameSize: 50
|
|
|
}
|
|
|
|
|
|
- recorderManager.start(options)
|
|
|
+ try {
|
|
|
+ recorderManager.start(options)
|
|
|
+ } catch (e) {
|
|
|
+ console.error('启动录音失败:', e)
|
|
|
+ isRecording.value = false
|
|
|
+ isRecorderReady.value = true
|
|
|
+ uni.showToast({
|
|
|
+ title: '启动录音失败,请重试',
|
|
|
+ icon: 'none'
|
|
|
+ })
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// 结束录音
|
|
@@ -234,9 +252,13 @@
|
|
|
if (!isRecording.value) return
|
|
|
|
|
|
console.log('停止录音')
|
|
|
- isRecording.value = false
|
|
|
- //stopTimer()
|
|
|
- recorderManager.stop()
|
|
|
+ try {
|
|
|
+ recorderManager.stop()
|
|
|
+ } catch (e) {
|
|
|
+ console.error('停止录音失败:', e)
|
|
|
+ isRecording.value = false
|
|
|
+ isRecorderReady.value = true
|
|
|
+ }
|
|
|
}
|
|
|
const getRecordingDuration = () => {
|
|
|
if (!isRecording.value) return 0
|
|
@@ -275,20 +297,28 @@
|
|
|
data.name = props.activeWord.name;
|
|
|
data.yinbiao = props.activeWord.yinbiao;
|
|
|
data.jianyi = props.activeWord.jianyi;
|
|
|
- console.log('data',data);
|
|
|
+ console.log('data', data);
|
|
|
}
|
|
|
|
|
|
onMounted(() => {
|
|
|
- initItem()
|
|
|
+ initItem()
|
|
|
initRecorder()
|
|
|
checkPermission()
|
|
|
-
|
|
|
+
|
|
|
})
|
|
|
|
|
|
onUnmounted(() => {
|
|
|
//stopTimer()
|
|
|
clearTimeout(longPressTimer.value)
|
|
|
- recorderManager.stop()
|
|
|
- innerAudioContext.stop()
|
|
|
+
|
|
|
+ try {
|
|
|
+ recorderManager.stop()
|
|
|
+ innerAudioContext.stop()
|
|
|
+ innerAudioContext.destroy()
|
|
|
+ } catch (e) {
|
|
|
+ console.error('清理资源时出错:', e)
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
})
|
|
|
</script>
|