Procházet zdrojové kódy

sink added more features; sink refactoring. need to test.

Michelle Bu před 12 roky
rodič
revize
db1fc5cefe
2 změnil soubory, kde provedl 142 přidání a 54 odebrání
  1. 1 1
      public/js/msgpack
  2. 141 53
      public/js/sink.js

+ 1 - 1
public/js/msgpack

@@ -1 +1 @@
-Subproject commit 4be53c9400537f82396c53645920637ad3251264
+Subproject commit 7f56c788ad409cee3ede80889bbb4661dd96ff96

+ 141 - 53
public/js/sink.js

@@ -1,86 +1,170 @@
-function SinkPeer(options, readyfn) {
+function SinkPeer(options) {
   if (!browserisms) {
     readyfn({ error: 'RTC-incompatible browser' });
   }
   this._config = options.config || {};
-  this._source = options.source || 'StreamAPI';
+  this._source = options.source || null;
+  this._stream = this._source ? options.stream || null : options.stream || 'd';
   this._pc = null;
   this._id = null;
   this._dc = null;
   this._socket = io.connect('http://localhost');
-  this.socketInit(readyfn);
+  this.socketInit();
 };
 
 
-SinkPeer.prototype.socketInit = function(cb) {
+SinkPeer.prototype.socketInit = function() {
   self = this;
-  this._socket.emit('sink', { source: this._source, isms: browserisms },
-      function(data) {
-    self._id = data.id;
-    self._pc = new RTCPeerConnection(self._config);
-
-    //FIREFOX
-    self._pc.onaddstream = function(obj) {
-      console.log('SINK: data stream get');
-    };
-
-    self.setupDataChannel();
-
-    self._socket.on('offer', function(offer) {
-      self._pc.setRemoteDescription(offer.sdp, function() {
-        //Firefox
-        getUserMedia({ audio: true, fake: true }, function(s) {
-          self._pc.addStream(s);
-
-          self._pc.createAnswer(function(answer) {
-            self._pc.setLocalDescription(answer, function() {
-              self._socket.emit('answer',
-                  { 'sink': self._id,
-                    'sdp': answer,
-                    'source': offer.source });
-              // Firefoxism
-              if (browserisms && browserisms == 'Firefox') {
-                self._pc.connectDataConnection(5001, 5000);
-              }
-              if (cb) {
-                cb({ response: 'done' });
-              }
-            }, function(err) {
-              console.log('failed to setLocalDescription, ', err)
+  // Multiple sinks to one source.
+  if (!!this._source) {
+    this._socket.emit('sink', { source: this._source, isms: browserisms },
+        function(data) {
+      self._id = data.id;
+      self._pc = new RTCPeerConnection(self._config);
+
+      //FIREFOX
+      self._pc.onaddstream = function(obj) {
+        console.log('SINK: data stream get');
+      };
+
+
+      self._socket.on('offer', function(offer) {
+        self._pc.setRemoteDescription(offer.sdp, function() {
+
+          // If we also have to set up a stream on the sink end, do so.
+          if (!!self._stream) {
+            self.handleStream(false, function() {
+              self.maybeBrowserisms(false, offer.source);
             });
-          }, function(err) {
-            console.log('failed to create answer, ', err)
-          });
-        }, function(err) { console.log('crap'); });
-      }, function(err) {
-        console.log('failed to setRemoteDescription with offer, ', err);
+          } else {
+            self.maybeBrowserisms(false, offer.source);
+          }
+
+        }, function(err) {
+          console.log('failed to setRemoteDescription with offer, ', err);
+        });
+      });
+    });
+  } else {
+    // Otherwise, this sink is the originator to another sink and should wait
+    // for an alert.
+    this._socket.emit('source', function(data) {
+      self._id = data.id;
+
+      if (!!self.readyHandler) {
+        self.readyHandler(self._id);
+      }
+
+      this._socket.on('sink-connected', function(data) {
+        target = data.sink;
+        self._pc = new RTCPeerConnection(self._config);
+        self.handleStream(true, function() {
+          self.maybeBrowserisms(true, target);
+        });
       });
     });
+  }
+};
+
+
+SinkPeer.prototype.maybeBrowserisms = function(originator, target) {
+  var self = this;
+  if (browserisms == 'Firefox') {
+    getUserMedia({ audio: true, fake: true }, function(s) {
+      self._pc.addStream(s);
+
+      if (originator) {
+        self.makeOffer(target);
+      } else {
+        self.makeAnswer(target);
+      }
+
+    }, function(err) { console.log('crap'); });
+  } else {
+    if (originator) {
+      this.makeOffer(target);
+    } else {
+      this.makeAnswer(target);
+    }
+  }
+}
+
+
+SinkPeer.prototype.makeAnswer = function(target) {
+  var self = this;
+
+  this._pc.createAnswer(function(answer) {
+    self._pc.setLocalDescription(answer, function() {
+      self._socket.emit('answer',
+          { 'sink': self._id,
+            'sdp': answer,
+            'source': target });
+      // Firefoxism
+      if (browserisms && browserisms == 'Firefox') {
+        self._pc.connectDataConnection(5001, 5000);
+      }
+    }, function(err) {
+      console.log('failed to setLocalDescription, ', err)
+    });
+  }, function(err) {
+    console.log('failed to create answer, ', err)
   });
+};
 
+SinkPeer.prototype.makeOffer = function(target) {
+  var self = this;
+
+  this._pc.createOffer(function(offer) {
+    self._pc.setLocalDescription(offer, function() {
+      self._socket.emit('offer',
+        { 'sdp': offer,
+          'sink': target,
+          'source': self._id });
+    }, function(err) {
+      console.log('failed to setLocalDescription, ' err);
+    });
+  });
 };
 
 
-SinkPeer.prototype.setupDataChannel = function() {
+SinkPeer.prototype.handleStream = function(originator, cb) {
+  self.setupDataChannel(originator, cb);
+}
+
+
+SinkPeer.prototype.setupDataChannel = function(originator, cb) {
   self = this;
   if (browserisms != 'Webkit') {
-    this._pc.ondatachannel = function(dc) {
-      console.log('SINK: ondatachannel triggered');
-      dc.binaryType = 'arraybuffer';
-      dc.onmessage = function(e) {
-        self.handleDataMessage(e);
+    if (originator) {
+      this._pc.onconnection = function() {
+        self._dc = pc.createDataChannel(self._name, {}, target);
+        self._dc.binaryType = 'arraybuffer';
+      };
+    } else {
+      this._pc.ondatachannel = function(dc) {
+        console.log('SINK: ondatachannel triggered');
+        dc.binaryType = 'arraybuffer';
+
+        if (!!self._connectionHandler) {
+          self._connectionHandler(target);
+        }
+
+        dc.onmessage = function(e) {
+          self.handleDataMessage(e);
+        };
+        self._dc = dc;
       };
-      self._dc = dc;
-    };
 
-    this._pc.onconnection = function() {
-      console.log('SINK: onconnection triggered');
+      this._pc.onconnection = function() {
+        console.log('SINK: onconnection triggered');
+      };
     }
   }
 
   this._pc.onclosedconnection = function() {
     // Remove socket handlers perhaps.
   };
+  cb();
 };
 
 SinkPeer.prototype.send = function(data) {
@@ -108,5 +192,9 @@ SinkPeer.prototype.on = function(code, cb) {
     this._disconnectHandler = cb;
   } else if (code === 'data') {
     this._dataHandler = cb;
+  } else if (code === 'ready') {
+    this._readyHandler = cb;
+  } else if (code === 'connection') {
+    this._connectionHandler = cb;
   }
 }