Re: Track cloning behavior of MediaStream() constructor and addTrack()

I like this proposal,

it makes it possible to select whether you clone a track, or just 
include the existing one in another MediaStream.

Also, if you clone using track.clone, than you'd automatically know what 
tracks are related (i.e. use the same source) and not need to detour via 
SourceId to find out the relations.

Personally I think we could even consider to simplify the MediaStream 
constructor so that it would not take any arguments but just create an 
empty MediaStream. You'd then have to use "addTrack" to add tracks to it.

Stefan

On 2013-03-18 15:47, Adam Bergkvist wrote:
> Hi
>
> As the spec is currently written, the MediaStream() constructor and the
> addTrack() method create a new MediaStreamTrack instance to represent a
> given track argument. Some of the changes we done lately, like removed
> the ordered track list attributes, have made this API harder to work with.
>
> Independent track instances (or clones) are useful to control the output
> to different consumers. In the case below, the self-view will show video
> but the video to the other peer is disabled.
>
> var peerStream = new MediaStream(selfViewStream); // clone the stream
> pc.addStream(peerStream);
> peerStream.getVideoTracks()[0].enabled = false;
> selfViewStream.getVideoTracks()[0].enabled = true;
>
> However, the cloning behavior of MediaStream() and addTrack() causes
> some unintuitive API behavior. For example, if we do:
>
> stream.addTrack(track);
>
> Then the following calls won't behave as one might expect.
>
> stream.getTrackbyId(track.id); // is null
> stream.removeTrack(track); // is a no-op and won't remove track from
>                             // stream
>
> The instance track is not a part of stream and the new track instance
> has a different id. This may also cause confustion if one tries to use
> the track reference passed to addTrack() to influence the output of
> stream (example below).
>
> stream.addTrack(track); // as above
> pc.addStream(stream);
> track.enabled = false; // won't disable the output of any track in
>                         // stream
>
> If we take the proposed approach for sync getUserMedia() as an example.
>
> var video1 = new VideoStreamTrack(constraints1);
> var video2 = new VideoStreamTrack(constraints2);
> var stream = new MediaStream([video1, video2]);
>
> The instances video1 and video2 are pretty much useless since new track
> instances are created when the stream is constructed. It's also not
> obvious which video tracks in stream that correspond to video1 and
> video2, since the track order is undefined. The proposed sourceId would
> make the pairing easier, as long as we keep the restriction that only
> one track can represent a source in a MediaStream.
>
> I think the API would be more intuitive if MediaStream() and addTrack()
> "adopted" the track arguments instead of cloned them. Cloning would then
> be an explicit operation.
>
> To still support cloning, we could either support cloning of both tracks
> and streams or simply only tracks.
>
> var clonedStream = stream.clone();
>
> A stream clone can be created by adding cloned tracks to a new stream.
>
> var tracks = stream.getAudioTracks().concat(stream.getVideoTracks());
> var trackClones = tracks.map(function (track) {
>      return track.clone();
> });
> var streamClone = new MediaStream(trackClones);
>
> What do people think about this?
>
> BR
> Adam
>

Received on Tuesday, 19 March 2013 08:30:59 UTC