@@ -4,8 +4,7 @@ import { useSupported } from '@vueuse/core'
44import { tryOnScopeDispose } from '@vueuse/shared'
55import { defu } from 'defu'
66import { computed , ref , shallowRef , toValue , watch } from 'vue'
7-
8- export { MediaRecorderPlugin } from './plugin'
7+ import { computedWithControl } from '@vueuse/core'
98
109interface UseMediaRecorderOptions extends ConfigurableNavigator {
1110 /**
@@ -20,13 +19,14 @@ interface UseMediaRecorderOptions extends ConfigurableNavigator {
2019
2120const defaultOptions : UseMediaRecorderOptions = {
2221 constraints : { audio : false , video : false } ,
23- mediaRecorderOptions : { } ,
22+ mediaRecorderOptions : { }
2423}
2524
2625export function useMediaRecorder ( options : UseMediaRecorderOptions = { } ) {
2726 const data = ref < Blob [ ] > ( [ ] )
2827 const mediaRecorder = shallowRef < MediaRecorder > ( )
2928 const stream = shallowRef < MediaStream > ( )
29+ const result = shallowRef < Blob [ ] > ( [ ] )
3030
3131 const isMimeTypeSupported = computed ( ( ) => {
3232 return toValue ( options . mediaRecorderOptions ) ?. mimeType ? MediaRecorder . isTypeSupported ( toValue ( options . mediaRecorderOptions ) ?. mimeType ?? '' ) : true
@@ -35,66 +35,67 @@ export function useMediaRecorder(options: UseMediaRecorderOptions = {}) {
3535 return ! ! navigator ?. mediaDevices ?. getUserMedia && isMimeTypeSupported . value
3636 } )
3737
38- const state = shallowRef < RecordingState | undefined > ( undefined )
38+ const state = computedWithControl < RecordingState | undefined > ( ( ) => mediaRecorder . value , ( ) => {
39+ return mediaRecorder . value ?. state
40+ } )
3941
40- const mimeType = shallowRef < string | undefined > ( undefined )
42+ const mimeType = computedWithControl < string | undefined > ( ( ) => mediaRecorder . value , ( ) => {
43+ return mediaRecorder . value ?. mimeType
44+ } )
4145
4246 const updateStates = ( ) => {
43- state . value = mediaRecorder . value ?. state
47+ state . trigger ( )
4448 }
4549
4650 const {
4751 mediaRecorderOptions,
48- constraints,
52+ constraints
4953 } = defu ( options , defaultOptions )
5054
5155 const start = async ( timeslice : number | undefined = undefined ) => {
5256 if ( state . value === 'recording' )
5357 return // todo warning?
58+ data . value = [ ]
5459 stream . value = await navigator ! . mediaDevices . getUserMedia ( toValue ( constraints ) )
5560 mediaRecorder . value = new MediaRecorder ( stream . value , toValue ( mediaRecorderOptions ) )
56- data . value = [ ]
5761 mediaRecorder . value ?. start ( timeslice )
58- updateStates ( )
59- }
60-
61- const reset = ( ) => {
62- stream . value ?. getTracks ( ) . forEach ( t => t . stop ( ) )
63- stream . value = undefined
64- mediaRecorder . value ?. stop ( )
6562 }
6663
6764 const stop = ( ) => {
6865 if ( ! state . value || state . value === 'inactive' )
6966 return // todo warning?
70- reset ( )
71- updateStates ( )
67+ mediaRecorder . value ?. stop ( )
7268 }
7369
7470 const pause = ( ) => {
7571 if ( state . value !== 'recording' )
7672 return // todo warning?
7773 mediaRecorder . value ?. pause ( )
78- updateStates ( )
7974 }
8075
8176 const resume = ( ) => {
8277 if ( state . value !== 'paused' )
8378 return // todo warning?
8479 mediaRecorder . value ?. resume ( )
85- updateStates ( )
8680 }
8781
8882 watch ( ( ) => mediaRecorder . value , ( newMediaRecorder ) => {
8983 if ( ! newMediaRecorder )
9084 return
9185 newMediaRecorder . ondataavailable = ( e ) => {
9286 const blob = e . data
93- if ( blob . type !== mimeType . value ) {
94- mimeType . value = blob . type ?? mediaRecorder . value ?. mimeType
95- }
87+ mimeType . trigger ( )
9688 data . value . push ( e . data )
9789 }
90+ newMediaRecorder . onstop = ( ) => {
91+ stream . value ?. getTracks ( ) . forEach ( t => t . stop ( ) )
92+ result . value = data . value
93+ updateStates ( )
94+ }
95+ newMediaRecorder . onpause = updateStates
96+ newMediaRecorder . onresume = updateStates
97+ newMediaRecorder . onstart = updateStates
98+ newMediaRecorder . onerror = updateStates
9899 } , { immediate : true } )
99100
100101 tryOnScopeDispose ( ( ) => {
@@ -112,7 +113,7 @@ export function useMediaRecorder(options: UseMediaRecorderOptions = {}) {
112113 isSupported,
113114 isMimeTypeSupported,
114115 mimeType : computed ( ( ) => mimeType . value ) ,
115- mediaRecorder : computed ( ( ) => mediaRecorder . value ) ,
116+ mediaRecorder : computed ( ( ) => mediaRecorder . value )
116117 }
117118}
118119
0 commit comments