- From: Jan-Ivar Bruaroey <jib@mozilla.com>
- Date: Thu, 06 Jun 2013 21:10:41 -0400
- To: public-webrtc@w3.org
On 6/6/13 7:54 AM, Adam Bergkvist wrote:
> Hi
>
> I played around a bit with slightlyoff's Future/Promise polyfill,
> redefined some of the methods on PeerConnection and tested it in
> chrome. Here's how our current simple example from the spec could look
> with futures. It's not the simplest re-write (method(success, error)
> -> method().then(success, error)); it uses some chaining.
>
> An alternative would be to not listen for the negotiationneeded event
> and chain offer generation with the call to getUserMedia().
I was going to say, at the Boston interim I thought we agreed that
keying off onnegotiationneeded was unusual. Didn't someone get an action
item to "align" the example to not steer people this way? - If this has
changed, please let me know, as this doesn't work in Firefox currently.
> Here's the code if someone is interested.
Great! Comments below.
> /Adam
>
> var remotePeer = new SignalingChannel();
> var configuration = { "iceServers":
> [{ "url": "stun:stun.example.org" }] };
> var pc;
>
> // call start() to initiate
> function start() {
> pc = new RTCPeerConnection(configuration);
>
> // send any ice candidates to the other peer
> pc.onicecandidate = function (evt) {
> if (evt.candidate)
> remotePeer.send(JSON.stringify(
> { "candidate": evt.candidate }));
> };
>
> // let the "negotiationneeded" event trigger offer generation
> pc.onnegotiationneeded = function () {
> pc.createOffer().then(function (offer) {
> // set the newly created offer
> return pc.setLocalDescription(offer);
> }, logError)
> .then(function () {
> // send the offer to the other peer
> remotePeer.send(JSON.stringify(
> { "sdp": pc.localDescription }));
> }, logError);
> };
I believe Futures is optimized for chains that take the single result of
the previous step (the single success-callback arg), so you should be
able to collapse:
// let the "negotiationneeded" event trigger offer generation
pc.onnegotiationneeded = function () {
pc.createOffer()
.then(pc.setLocalDescription)
.then(function () {
// send the offer to the other peer
remotePeer.send(JSON.stringify({ "sdp": pc.localDescription
}));
}, logError);
};
Errors bubble, so logError isn't needed on every step and still gets called.
> // once remote stream arrives, show it in the remote video element
> pc.onaddstream = function (evt) {
> remoteVideo.src = URL.createObjectURL(evt.stream);
> };
>
> // get a local stream, show it in a self-view and add it to be sent
> navigator.getUserMedia({ "audio": true, "video": true })
> .then(function (stream) {
> selfVideo.src = URL.createObjectURL(stream);
> pc.addStream(stream);
> });
> }
>
> remotePeer.onmessage = function (evt) {
> // got signaling message from other peer
> if (!pc)
> start();
>
> var message = JSON.parse(evt.data);
> if (message.sdp) {
> var desc = new RTCSessionDescription(message.sdp);
>
> pc.setRemoteDescription(desc).then(function () {
> // if we received an offer, we need to create an answer
> if (pc.remoteDescription.type == "offer") {
> pc.createAnswer().then(function (answer) {
> // set answer locally
> return pc.setLocalDescription(answer);
> }, logError)
> .then(function () {
> // send our updated local description to ther peer
> remotePeer.send(JSON.stringify(
> { "sdp": pc.localDescription }));
> }, logError);
> }
> }, logError);
Nice! You're leaning right a little though. How about:
var message = JSON.parse(evt.data);
if (message.sdp) {
var desc = new RTCSessionDescription(message.sdp);
if (desc.type == "offer") {
pc.setRemoteDescription(desc)
.then(function () { return pc.createAnswer(); })
.then(pc.setLocalDescription)
.then(function () {
// send our updated local description to ther peer
remotePeer.send(JSON.stringify(
{ "sdp": pc.localDescription }));
}, logError);
} else
pc.setRemoteDescription(desc).then(function(){}, logError);
Different pattern, different pain-points, but I find this easier to read
as it sets up distinct chains for offer and answer.
.: Jan-Ivar :.
> } else
> pc.addIceCandidate(new RTCIceCandidate(message.candidate));
> };
>
> function logError(error) {
> log(error.name + ": " + error.message);
> }
Received on Friday, 7 June 2013 01:11:10 UTC