@@ -89,21 +89,31 @@ const LiveAudioVisualizer: (props: Props) => ReactElement = ({
89
89
minDecibels = - 90 ,
90
90
smoothingTimeConstant = 0.4 ,
91
91
} : Props ) => {
92
- const [ context ] = useState ( ( ) => new AudioContext ( ) ) ;
92
+ const [ context , setContext ] = useState < AudioContext > ( ) ;
93
+ const [ audioSource , setAudioSource ] = useState < MediaStreamAudioSourceNode > ( ) ;
93
94
const [ analyser , setAnalyser ] = useState < AnalyserNode > ( ) ;
94
95
const canvasRef = useRef < HTMLCanvasElement > ( null ) ;
95
96
96
97
useEffect ( ( ) => {
97
98
if ( ! mediaRecorder . stream ) return ;
98
99
99
- const analyserNode = context . createAnalyser ( ) ;
100
+ const ctx = new AudioContext ( ) ;
101
+ const analyserNode = ctx . createAnalyser ( ) ;
100
102
setAnalyser ( analyserNode ) ;
101
103
analyserNode . fftSize = fftSize ;
102
104
analyserNode . minDecibels = minDecibels ;
103
105
analyserNode . maxDecibels = maxDecibels ;
104
106
analyserNode . smoothingTimeConstant = smoothingTimeConstant ;
105
- const source = context . createMediaStreamSource ( mediaRecorder . stream ) ;
107
+ const source = ctx . createMediaStreamSource ( mediaRecorder . stream ) ;
106
108
source . connect ( analyserNode ) ;
109
+ setContext ( ctx ) ;
110
+ setAudioSource ( source ) ;
111
+
112
+ return ( ) => {
113
+ source . disconnect ( ) ;
114
+ analyserNode . disconnect ( ) ;
115
+ ctx . state !== "closed" && ctx . close ( ) ;
116
+ } ;
107
117
} , [ mediaRecorder . stream ] ) ;
108
118
109
119
useEffect ( ( ) => {
@@ -113,7 +123,7 @@ const LiveAudioVisualizer: (props: Props) => ReactElement = ({
113
123
} , [ analyser , mediaRecorder . state ] ) ;
114
124
115
125
const report = useCallback ( ( ) => {
116
- if ( ! analyser ) return ;
126
+ if ( ! analyser || ! context ) return ;
117
127
118
128
const data = new Uint8Array ( analyser ?. frequencyBinCount ) ;
119
129
@@ -129,14 +139,16 @@ const LiveAudioVisualizer: (props: Props) => ReactElement = ({
129
139
) {
130
140
context . close ( ) ;
131
141
}
132
- } , [ analyser , context . state ] ) ;
142
+ } , [ analyser , context ? .state ] ) ;
133
143
134
144
useEffect ( ( ) => {
135
145
return ( ) => {
136
- if ( context . state !== "closed" ) {
146
+ if ( context && context . state !== "closed" ) {
137
147
context . close ( ) ;
138
148
}
139
- }
149
+ audioSource ?. disconnect ( ) ;
150
+ analyser ?. disconnect ( ) ;
151
+ } ;
140
152
} , [ ] ) ;
141
153
142
154
const processFrequencyData = ( data : Uint8Array ) : void => {
0 commit comments