@@ -31,6 +31,8 @@ export function initializeAnalyser(stream: MediaStream) {
3131 return analyser ;
3232}
3333
34+ const isIOS = / i P h o n e | i P a d / . test ( navigator . userAgent ) ;
35+
3436function AudioLevelIndicator ( { audioTrack, color = 'white' } : { audioTrack ?: AudioTrack ; color ?: string } ) {
3537 const SVGRectRef = useRef < SVGRectElement > ( null ) ;
3638 const [ analyser , setAnalyser ] = useState < AnalyserNode > ( ) ;
@@ -41,22 +43,27 @@ function AudioLevelIndicator({ audioTrack, color = 'white' }: { audioTrack?: Aud
4143 if ( audioTrack && mediaStreamTrack && isTrackEnabled ) {
4244 // Here we create a new MediaStream from a clone of the mediaStreamTrack.
4345 // A clone is created to allow multiple instances of this component for a single
44- // AudioTrack on iOS Safari.
45- let newMediaStream = new MediaStream ( [ mediaStreamTrack . clone ( ) ] ) ;
46+ // AudioTrack on iOS Safari. We only clone the mediaStreamTrack on iOS.
47+ let newMediaStream = new MediaStream ( [ isIOS ? mediaStreamTrack . clone ( ) : mediaStreamTrack ] ) ;
4648
4749 // Here we listen for the 'stopped' event on the audioTrack. When the audioTrack is stopped,
4850 // we stop the cloned track that is stored in 'newMediaStream'. It is important that we stop
4951 // all tracks when they are not in use. Browsers like Firefox don't let you create a new stream
5052 // from a new audio device while the active audio device still has active tracks.
5153 const stopAllMediaStreamTracks = ( ) => {
52- newMediaStream . getTracks ( ) . forEach ( track => track . stop ( ) ) ;
54+ if ( isIOS ) {
55+ // If we are on iOS, then we want to stop the MediaStreamTrack that we have previously cloned.
56+ // If we are not on iOS, then we do not stop the MediaStreamTrack since it is the original and still in use.
57+ newMediaStream . getTracks ( ) . forEach ( track => track . stop ( ) ) ;
58+ }
5359 newMediaStream . dispatchEvent ( new Event ( 'cleanup' ) ) ; // Stop the audioContext
5460 } ;
5561 audioTrack . on ( 'stopped' , stopAllMediaStreamTracks ) ;
5662
5763 const reinitializeAnalyser = ( ) => {
5864 stopAllMediaStreamTracks ( ) ;
59- newMediaStream = new MediaStream ( [ mediaStreamTrack . clone ( ) ] ) ;
65+ // We only clone the mediaStreamTrack on iOS.
66+ newMediaStream = new MediaStream ( [ isIOS ? mediaStreamTrack . clone ( ) : mediaStreamTrack ] ) ;
6067 setAnalyser ( initializeAnalyser ( newMediaStream ) ) ;
6168 } ;
6269
0 commit comments