Closed Bug 1614657 Opened 2 years ago Closed 2 years ago

Missing webrtc track ended event when unplugging the device and having multiple devices connected

Categories

(Core :: WebRTC: Audio/Video, defect, P1)

72 Branch
Unspecified
All
defect

Tracking

()

VERIFIED FIXED
mozilla75
Tracking Status
firefox75 --- verified

People

(Reporter: jan, Assigned: achronop)

References

Details

Attachments

(1 file)

User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:73.0) Gecko/20100101 Firefox/73.0

Steps to reproduce:

Have at least two cameras (with microphone) connected to a windows 10 system using ff 72,73 or 74.

get an audio/video stream using getUserMedia

Add an event handler for the ended event.
localStream.getTracks().forEach(t => t.onended = () => console.error(t.kind, "ended"));

Unplug, disconnect the camera you have been using for the getUserMedia.


jib made a reference implementation here:
https://jsfiddle.net/jib1/LbtxeLvw/
Follow the steps mentioned above, take a look at the output.


Side note:
Looks like the microphone affects the behaviour. If you choose audio and video from different devices and you unplug the video device the event is fired. If you unplug the audio device no event is fired at all.

Actual results:

No event is fired if more than the acutally used camera is connected. if only the used camera is connected an audio and video ended event is fired.

Expected results:

Would expect the event every time (no matter how many devices are connected)

NI to myslef to check it.

Flags: needinfo?(achronop)

Confirmed on Windows 10 in FF 70.0.2. Both video and audio track ended events are missing. Only repros with the second device in the list.

It also reproduces with mics only, whereas it doesn't reproduce with video only.

Mic-only STRs:

  1. Make sure two 2 USB mic-ed cameras are attached (mine are Logitech BRIO & Microsoft® LifeCam HD-3000)
  2. Open https://jsfiddle.net/jib1/LbtxeLvw/77
  3. Click Start Microphone!
  4. Select the second mic ("Microphone (Logitech BRIO)" in my case), and click "Allow".
  5. Pull out the USB cord of that device.

Expected result:

Microphone (live): Microphone (Logitech BRIO)
audio track ended
devicechange!
Microphone (ended): Microphone (Logitech BRIO)

Actual result:

Microphone (live): Microphone (Logitech BRIO)
devicechange!
Microphone (live): Microphone (Logitech BRIO)

Bonus step: 6. Pull out the USB cord of the remaining device.
Now I get

audio track ended

...even though I never selected that device.

Status: UNCONFIRMED → NEW
Component: Untriaged → WebRTC: Audio/Video
Ever confirmed: true
OS: Unspecified → Windows 10
Priority: -- → P2
Product: Firefox → Core
Version: 74 Branch → 72 Branch

I am testing on Linux and I am getting the following strange behavior. Restart the browser, just one camera with mic is connected. I execute the scenario from comment 2 (without caring about a second USB device) and the error reproduces. Then I click Run in jsfiddle, I re-run the test and the problem is gone. Then I refresh the page, I re-run it again and the problem is still gone. If I add a second mic does not change anything. The problem does not reproduce anymore.

Flags: needinfo?(achronop)
Depends on: 1616086

In MediaManager::DeviceListChanged() we check if a device is removed in order to stop it. That eventually will send the end track event. The logic there relies on the devices stored in mDeviceIDs. In the case of solo-microphone or solo-camera gUM the mDevicesIDs is empty on the first DeviceListChanged event so the check fails and the source track is never stopped. At the end of DeviceListChanged the mDeviceIDs is updated thus the logic works on the following unplugs.

Before that, the mDeviceIDs is set as a part of gUM execution in MediaManager::EnumerateDevicesImpl. However, the outer if statement does not look flexible enough. If we have camera only or microphone only the if check fails and the mDeviceIDs is not set at all. Thus the source track is not being stopped later, on the first unplug, and we are missing the end track event.

Assignee: nobody → achronop
Priority: P2 → P1

In MediaManager::DeviceListChanged() we check if a device is removed in order to stop it. That eventually will send the end track event. For doing that correctly the mDeviceIDs must be up to date. The mDeviceIDs is set as a part of gUM execution in MediaManager::EnumerateDevicesImpl inside an if-check. However, having the if-check is not necessary anymore. First, because the device ids do not contain anymore the "default:" prefix and second because there is no real reason to differentiate real from fake devices. In addition to that the if check had an error and did not update the mDeviceIDs correctly on video-only or audio-only gUM requests.

OS: Windows 10 → All
Pushed by achronopoulos@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/b5c695734ba5
Update the device list unconditionally on every gUM request. r=jib
Status: NEW → RESOLVED
Closed: 2 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla75

Tentative QE+.

Flags: qe-verify+

Reproduced the initial issue using Fx 72.0 on Ubuntu 18.04 64bit, I could verify that the correct output is thrown using Fx75.0b8 across platforms (Ubuntu 18.04 64bit, Windows 10 64bit and macOS 10.15). Thanks Alex for the help!

Status: RESOLVED → VERIFIED
See Also: → 1628639
You need to log in before you can comment on or make changes to this bug.