uni-app录音功能
纯纯干货,cv即用
<template><!-- 录音页面 --><view class="page"><view class="tape_box"><view class="upload_box1"><view class="upload_top"><view class="upload_img_title">录音</view></view><view class="tape_calculagraph">{{ formatTime }}</view><view class="upload_pate_con"><!-- 点击录音按钮 --><image @click="toggleRecording":src="isRecording ? '../../static/isks.png' : '../../static/isks.png'" mode=""style="width: 60px;height: 50px;"></image></view><view class="clear_tape" @click="clearRecording" v-if="recordingAvailable">清除录音</view><!-- H5 平台的音频播放器 --><view v-if="recordingAvailable" class="audio-player"><audio ref="h5Audio" :src="audioURL" controls autoplay title="自定义的音频名称" @play="onAudioPlay"@pause="onAudioPause" @ended="onAudioEnded"></audio></view></view></view></view>
</template><script setup>
import { ref, computed, onMounted, onBeforeUnmount, onUnmounted } from 'vue';
// 录音相关变量
const isRecording = ref(false);
const time = ref(0);
const formatTime = computed(() => {const minutes = String(Math.floor(time.value / 60)).padStart(2, '0');const seconds = String(time.value % 60).padStart(2, '0');return `${minutes}:${seconds}`;
});
let timer = null;// 平台检测
const systemInfo = uni.getSystemInfoSync();
const platform = systemInfo.platform;// 录音管理器
let recorderManager = null;// H5录音相关变量
let mediaRecorder = null;
let audioChunks = [];
let audioBlob = null;
const recordingAvailable = ref(false);
let audioURL = '';// 播放相关变量
const isPlaying = ref(false);
const h5Audio = ref(null);// 初始化录音和播放功能
onMounted(() => {if (['ios', 'android', 'devtools'].includes(platform)) {initNativeRecorder();isPlaying.value = false;} else if (['windows', 'mac'].includes(platform)) {initH5Recorder();} else {uni.showToast({title: '当前平台不支持录音',icon: 'none',});}
});// 清理资源
onBeforeUnmount(() => {if (h5Audio.value) {h5Audio.value.removeEventListener('play', onAudioPlay);h5Audio.value.removeEventListener('pause', onAudioPause);h5Audio.value.removeEventListener('ended', onAudioEnded);}
});onUnmounted(() => {clearInterval(timer);if (recorderManager && recorderManager.stop) {recorderManager.stop();}if (mediaRecorder && mediaRecorder.state !== 'inactive') {mediaRecorder.stop();}
});// 初始化原生平台的录音管理器
function initNativeRecorder() {recorderManager = uni.getRecorderManager();recorderManager.onStart(() => {console.log('开始录音');});recorderManager.onStop((res) => {console.log('录音已停止', res);isRecording.value = false;clearInterval(timer);time.value = 0;recordingAvailable.value = true;audioURL = res.tempFilePath;});recorderManager.onError((err) => {console.error('录音错误', err);isRecording.value = false;clearInterval(timer);time.value = 0;uni.showToast({title: '录音失败',icon: 'none',});});
}// 初始化H5平台的录音器
function initH5Recorder() {if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {uni.showToast({title: '浏览器不支持录音功能',icon: 'none',});return;}
}// 切换录音状态
function toggleRecording() {if (isRecording.value) {stopRecording();} else {startRecording();}
}// 开始录音
function startRecording() {if (['ios', 'android', 'devtools'].includes(platform)) {uni.authorize({scope: 'scope.record',success() {recorderManager.start({format: 'mp3',});isRecording.value = true;timer = setInterval(() => {time.value += 1;}, 1000);},fail() {uni.showModal({content: '请打开录音功能权限',confirmText: '确认',cancelText: '取消',success: (res) => {if (res.confirm) {uni.openSetting();}},});},});} else {// H5平台录音navigator.mediaDevices.getUserMedia({audio: true,}).then((stream) => {mediaRecorder = new MediaRecorder(stream);mediaRecorder.start();isRecording.value = true;timer = setInterval(() => {time.value += 1;}, 1000);mediaRecorder.ondataavailable = (e) => {audioChunks.push(e.data);};mediaRecorder.onstop = () => {audioBlob = new Blob(audioChunks, { type: 'audio/mp3' });audioChunks = [];recordingAvailable.value = true;audioURL = URL.createObjectURL(audioBlob);if (h5Audio.value) {h5Audio.value.src = audioURL;}};}).catch((err) => {console.error('录音失败:', err);uni.showToast({title: '无法访问麦克风',icon: 'none',});});}
}// 停止录音
function stopRecording() {if (['ios', 'android', 'devtools'].includes(platform)) {recorderManager.stop();} else {if (mediaRecorder && mediaRecorder.state !== 'inactive') {mediaRecorder.stop();isRecording.value = false;clearInterval(timer);time.value = 0;}}
}// 清除录音
function clearRecording() {recordingAvailable.value = false;audioURL = '';time.value = 0;
}// H5音频播放事件处理
function onAudioPlay() {isPlaying.value = true;
}function onAudioPause() {isPlaying.value = false;
}function onAudioEnded() {isPlaying.value = false;
}
</script><style>
.page {position: fixed;top: 0;left: 0;right: 0;bottom: 0;background-color: rgba(0, 0, 0, 0.5);display: flex;justify-content: center;align-items: center;
}.tape_box {background-color: white;width: 90%;padding: 20px;border-radius: 10px;box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);text-align: center;
}.upload_top {display: flex;justify-content: space-between;align-items: center;
}.upload_img_title {flex: 1;text-align: center;font-size: 18px;font-weight: bold;
}.tape_calculagraph {margin: 10px 0;font-size: 24px;font-weight: bold;
}.upload_pate_con image {width: 50px;height: 50px;cursor: pointer;
}.clear_tape {margin-top: 10px;color: #00daca;cursor: pointer;
}.audio-player audio {width: 100%;margin-top: 10px;
}
</style>