Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disconnecting media element from MediaElementAudioSourceNode #1202

Closed
rtoy opened this issue Apr 12, 2017 · 4 comments
Closed

Disconnecting media element from MediaElementAudioSourceNode #1202

rtoy opened this issue Apr 12, 2017 · 4 comments

Comments

@rtoy
Copy link
Member

rtoy commented Apr 12, 2017

Currently, once you create a MediaElementAudioSourceNode all audio from the media element is sent to this node. But what if I'm done with this routing? Currently there's no way to break this connection. Waiting for GC to collect the media node and undoing the routing is a terrible way because you're not in control of when that happens.

There should be a way to break this connection, perhaps by adding a new detach (name TBD) method or allowing the user to set the mediaElement attribute to null. (I prefer a new method.)

The same issue applies to a MediaStreamAudioSourceNode.

@padenot
Copy link
Member

padenot commented Oct 25, 2018

Using HTMLMediaElement.captureStream(), feeding that to a MediaStreamAudioSourceNode, and setting HTMLMediaElement.muted to true replicates MediaElementAudioSourceNode, while being more flexible: disconnecting/reconnecting the HTMLMediaElement is possible.

In light of this, I'm closing this issue.

@WofWca
Copy link

WofWca commented Oct 7, 2021

But what if we want the user to be able to control the volume of the media? Are we forced to proxy the existing volume controlling code to a GainNode? It would be even harder if we're making a browser extension that aims to work on several websites.

@WofWca
Copy link

WofWca commented Oct 7, 2021

As far as I can tell, the workaround @padenot mentioned doesn't work in Chromium due to an incorrect implementation: https://bugs.chromium.org/p/chromium/issues/detail?id=1136404

https://w3c.github.io/mediacapture-fromelement/#dom-htmlmediaelement-capturestream says:

Muting the audio on a media element does not cause the capture to produce silence

Try el.volume = 0.00001 instead of el.muted = true.

@WofWca
Copy link

WofWca commented Oct 9, 2021

I came up with a different workaround where you don't have problems with el.volume, but the downside is that you still have to use createMediaElementSource, therefore e.g. have no way of making the element play sound again if the source is cross-origin.

Instead of el.muted = true you createMediaElementSource and connect it to a GainNode with gain.value = 0. Then, to emulate disconnect you can set the gain back to 1, which for your application may be kind of the same as reverting createMediaElementSource. In order to control the volume you can just copy the value of el.volume to another GainNode. In other words:

context = new AudioContext();

elementSource = context.createMediaElementSource(el);
togglingGain = context.createGain();
togglingGain.gain.value = 0;
elementSource
  .connect(togglingGain)
  .connect(context.destination)
;
// Do this is you want to detach
myDetachMediaElement = () => {
  togglingGain.gain.value = 1;
}

streamSource = context.createMediaStreamSource(el.captureStream());
elementVolumeReplicatingGain = context.createGain();
streamSource.connect(elementVolumeReplicatingGain);
elementVolumeReplicatingGain.gain.value = el.volume;
el.addEventListener('volumechange', () => {
  elementVolumeReplicatingGain.gain.value = el.volume;
});

// Then use `elementVolumeReplicatingGain` instead of `elementSource` for your applications.
elementVolumeReplicatingGain.connect(context.destination); // For example

But createMediaStreamSource is still different from createMediaElementSource in other ways - for example, createMediaStreamSource would throw if the media element doesn't have its currentSrc set (yet), which is, again, not very god especially in context of browser extensions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
No open projects
Development

No branches or pull requests

5 participants