80 likes | 145 Views
This proposal discusses solutions for negotiating streams with MediaStreams and MediaStreamTracks only after user consent. Options include placeholders, event handling, wrappers, and stream instantiation.
E N D
a synchronous choice getUserMedia options
Problem • RTCPeerConnection requires MediaStreams (and MediaStreamTracks) in order to negotiate streams • MediaStreams can currently only exist when the user has provided consent • This leads to a problem where negotiation can’t continue without consent, which leads to clipping on answer
Proposed Solution (Common) • Provide placeholder MediaStreams that can be used as a basis for negotiation • The object is real, but unconnected or disabled somehow prior to the user providing consent • The SSRCs that can be generated are stable [sic] • Negotiation can continue prior to consent being granted using the placeholder
Option 1 • getUserMedia returns streams that do not start until consent is granted. var stream = navigator.getUserMedia(constraints);stream.audioTracks[0].onstart = grantedCb;stream.audioTracks[0].onend = deniedCb;pc.addStream(stream); • Consent events are communicated on the tracks • A new started event is added to tracks. • The reasons for the end event are expanded to include all the error conditions for getUserMedia: • nodevice, permissiondenied, deviceerror
Option 2 • As option 1, except the return value is a wrapper: varstreamBucket = navigator.getUserMedia(constraints);streamBucket.onsuccess = grantedCb;streamBucket.onfailure = deniedCb;pc.addStream(streamBucket.stream); • Returned tracks are ‘muted’ until consent is granted • Extra arguments to gUM create a signature that is identical in usage to existing asynchronous gUM • also possible with Option 1
Option 3 • Stream placeholders are instantiated and “connected” to devices by getUserMedia varaudioTrack = new AudioMediaStreamTrack(constraints);var stream = new MediaStream(audioTrack);navigator.getUserMedia(stream, grantedCb, deniedCb);pc.addStream(stream); • Constraints are attached directly to tracks • Nascent until the device is connected • Turn into settings once the device is connected • Backward compat (if desired) with overload
Option 4 • Leave it asynchronous • Don’t change anything • Ensures that users don’t get an object that isn’t “working” • Avoid programmer errors that arise due to bad assumptions about consent, device availability, constraints, etc…
Preferences • Synchronous Option 3: • 3 fits better with the new settings work • 1 and 2 are functionally equivalent, with some stylistic differences, and some usability issues • 4 doesn’t solve the problem • No backward compatibility hack • Overloading gUM might be possible to replicate old behavior, but that’s just extra API cruft