|
1 | 1 | <template> |
2 | | - <div> |
3 | | - <button @click="toggleRecording"> |
4 | | - {{ recording ? 'Stop Recording' : 'Start Recording' }} |
5 | | - </button> |
6 | | - <button @click="playRecording" :disabled="!audioUrl">Play Recording</button> |
7 | | - </div> |
| 2 | + <q-btn round flat :icon="recording ? matStop :matMic " :color="recording ? 'primary' : ''" @click="toggleRecording"> |
| 3 | + </q-btn> |
| 4 | + <btn v-if="props.showPlay" @click="playRecording" :disabled="!audioUrl">Play Recording</btn> |
8 | 5 | </template> |
9 | 6 |
|
10 | 7 | <script setup lang="ts"> |
11 | | -import { Ref, ref } from 'vue' |
12 | | -import { createTranscription } from 'src/lib/ai/openaiFacade' |
| 8 | +import {Ref, ref} from 'vue' |
| 9 | +import {createTranscription} from 'src/lib/ai/openaiFacade' |
| 10 | +import {matStop, matMic} from '@quasar/extras/material-icons' |
13 | 11 |
|
14 | | -const recording: Ref<boolean> = ref(false); |
15 | | -const mediaRecorder: Ref<MediaRecorder | null> = ref(null); |
16 | | -const audioUrl: Ref<string> = ref(''); |
| 12 | +const recording: Ref<boolean> = ref(false) |
| 13 | +const mediaRecorder: Ref<MediaRecorder | null> = ref(null) |
| 14 | +const audioUrl: Ref<string> = ref('') |
17 | 15 | const emit = defineEmits(['message']) |
| 16 | +const props = defineProps({showPlay: Boolean}) |
18 | 17 |
|
19 | 18 | const toggleRecording = async () => { |
20 | 19 | try { |
21 | 20 | if (recording.value && mediaRecorder.value) { |
22 | | - mediaRecorder.value.stop(); |
23 | | - recording.value = false; |
| 21 | + mediaRecorder.value.stop() |
| 22 | + recording.value = false |
24 | 23 | } else { |
25 | | - const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); |
26 | | - mediaRecorder.value = new MediaRecorder(stream); |
27 | | - recording.value = true; |
28 | | - audioUrl.value = ''; |
| 24 | + const stream = await navigator.mediaDevices.getUserMedia({audio: true}) |
| 25 | + mediaRecorder.value = new MediaRecorder(stream) |
| 26 | + recording.value = true |
| 27 | + audioUrl.value = '' |
29 | 28 |
|
30 | | - const recordedChunks: Blob[] = []; |
| 29 | + const recordedChunks: Blob[] = [] |
31 | 30 | mediaRecorder.value.ondataavailable = (event) => { |
32 | 31 | if (event.data.size > 0) { |
33 | | - recordedChunks.push(event.data); |
| 32 | + recordedChunks.push(event.data) |
34 | 33 | } |
35 | | - }; |
| 34 | + } |
36 | 35 |
|
37 | 36 | mediaRecorder.value.onstop = async () => { |
38 | 37 | try { |
39 | | - const blob = new Blob(recordedChunks, { type: 'audio/wav' }); |
40 | | - const file = new File([blob], 'recording.wav', { type: 'audio/wav' }); |
41 | | - audioUrl.value = URL.createObjectURL(file); |
42 | | - const text = await createTranscription({ blob }); |
43 | | - emit('message', text); |
| 38 | + const blob = new Blob(recordedChunks, {type: 'audio/wav'}) |
| 39 | + const file = new File([blob], 'recording.wav', {type: 'audio/wav'}) |
| 40 | + audioUrl.value = URL.createObjectURL(file) |
| 41 | + const text = await createTranscription({blob}) |
| 42 | + emit('message', text) |
44 | 43 | } catch (error) { |
45 | | - console.error('Error during transcription:', error); |
| 44 | + console.error('Error during transcription:', error) |
46 | 45 | } finally { |
47 | | - mediaRecorder.value = null; |
| 46 | + mediaRecorder.value = null |
48 | 47 | } |
49 | | - }; |
| 48 | + } |
50 | 49 |
|
51 | | - mediaRecorder.value.start(); |
| 50 | + mediaRecorder.value.start() |
52 | 51 | } |
53 | 52 | } catch (error) { |
54 | | - console.error('Error accessing microphone:', error); |
| 53 | + console.error('Error accessing microphone:', error) |
55 | 54 | } |
56 | | -}; |
| 55 | +} |
57 | 56 |
|
58 | 57 | const playRecording = () => { |
59 | 58 | if (audioUrl.value) { |
60 | | - const audioElement = new Audio(audioUrl.value); |
61 | | - audioElement.play(); |
| 59 | + const audioElement = new Audio(audioUrl.value) |
| 60 | + audioElement.play() |
62 | 61 | audioElement.onended = () => { |
63 | | - audioUrl.value = ''; |
64 | | - }; |
| 62 | + audioUrl.value = '' |
| 63 | + } |
65 | 64 | } |
66 | | -}; |
| 65 | +} |
67 | 66 | </script> |
0 commit comments