| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- <template>
- <button class="cu-btn voice-btn" v-if="!disabled" ref="v-btn"
- :class="voice.recording ? 'active' : ''"
- @touchstart.stop.prevent="startVoice" @touchmove.stop.prevent="moveVoice" @touchend.stop="endVoice"
- @touchcancel.stop="cancelVoice">
- {{ voice.voiceTitle }}
- </button>
- <button class="cu-btn" v-if="disabled" ref="v-btn"
- :style="{ background: voice.recording ? '#c7c6c6' : '#FFFFFF',flex:'1' }">
- {{ times }}秒后可录音
- </button>
- </template>
- <script setup lang="ts">
- import {onMounted, reactive, ref} from "vue";
- import MessageType from "@/utils/MessageType";
- import upload from '@/api/UploadApi';
- import MessageUtils from "@/utils/MessageUtils";
- const disabled = ref(false);
- const times = ref(5);
- const interval = ref(-1);
- const emit = defineEmits(["uploadCallback"]);
- const voice = reactive({
- voiceTitle: '按住 说话',
- Recorder: uni.getRecorderManager(),
- recording: false,
- //标识是否正在录音
- isStopVoice: false,
- //加锁 防止点击过快引起的当录音正在准备(还没有开始录音)的时候,却调用了stop方法但并不能阻止录音的问题
- voiceInterval: -1,
- voiceTime: 0, //总共录音时长
- canSend: true, //是否可以发送
- PointY: 0, //坐标位置
- showFunBtn: false, //是否展示功能型按钮
- AudioExam: null //正在播放音频的实例
- })
- onMounted(() => {
- //录音开始事件
- voice.Recorder.onStart(() => {
- beginVoice();
- });
- //录音结束事件
- voice.Recorder.onStop(res => {
- clearInterval(voice.voiceInterval);
- if (voice.voiceTime >= 1) {
- handleRecorder(res);
- } else {
- voice.recording = false;
- MessageUtils.message('录音时间太短')
- }
- });
- })
- //准备开始录音
- const startVoice = (e: TouchEvent) => {
- voice.recording = true;
- voice.isStopVoice = false;
- voice.canSend = true;
- voice.PointY = e.touches[0].clientY;
- voice.Recorder.start({
- format: 'mp3'
- });
- }
- //录音已经开始
- const beginVoice = () => {
- uni.showLoading({
- title: '正在录音'
- })
- voice.voiceTitle = '松开 结束'
- voice.voiceInterval = setInterval(() => {
- voice.voiceTime++;
- }, 1000)
- }
- //move 正在录音中
- const moveVoice = (e: TouchEvent) => {
- const pointY = e.touches[0].clientY
- const slideY = voice.PointY - pointY;
- if (slideY > uni.upx2px(120)) {
- voice.canSend = false;
- } else if (slideY > uni.upx2px(60)) {
- voice.canSend = true;
- }
- }
- //结束录音
- const endVoice = () => {
- uni.hideLoading()
- voice.isStopVoice = true; //加锁 确保已经结束录音并不会录制
- setTimeout(function () {
- voice.Recorder.stop();
- }, 200)
- voice.voiceTitle = '按住 说话'
- disabled.value = true;
- setTimeout(function () {
- disabled.value = false;
- clearInterval(interval.value)
- times.value = 5;
- }, 5000)
- interval.value = setInterval(function () {
- times.value--;
- }, 1000)
- }
- //录音被打断
- const cancelVoice = () => {
- voice.voiceTime = 0;
- voice.voiceTitle = '按住 说话';
- voice.canSend = false;
- voice.Recorder.stop();
- }
- //处理录音文件
- const handleRecorder = ({tempFilePath}: any) => {
- voice.recording = false;
- uni.showLoading({
- title: '正在上传'
- })
- upload(tempFilePath)
- .then((res: any) => {
- const extend = {url: res.url, time: Math.ceil(voice.voiceTime)};
- voice.voiceTime = 0;
- emit('uploadCallback', extend, MessageType.voice)
- })
- .finally(() => {
- uni.hideLoading()
- })
- }
- </script>
- <style scoped>
- .voice-btn {
- flex: 1;
- display: flex;
- align-items: center;
- justify-content: center;
- background-color: #fff;
- padding: 20upx;
- box-shadow: 0.0625rem 0.0625rem 0.1875rem rgba(0, 0, 0, .2);
- position: relative;
- margin: 0 .1875rem !important;
- height: 100%;
- }
- .voice-btn.active {
- background-color: #57d757;
- color: #ffffff;
- }
- </style>
|