Skip to content

Commit f92e4ed

Browse files
author
timmydoza
authored
Do not clone MediaStreamTrack in Chrome (#713)
1 parent d4c418c commit f92e4ed

File tree

1 file changed

+11
-4
lines changed

1 file changed

+11
-4
lines changed

src/components/AudioLevelIndicator/AudioLevelIndicator.tsx

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ export function initializeAnalyser(stream: MediaStream) {
3131
return analyser;
3232
}
3333

34+
const isIOS = /iPhone|iPad/.test(navigator.userAgent);
35+
3436
function 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

Comments
 (0)