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

addtrack and removetrack events only fire when user agent updates stream #517

Closed
leahciMic opened this issue May 1, 2018 · 2 comments
Closed
Assignees
Labels

Comments

@leahciMic
Copy link

Currently we already have a addtrack and a removetrack event on a MediaStream. These events are only fired when the user agent changes what is contained inside the stream, and does not fire when a script adds, or removes a track from a stream.

Currently if a script is passed in a MediaStream there is no good method of being notified when the tracks are changed without: a) polling, b) overriding the addtrack, and removetrack methods, both which are undesirable.

What is the rational of not firing these events when addTrack and removeTrack are called by a script? I understand that if you produced the MediaStream and you called addTrack, that you are aware that this is happening, but it's not always the case that your script owns the MediaStream and is aware of what is happening to it.

Could we add some sort of isExternal flag (not sure on the naming here) to the MediaStreamTrackEvent that could indicate that this came from the useragent and fire addtrack and removetrack every time the stream is modified regardless of where the modifications came from?

Consider the following:

// stream is passed in to our API, and we want to monitor the tracks.
function processStream(stream) {
  const tracks = stream.getTracks();
  stream.addEventListener('addtrack', ({ track }) => tracks.push(track));
  stream.addEventListener('removetrack', ({ track }) => tracks.splice(tracks.indexOf(track), 1));
}

It would be really nice if tracks would be kept in sync with the actual tracks of the stream. But currently this is not the case.

Perhaps the addtrack and removetrack definition cannot be changed from what it is, without it affecting existing code. In this case, would it be possible to have yet another event? Perhaps a updatetracks event or something similar.

FWIW I'm completely open to the method/terminology used to provide this. I'm not fussed what it is called, or how it works, as long as there is a way to be notified when the track list is updated regardless of what did the updating.

Sorry if this is not the right place to post this sort of question, but I'm not sure where else to do so.

@adam-be
Copy link
Member

adam-be commented May 24, 2018

To answer your last question first; this is indeed the right place to ask this kind of question. :)

The rationale for not firing the events when API modifies the tracks of a MediaStream is that those operations are synchronous. I.e., after adding a track, you can check on the next line that the new track is in place. The purpose of the events are notify the script that something has happened asynchronously, and the first time the new change will be visible (the track addition or removal) is in the event handler as the change is done synchronously with the event being fired.

We don't fire events with synchronous API since the script can detect it anyhow, as you describe above, and that it can cause strange behavior. For example that the event notifies about something that is no longer true, since the "change" has already happened and is not done in sync with the event firing. For example, by the time the firing of an addtrack event is picked up the main thread, the track could have been removed by the script or some other queued task.

I think you're case when the script doesn't own the MediaStream is special, and therefore requires some special handling in code.

@aboba aboba assigned jan-ivar and unassigned adam-be Aug 22, 2019
@jan-ivar
Copy link
Member

jan-ivar commented Nov 14, 2019

I'm closing this question as answered. For better or worse, this is the API we've designed, and there's no web compatible way to change it at this point.

As Adam explains, to fire an event from a synchronous change method, would require us either to fire the event synchronously before the method returns, re-entering JavaScript, which is not POLA, or fire the event later, after the change has happened, a semantic break with guarantees today's event handlers enjoy (the added track may have since been removed and vice versa).

Adding a new event fails the "minimal API" test, and is easily done in a polyfill, which seems appropriate since it seems that mostly libraries would need this anyway.

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

No branches or pull requests

3 participants