Re: Simplify the new addTrack() API

On 02/10/2015 10:54 AM, Adam Bergkvist wrote:
> On 10/02/15 08:09, Harald Alvestrand wrote:
>> On 02/09/2015 03:26 PM, Adam Bergkvist wrote:
>>> Hi
>>>
>>> With the introduction of RTCRtpSender/Receiver (Doohickeys), the way to
>>> send and receive media will change. We used to add a MediaStream at one
>>> end, and dispatch a corresponding stream at the other end.
>>>
>>> The new addTrack()-based approach is to add one MediaStreamTrack and
>>> zero or more MediaStreams, containing the track, at one end, and
>>> dispatch a RTCRtpReceiver, the corresponding track and a list of
>>> MediaStreams, containting the track, at the other end. This implies
>>> creating a new stream if a certain stream isn't represented at the other
>>> side, or no stream was supplied for a track, and keeping handles to
>>> previously created streams to be able to add future tracks to them.
>>>
>>> Even though the API call is named addTrack(), MediaStreams are very much
>>> involved with increased complexity as the cost. One reason for this is
>>> the need to polyfill the old addStream()-API on top of the new.
>> This is a common thing to have to do, whether it's done as part of
>> implementing the spec or as part of making the spec usable for people
>> who are used to the "previous style".
>>
>> These days, it seems common to write new APIs first as polyfills and
>> then embed the polyfill (still in Javascript) inside the browser through
>> an API-embedding mechanism and call it "platform implementation" - I
>> hear this is done for the Chrome Promises API, for instance.
>>
>>> A different approach could be to keep the new addTrack()-API simple and
>>> provide the API points needed to polyfill or implement advanced stream
>>> handling in the application. For example:
>>>
>>> addTrack(MST track, optional DOMString tag);
>>>
>>> - The optional tag argument is a string that is signalled in SDP that
>>> contains application specific info. For example, a list of MediaStream
>>> ids.
>> I take it you're assuming that the app would have to know from
>> non-standard sources what the tag was supposed to mean?
> Yes.
>
>> If it's going to support the previous addStream() API in the way the
>> currently proposed addTrack() does, with multiple streams created, it
>> would have to be either a sequence of DOMStrings or a tag with internal
>> syntax <ugh>.
> A list of tags wold work as well, even though it's quite easy to split
> strings in JavaScript. I believe the support for multiple streams is
> introduced with the new addTrack() API and it's not really needed to
> polyfill the old addStream() API. The tracks belong solely to the
> MediaStream indicated by the argument to addStream().

I think the multi-stream support was intended to support what in the old 
API would have been:

stream1.addTrack(x)
stream2.addTrack(x)
pc.addStream(stream1)
pc.addStream(stream2)

In the new API, this would be:

stream1.addTrack(x)
stream2.addTrack(x)
pc.addTrack(x, [stream1, stream2])

although I don't quite understand why it shouldn't be

pc.addTrack(x, stream1)
pc.addTrack(x, stream2)

instead (we would have to allow adding the same track twice in that case).

>
>>>     The corresponding event would expose the string the other side.
>>>
>>> (Constructor) MediaStream(DOMString id);
>>>
>>> - Construct a stream with a given id.
>>>
>>> Feedback and suggestions are welcome.
>> As an experiment, I'd suggest writing up the polyfill that would give
>> the old addstream API on top of the proposed API and see where the
>> disconnects (if any) are.
> Here's one version:
>
> // addStream() (sending side)
> function addStreamPolyfilled(stream) {
>       var tracks = stream.getTracks();
>       tracks.forEach(function (track) {
>           // include info in tag to rebuild stream
>           pc.addTrack(track, tracks.length + "," + stream.id);
>       });
> }
>
> // "addstream" event (receiver side)
> pc.ontrack = function (evt) {
>       var tags = evt.tag.split(",");
>       var trackCount = parseInt(tags[0]);
>       var streamId = tags[1];
>
>       var stream = privateStreamHandles[streamId] ||
>           new MediaStream(streamId);
>       stream.addTrack(evt.track);
>
>       // dispatch when we have rebuilt the entire stream
>       if (stream.getTracks().length == trackCount)
>           dispatchAddStreamEvent(stream);
> };
>
> Regarding polyfilling the addStream() API, the more advanced addTrack()
> (with MediaStreams) do create the MediaStream(s) for you, but when
> should you dispatch the addstream event?
>
> /Adam
>

Received on Tuesday, 10 February 2015 11:41:34 UTC