Original link: https://paugram.com/coding/media-stream-audio-track-clone-bug.html
The company’s project uses the SoundNet SDK to implement voice calls, but after other colleagues connected to another function, it was found that after disconnecting the microphone to end the call, the browser window displayed a “small red dot”, still occupying the microphone. This can easily lead customers to think that we are continuing to “listen” to him and affect the user experience. This is a bug that has been around for a long time, and no one has found the specific cause, but today, I finally have a new discovery! View the full diary
I plan to use the browser’s native method to implement a function that obtains the microphone source and uses the player to play it in real time, simply simulating the process of using the microphone and eliminating the occupation. If you can successfully reproduce the same “small red dot” occupation effect in this minimal code example, you need to check whether the corresponding library has code that causes this problem.
Use navigator.mediaDevices.getUserMedia()
to get the source, and then use the getAudioTracks()
method to successfully get the track of the microphone. According to the source code of the company project, this track should be copied to another source .
const stream = await navigator.mediaDevices.getUserMedia(constraints); let newStream = new MediaStream(); const audioTracks = stream.getAudioTracks(); audioTracks.forEach(item => { newStream.addTrack(item); });
If you want the window corresponding to the browser to stop occupying the microphone, you need to stop the track’s real-time acquisition of the microphone sound. This can be achieved by using the stop()
method of MediaStreamTrack, and the “little red dot” on my browser has indeed disappeared after execution.
const newStreamTracks = newStream.getTracks(); newStreamTracks.forEach(item => { // 只要stop 理论上就会停止占用麦克风设备了item.stop(); });
During this period, by using MDN to query the document, I found that MediaStreamTrack has a method called clone
, which will return the copied track object. The main visible change is to replace its id
.
I tried to apply it to my code , and then planned to stop occupying it. As a result, the “little red dot” did not disappear and was always occupied.
audioTracks.forEach(item => { // newStream.addTrack(item); // ! 只要使用clone 方法,就会导致stop 流时,浏览器依旧显示小红点(麦克风设备使用中) newStream.addTrack(item.clone()); });
After Google, I found that there seems to be a similar problem , which belongs to the bug of the browser kernel. But Paul was still relatively simple, so he did not continue his research on this issue.
This has already made a lot of discoveries. Next, we need to check whether a third-party library executes similar code. In addition to the sound network, our project also uses another service, and also needs to refer to the microphone source used by the current user.
After replacing the microphone source returned by the SoundNet SDK with its built-in method (the first microphone source will be returned, if you have multiple microphones, another bug with the wrong microphone source will be triggered), the “little red dot” does not appear. Always show the situation. So basically it can be confirmed that the track returned by Shengwang SDK may have been clone
, causing the “small red dot” to always be displayed. The source code of the SDK is closed source, but I also found a similar clone
method from the compressed and obfuscated code. I think the above so many differential tests are enough to explain the problem. I will not explore the specific situation inside the SDK code.
Know the cause of the problem, but there is no good solution. Next, I may submit a ticket to Shengwang on this issue and see their reply. One thing to say, it is quite a sense of achievement to solve such a difficult disease for the first time!
This article is reproduced from: https://paugram.com/coding/media-stream-audio-track-clone-bug.html
This site is for inclusion only, and the copyright belongs to the original author.