-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Description
Muting in VoIP calls
This is my current stream of thoughts regarding muting in VoIP calls. The issue will be closed as soon as a better place for this appears (probably an MSC). Also, this is currently opened in element-web as it focuses on its implementation but it will be necessary to eventually expand the focus.
Problems of the current implementation
Clients may wish to inform the user of the opponent's mute state.
If a user mutes their camera, their opponent just sees a black screen, but the opponent's client may wish to show a placeholder instead (e.g. an avatar).
The current solution is to set MediaStreamTrack.enabled = false for the tracks we want to mute. This works but isn't ideal. There is no way for the opponent to know that a track is muted. This in itself isn't that big of a problem and could be solved by additional signalling. The big problem is even with the data being meaningless there is still significant bandwidth usage. This is a problem because a user might want to turn on their webcam for a moment causing a call upgrade to voice + video and then turn their camera back off. This would keep sending black frames which isn't completely awful but still uses some bandwidth.
Solutions
This lists three solutions to muting. Let's apply them to our use case.
removeTrack(sender)
We can rule this out because it requires re-negotiation which isn't desired
Disabling tracks
This is the current solution which has many problems. Additional signalling using m.cal.mute could be added (onmute events aren't fired when a track is disabled) but we still need to fix the bandwidth issue. Would it make sense to downgrade the call after some time for which the user had their camera turned off?
replaceTrack(null)
This solution seems to be the most promising. It should be theoretically supported in Firefox, Chromium and Safari, but some testing wouldn't be a bad idea. I am also very unsure how this translates to other platforms. If this really worked we need to find out if the other side can see the mute state using onmute events on MediaStreamTrack. If not we would still need mute events (m.call.mute).