@@ -4,8 +4,11 @@ import { until } from '@vueuse/core'
44import { BufferTarget , MediaStreamAudioTrackSource , Output , QUALITY_MEDIUM , WavOutputFormat } from 'mediabunny'
55import { ref , shallowRef , toRef } from 'vue'
66
7- async function getMediaStreamTrack ( stream : MediaStream ) {
8- return stream . getAudioTracks ( ) [ 0 ]
7+ function getMediaStreamTrack ( stream : MediaStream ) {
8+ const tracks = stream . getAudioTracks ( )
9+ if ( ! tracks . length )
10+ throw new Error ( 'No audio tracks found in stream' )
11+ return tracks [ 0 ]
912}
1013
1114export function useAudioRecorder (
@@ -21,6 +24,10 @@ export function useAudioRecorder(
2124
2225 function onStopRecord ( callback : ( recording : Blob | undefined ) => Promise < void > ) {
2326 onStopRecordHooks . value . push ( callback )
27+ // Return unsubscribe function to prevent memory leaks
28+ return ( ) => {
29+ onStopRecordHooks . value = onStopRecordHooks . value . filter ( h => h !== callback )
30+ }
2431 }
2532
2633 async function startRecord ( ) {
@@ -42,15 +49,25 @@ export function useAudioRecorder(
4249 return
4350 }
4451
45- await mediaOutput . value ?. finalize ( )
46- const bufferTarget = mediaOutput . value ?. target as BufferTarget | undefined
47- const buffer = bufferTarget ! . buffer
48- const audioBlob = new Blob ( [ buffer ! ] , { type : mediaFormat . value } )
52+ await mediaOutput . value . finalize ( )
53+ const bufferTarget = mediaOutput . value . target as BufferTarget | undefined
54+ const buffer = bufferTarget ?. buffer
55+ const audioBlob = buffer ? new Blob ( [ buffer ] , { type : mediaFormat . value } ) : undefined
56+
57+ recording . value = audioBlob
4958
59+ // await hooks and catch errors
5060 for ( const hook of onStopRecordHooks . value ) {
51- hook ( audioBlob )
61+ try {
62+ await hook ( audioBlob )
63+ }
64+ catch ( err ) {
65+ console . error ( 'onStopRecord hook failed:' , err )
66+ }
5267 }
5368
69+ mediaOutput . value = undefined
70+
5471 return audioBlob
5572 }
5673
0 commit comments