feat: expose live stream ref from useVoiceRecorder

This commit is contained in:
2026-04-06 20:00:22 -04:00
parent 84926d4ba2
commit ac7dde472f
+7 -6
View File
@@ -1,4 +1,4 @@
import { ref, readonly } from 'vue'
import { ref, readonly, type Ref } from 'vue'
/**
* Push-to-talk recorder wrapping the browser MediaRecorder API.
@@ -15,7 +15,7 @@ export function useVoiceRecorder() {
let mediaRecorder: MediaRecorder | null = null
let chunks: Blob[] = []
let stream: MediaStream | null = null
const streamRef = ref<MediaStream | null>(null)
let resolveStop: ((blob: Blob) => void) | null = null
let rejectStop: ((err: Error) => void) | null = null
@@ -28,7 +28,7 @@ export function useVoiceRecorder() {
if (recording.value) return
try {
stream = await navigator.mediaDevices.getUserMedia({ audio: true })
streamRef.value = await navigator.mediaDevices.getUserMedia({ audio: true })
} catch (e) {
error.value = 'Microphone access denied'
return
@@ -41,7 +41,7 @@ export function useVoiceRecorder() {
? 'audio/webm'
: ''
mediaRecorder = mimeType ? new MediaRecorder(stream, { mimeType }) : new MediaRecorder(stream)
mediaRecorder = mimeType ? new MediaRecorder(streamRef.value!, { mimeType }) : new MediaRecorder(streamRef.value!)
mediaRecorder.ondataavailable = (e) => {
if (e.data.size > 0) chunks.push(e.data)
@@ -50,8 +50,8 @@ export function useVoiceRecorder() {
mediaRecorder.onstop = () => {
const blob = new Blob(chunks, { type: mediaRecorder?.mimeType ?? 'audio/webm' })
chunks = []
stream?.getTracks().forEach((t) => t.stop())
stream = null
streamRef.value?.getTracks().forEach((t) => t.stop())
streamRef.value = null
recording.value = false
resolveStop?.(blob)
resolveStop = null
@@ -88,5 +88,6 @@ export function useVoiceRecorder() {
isSupported,
startRecording,
stopRecording,
stream: readonly(streamRef) as Readonly<Ref<MediaStream | null>>,
}
}