[mediacapture-main] When an HTMLMediaElement has srcObject set to a MediaStream where the MediaStreamTrack is muted the HTMLMediaElement muted attribute should be set to muted to reflect muted input and muted output (#583)

guest271314 has just created a new issue for https://github.com/w3c/mediacapture-main:

== When an HTMLMediaElement has srcObject set to a MediaStream where the MediaStreamTrack is muted the HTMLMediaElement muted attribute should be set to muted to reflect muted input and muted output ==
The relevant specifications 

https://w3c.github.io/mediacapture-main/#media-flow

> **Media Flow**
> 
> There are two dimensions related to the media flow for a live MediaStreamTrack : muted / not muted, and enabled / disabled.
> 
> Muted refers to the input to the MediaStreamTrack. If live samples are not made available to the MediaStreamTrack it is muted.
> 
> Muted is out of control for the application, but can be observed by the application by reading the muted attribute and listening to the associated events mute and unmute. There can be several reasons for a MediaStreamTrack to be muted: the user pushing a physical mute button on the microphone, **the user toggling a control in the operating system** (emphasis added), the user clicking a mute button in the browser chrome, the User Agent (on behalf of the user) mutes, etc.
> 
> Whenever the User Agent initiates such a change, it MUST queue a task, using the user interaction task source, to set a track's muted state to the state desired by the user.
> 
> To set a track's muted state to newState, the User Agent MUST run the following steps:
> 
> 1. Let track be the MediaStreamTrack in question.
> 
> 2. Set track's muted attribute to newState.
> 
> 3. If newState is true let eventName be mute, otherwise unmute.
> 
> 4. Fire a simple event named eventName on track.

https://html.spec.whatwg.org/multipage/media.html#dom-media-muted

> A media element can also be muted. If anything is muting the element, then it is muted. (For example, when the direction of playback is backwards, the element is muted.)
> 
> The muted IDL attribute must return the value to which it was last set. When a media element is created, if the element has a muted content attribute specified, then the muted IDL attribute should be set to true; otherwise, the user agents may set the value to the user's preferred value (e.g. remembering the last set value across sessions, on a per-site basis or otherwise). While the muted IDL attribute is set to true, the media element must be muted.
> 
> Whenever either of the values that would be returned by the volume and muted IDL attributes change, the user agent must queue a task to fire an event named volumechange at the media element. Then, if the media element is not allowed to play, the user agent must run the internal pause steps for the media element.
> 
> An element's effective media volume is determined as follows:
> 
> 1. If the user has indicated that the user agent is to override the volume of the element, then return the volume desired by the user.
> 
> 2. If the element's audio output is muted, then return zero.
> 
> 3. Let volume be the playback volume of the audio portions of the media element, in range 0.0 (silent) to 1.0 (loudest).
> 
> 4. Return volume, interpreted relative to the range 0.0 to 1.0, with 0.0 being silent, and 1.0 being the loudest setting, values in between increasing in loudness. The range need not be linear. The loudest setting may be lower than the system's loudest possible setting; for example the user could have set a maximum volume.
> 
> The muted content attribute on media elements is a boolean attribute that controls the default state of the audio output of the media resource, potentially overriding user preferences.
> 
> The defaultMuted IDL attribute must reflect the muted content attribute.

Consider this question Check if selected microphone is muted or not with web audio api https://stackoverflow.com/q/41309682

> By using the following, we can prompt the user to select their preferred media input device with audio and video source constraints (currently only interested in Chrome support).
> 
> ```
> navigator.mediaDevices.getUserMedia({audio: true})
>   .then((stream) => {
>     console.log(stream);
>   });
> ```
> Anyone know if there is an exposed API to detect if the user-selected input device is currently muted or not? The input device would be either an onboard microphone, external mic, or software defined microphone that shows in the system as a hardware device.
> 
> 

and these comments

> Tray refers to the Windows tray area where the sound settings are available via context menu on the sound icon. I used the demo available [here](https://www.webrtc-experiment.com/RecordRTC/) to validate that no sound is recorded when the device is muted but it still doesn't appear that the muted property of the device (at least when done through the OS recording device settings) is reflected in the `muted` property of the stream. FYI the MediaCapture and Stream Spec backs you up, so this might just be a bug or some problem of mine. – Chris Hunt Dec 24 '16 at 3:00 

<p>

> Have anybody managed to find the solution? – Jakub yesterday

and code

```
<!DOCTYPE html>
<html>
  <head>
    <title>Test muted property of MediaStreamTrack and muted attribute of HTMLMediaElement with the user toggling a control in the operating system</title>
  </head>
  <body>
    <button>start</button>
    <button>stop</button><br>
    <audio controls autoplay muted="false"></audio>
    <script>
      (async () => {
        const [start, stop] = document.querySelectorAll("button");
        const audio = document.querySelector("audio");
        try {
          console.log(audio.audioTracks);
        } catch (e) {
          console.error(e);
        }
        audio.onvolumechange = e => console.log(e, {
          HTMLMediaElementMuted: audio.muted,
          volume: e.target.volume
        });
        let mediaStream, mediaStreamTrack;
        start.onclick = async e => {
          try {
            mediaStream = await navigator.mediaDevices.getUserMedia({
              audio: true
            });
            audio.srcObject = mediaStream;
            [mediaStreamTrack] = mediaStream.getAudioTracks();
            mediaStreamTrack.onmute = e => console.log(e, {
              MediaStreamTrackMuted: e.target.muted,
              HTMLAudioElementMuted: audio.muted
            });
            mediaStreamTrack.onunmute = e => console.log(e, {
              MediaStreamTrackMuted: e.target.muted,
              HTMLAudioElementMuted: audio.muted
            });
            mediaStreamTrack.onended = e => console.log(e, {
              MediaStreamTrackMuted: e.target.muted,
              HTMLAudioElementMuted: audio.muted
            });
          } catch (e) {
            console.error(e);
          }
        }
        stop.onclick = e => {
          mediaStreamTrack.enabled = false;
          mediaStreamTrack.stop();
          console.log({
              MediaStreamTrackMuted: e.target.muted,
              HTMLAudioElementMuted: audio.muted
            });
        }
      })();

    </script>
  </body>
</html>


```to test the result of setting mute and unmute by means of  

> **the user toggling a control in the operating system**

To test 

1. Open OS sound settings for Input Devices
2. Run the code
3. Toggle mute and unmute Input Device (microphone)

Results:

- Chromium 73 dispatches `mute` and `unmute` event at `MediaStreamTrack` target when toggling the mute and unmute control of input device (microphone) of the operating system
- Firefox 68 does not dispatch  `mute` and `unmute` event at `MediaStreamTrack` target when toggling the mute and unmute control of input device (microphone) of the operating system
- `HTMLMediaElement` with `srcObject` set to `MediaStream` `muted` attribute does not toggle between `true` and `false` when the Input Device (microphone) is muted with the user toggling a control in the operating system

Expected result and what the HTML Standard and Media Capture and Streams specifications should state:

The specifications should clarify that `muted` event MUST be fired at `MediaStreamTrack` when the user toggling a control in the operating system AND if the `MediaStreamTrack` that is muted by the user toggling a control in the operating system is set as a `MediaStreamTrack` at a `MediaStream` instance set as `srcObject` of an `HTMLMediaElement` the `muted` attribute MUST reflect the same value as the underlying media resource `MediaStreamTrack`.

Please view or discuss this issue at https://github.com/w3c/mediacapture-main/issues/583 using your GitHub account

Received on Wednesday, 1 May 2019 05:37:33 UTC