Giter Club home page Giter Club logo

simple-peer's Introduction

simple-peer ci coveralls npm downloads javascript style guide javascript style guide

Simple WebRTC video, voice, and data channels

Sponsored by    DFINITY

We are hiring a peer-to-peer WebRTC mobile Web application expert.

DFINITY is building an exciting peer-to-peer WebRTC-based mobile Web app to help improve democracy on the Internet Computer blockchain. The mobile web app connects groups of up to four people in a peer-to-peer WebRTC audio and video call so that they can mutually prove unique personhood.

We are looking for a software engineer or consultant who can help us solve (platform-dependent) reliability issues of our implementation. We are interested in applicants with substantial WebRTC experience for mobile Web apps, experience with different communication patterns (e.g., peer-to-peer, server relay), and substantial problem-solving skills. Having experience in automated testing of this type of applications is a plus. Pay is extremely competitive for the right expertise. For details, please see the full job description.

features

  • concise, node.js style API for WebRTC
  • works in node and the browser!
  • supports video/voice streams
  • supports data channel
  • supports advanced options like:

This package is used by WebTorrent and many others.

install

npm install simple-peer

This package works in the browser with browserify. If you do not use a bundler, you can use the simplepeer.min.js standalone script directly in a <script> tag. This exports a SimplePeer constructor on window. Wherever you see Peer in the examples below, substitute that with SimplePeer.

usage

Let's create an html page that lets you manually connect two peers:

<html>
  <body>
    <style>
      #outgoing {
        width: 600px;
        word-wrap: break-word;
        white-space: normal;
      }
    </style>
    <form>
      <textarea id="incoming"></textarea>
      <button type="submit">submit</button>
    </form>
    <pre id="outgoing"></pre>
    <script src="simplepeer.min.js"></script>
    <script>
      const p = new SimplePeer({
        initiator: location.hash === '#1',
        trickle: false
      })

      p.on('error', err => console.log('error', err))

      p.on('signal', data => {
        console.log('SIGNAL', JSON.stringify(data))
        document.querySelector('#outgoing').textContent = JSON.stringify(data)
      })

      document.querySelector('form').addEventListener('submit', ev => {
        ev.preventDefault()
        p.signal(JSON.parse(document.querySelector('#incoming').value))
      })

      p.on('connect', () => {
        console.log('CONNECT')
        p.send('whatever' + Math.random())
      })

      p.on('data', data => {
        console.log('data: ' + data)
      })
    </script>
  </body>
</html>

Visit index.html#1 from one browser (the initiator) and index.html from another browser (the receiver).

An "offer" will be generated by the initiator. Paste this into the receiver's form and hit submit. The receiver generates an "answer". Paste this into the initiator's form and hit submit.

Now you have a direct P2P connection between two browsers!

A simpler example

This example create two peers in the same web page.

In a real-world application, you would never do this. The sender and receiver Peer instances would exist in separate browsers. A "signaling server" (usually implemented with websockets) would be used to exchange signaling data between the two browsers until a peer-to-peer connection is established.

data channels

var Peer = require('simple-peer')

var peer1 = new Peer({ initiator: true })
var peer2 = new Peer()

peer1.on('signal', data => {
  // when peer1 has signaling data, give it to peer2 somehow
  peer2.signal(data)
})

peer2.on('signal', data => {
  // when peer2 has signaling data, give it to peer1 somehow
  peer1.signal(data)
})

peer1.on('connect', () => {
  // wait for 'connect' event before using the data channel
  peer1.send('hey peer2, how is it going?')
})

peer2.on('data', data => {
  // got a data channel message
  console.log('got a message from peer1: ' + data)
})

video/voice

Video/voice is also super simple! In this example, peer1 sends video to peer2.

var Peer = require('simple-peer')

// get video/voice stream
navigator.mediaDevices.getUserMedia({
  video: true,
  audio: true
}).then(gotMedia).catch(() => {})

function gotMedia (stream) {
  var peer1 = new Peer({ initiator: true, stream: stream })
  var peer2 = new Peer()

  peer1.on('signal', data => {
    peer2.signal(data)
  })

  peer2.on('signal', data => {
    peer1.signal(data)
  })

  peer2.on('stream', stream => {
    // got remote video stream, now let's show it in a video tag
    var video = document.querySelector('video')

    if ('srcObject' in video) {
      video.srcObject = stream
    } else {
      video.src = window.URL.createObjectURL(stream) // for older browsers
    }

    video.play()
  })
}

For two-way video, simply pass a stream option into both Peer constructors. Simple!

Please notice that getUserMedia only works in pages loaded via https.

dynamic video/voice

It is also possible to establish a data-only connection at first, and later add a video/voice stream, if desired.

var Peer = require('simple-peer') // create peer without waiting for media

var peer1 = new Peer({ initiator: true }) // you don't need streams here
var peer2 = new Peer()

peer1.on('signal', data => {
  peer2.signal(data)
})

peer2.on('signal', data => {
  peer1.signal(data)
})

peer2.on('stream', stream => {
  // got remote video stream, now let's show it in a video tag
  var video = document.querySelector('video')

  if ('srcObject' in video) {
    video.srcObject = stream
  } else {
    video.src = window.URL.createObjectURL(stream) // for older browsers
  }

  video.play()
})

function addMedia (stream) {
  peer1.addStream(stream) // <- add streams to peer dynamically
}

// then, anytime later...
navigator.mediaDevices.getUserMedia({
  video: true,
  audio: true
}).then(addMedia).catch(() => {})

in node

To use this library in node, pass in opts.wrtc as a parameter (see the constructor options):

var Peer = require('simple-peer')
var wrtc = require('wrtc')

var peer1 = new Peer({ initiator: true, wrtc: wrtc })
var peer2 = new Peer({ wrtc: wrtc })

api

peer = new Peer([opts])

Create a new WebRTC peer connection.

A "data channel" for text/binary communication is always established, because it's cheap and often useful. For video/voice communication, pass the stream option.

If opts is specified, then the default options (shown below) will be overridden.

{
  initiator: false,
  channelConfig: {},
  channelName: '<random string>',
  config: { iceServers: [{ urls: 'stun:stun.l.google.com:19302' }, { urls: 'stun:global.stun.twilio.com:3478?transport=udp' }] },
  offerOptions: {},
  answerOptions: {},
  sdpTransform: function (sdp) { return sdp },
  stream: false,
  streams: [],
  trickle: true,
  allowHalfTrickle: false,
  wrtc: {}, // RTCPeerConnection/RTCSessionDescription/RTCIceCandidate
  objectMode: false
}

The options do the following:

  • initiator - set to true if this is the initiating peer

  • channelConfig - custom webrtc data channel configuration (used by createDataChannel)

  • channelName - custom webrtc data channel name

  • config - custom webrtc configuration (used by RTCPeerConnection constructor)

  • offerOptions - custom offer options (used by createOffer method)

  • answerOptions - custom answer options (used by createAnswer method)

  • sdpTransform - function to transform the generated SDP signaling data (for advanced users)

  • stream - if video/voice is desired, pass stream returned from getUserMedia

  • streams - an array of MediaStreams returned from getUserMedia

  • trickle - set to false to disable trickle ICE and get a single 'signal' event (slower)

  • wrtc - custom webrtc implementation, mainly useful in node to specify in the wrtc package. Contains an object with the properties:

  • objectMode - set to true to create the stream in Object Mode. In this mode, incoming string data is not automatically converted to Buffer objects.

peer.signal(data)

Call this method whenever the remote peer emits a peer.on('signal') event.

The data will encapsulate a webrtc offer, answer, or ice candidate. These messages help the peers to eventually establish a direct connection to each other. The contents of these strings are an implementation detail that can be ignored by the user of this module; simply pass the data from 'signal' events to the remote peer and call peer.signal(data) to get connected.

peer.send(data)

Send text/binary data to the remote peer. data can be any of several types: String, Buffer (see buffer), ArrayBufferView (Uint8Array, etc.), ArrayBuffer, or Blob (in browsers that support it).

Note: If this method is called before the peer.on('connect') event has fired, then an exception will be thrown. Use peer.write(data) (which is inherited from the node.js duplex stream interface) if you want this data to be buffered instead.

peer.addStream(stream)

Add a MediaStream to the connection.

peer.removeStream(stream)

Remove a MediaStream from the connection.

peer.addTrack(track, stream)

Add a MediaStreamTrack to the connection. Must also pass the MediaStream you want to attach it to.

peer.removeTrack(track, stream)

Remove a MediaStreamTrack from the connection. Must also pass the MediaStream that it was attached to.

peer.replaceTrack(oldTrack, newTrack, stream)

Replace a MediaStreamTrack with another track. Must also pass the MediaStream that the old track was attached to.

peer.addTransceiver(kind, init)

Add a RTCRtpTransceiver to the connection. Can be used to add transceivers before adding tracks. Automatically called as neccesary by addTrack.

peer.destroy([err])

Destroy and cleanup this peer connection.

If the optional err parameter is passed, then it will be emitted as an 'error' event on the stream.

Peer.WEBRTC_SUPPORT

Detect native WebRTC support in the javascript environment.

var Peer = require('simple-peer')

if (Peer.WEBRTC_SUPPORT) {
  // webrtc support!
} else {
  // fallback
}

duplex stream

Peer objects are instances of stream.Duplex. They behave very similarly to a net.Socket from the node core net module. The duplex stream reads/writes to the data channel.

var peer = new Peer(opts)
// ... signaling ...
peer.write(new Buffer('hey'))
peer.on('data', function (chunk) {
  console.log('got a chunk', chunk)
})

events

Peer objects are instance of EventEmitter. Take a look at the nodejs events documentation for more information.

Example of removing all registered close-event listeners:

peer.removeAllListeners('close')

peer.on('signal', data => {})

Fired when the peer wants to send signaling data to the remote peer.

It is the responsibility of the application developer (that's you!) to get this data to the other peer. This usually entails using a websocket signaling server. This data is an Object, so remember to call JSON.stringify(data) to serialize it first. Then, simply call peer.signal(data) on the remote peer.

(Be sure to listen to this event immediately to avoid missing it. For initiator: true peers, it fires right away. For initatior: false peers, it fires when the remote offer is received.)

peer.on('connect', () => {})

Fired when the peer connection and data channel are ready to use.

peer.on('data', data => {})

Received a message from the remote peer (via the data channel).

data will be either a String or a Buffer/Uint8Array (see buffer).

peer.on('stream', stream => {})

Received a remote video stream, which can be displayed in a video tag:

peer.on('stream', stream => {
  var video = document.querySelector('video')
  if ('srcObject' in video) {
    video.srcObject = stream
  } else {
    video.src = window.URL.createObjectURL(stream)
  }
  video.play()
})

peer.on('track', (track, stream) => {})

Received a remote audio/video track. Streams may contain multiple tracks.

peer.on('close', () => {})

Called when the peer connection has closed.

peer.on('error', (err) => {})

Fired when a fatal error occurs. Usually, this means bad signaling data was received from the remote peer.

err is an Error object.

error codes

Errors returned by the error event have an err.code property that will indicate the origin of the failure.

Possible error codes:

  • ERR_WEBRTC_SUPPORT
  • ERR_CREATE_OFFER
  • ERR_CREATE_ANSWER
  • ERR_SET_LOCAL_DESCRIPTION
  • ERR_SET_REMOTE_DESCRIPTION
  • ERR_ADD_ICE_CANDIDATE
  • ERR_ICE_CONNECTION_FAILURE
  • ERR_SIGNALING
  • ERR_DATA_CHANNEL
  • ERR_CONNECTION_FAILURE

connecting more than 2 peers?

The simplest way to do that is to create a full-mesh topology. That means that every peer opens a connection to every other peer. To illustrate:

full mesh topology

To broadcast a message, just iterate over all the peers and call peer.send.

So, say you have 3 peers. Then, when a peer wants to send some data it must send it 2 times, once to each of the other peers. So you're going to want to be a bit careful about the size of the data you send.

Full mesh topologies don't scale well when the number of peers is very large. The total number of edges in the network will be full mesh formula where n is the number of peers.

For clarity, here is the code to connect 3 peers together:

Peer 1

// These are peer1's connections to peer2 and peer3
var peer2 = new Peer({ initiator: true })
var peer3 = new Peer({ initiator: true })

peer2.on('signal', data => {
  // send this signaling data to peer2 somehow
})

peer2.on('connect', () => {
  peer2.send('hi peer2, this is peer1')
})

peer2.on('data', data => {
  console.log('got a message from peer2: ' + data)
})

peer3.on('signal', data => {
  // send this signaling data to peer3 somehow
})

peer3.on('connect', () => {
  peer3.send('hi peer3, this is peer1')
})

peer3.on('data', data => {
  console.log('got a message from peer3: ' + data)
})

Peer 2

// These are peer2's connections to peer1 and peer3
var peer1 = new Peer()
var peer3 = new Peer({ initiator: true })

peer1.on('signal', data => {
  // send this signaling data to peer1 somehow
})

peer1.on('connect', () => {
  peer1.send('hi peer1, this is peer2')
})

peer1.on('data', data => {
  console.log('got a message from peer1: ' + data)
})

peer3.on('signal', data => {
  // send this signaling data to peer3 somehow
})

peer3.on('connect', () => {
  peer3.send('hi peer3, this is peer2')
})

peer3.on('data', data => {
  console.log('got a message from peer3: ' + data)
})

Peer 3

// These are peer3's connections to peer1 and peer2
var peer1 = new Peer()
var peer2 = new Peer()

peer1.on('signal', data => {
  // send this signaling data to peer1 somehow
})

peer1.on('connect', () => {
  peer1.send('hi peer1, this is peer3')
})

peer1.on('data', data => {
  console.log('got a message from peer1: ' + data)
})

peer2.on('signal', data => {
  // send this signaling data to peer2 somehow
})

peer2.on('connect', () => {
  peer2.send('hi peer2, this is peer3')
})

peer2.on('data', data => {
  console.log('got a message from peer2: ' + data)
})

memory usage

If you call peer.send(buf), simple-peer is not keeping a reference to buf and sending the buffer at some later point in time. We immediately call channel.send() on the data channel. So it should be fine to mutate the buffer right afterward.

However, beware that peer.write(buf) (a writable stream method) does not have the same contract. It will potentially buffer the data and call channel.send() at a future point in time, so definitely don't assume it's safe to mutate the buffer.

connection does not work on some networks?

If a direct connection fails, in particular, because of NAT traversal and/or firewalls, WebRTC ICE uses an intermediary (relay) TURN server. In other words, ICE will first use STUN with UDP to directly connect peers and, if that fails, will fall back to a TURN relay server.

In order to use a TURN server, you must specify the config option to the Peer constructor. See the API docs above.

js-standard-style

Who is using simple-peer?

  • WebTorrent - Streaming torrent client in the browser

  • Virus Cafe - Make a friend in 2 minutes

  • Instant.io - Secure, anonymous, streaming file transfer

  • Zencastr - Easily record your remote podcast interviews in studio quality.

  • Friends - Peer-to-peer chat powered by the web

  • Socket.io-p2p - Official Socket.io P2P communication library

  • ScreenCat - Screen sharing + remote collaboration app

  • WebCat - P2P pipe across the web using Github private/public key for auth

  • RTCCat - WebRTC netcat

  • PeerNet - Peer-to-peer gossip network using randomized algorithms

  • PusherTC - Video chat with using Pusher. See guide.

  • lxjs-chat - Omegle-like video chat site

  • Whiteboard - P2P Whiteboard powered by WebRTC and WebTorrent

  • Peer Calls - WebRTC group video calling. Create a room. Share the link.

  • Netsix - Send videos to your friends using WebRTC so that they can watch them right away.

  • Stealthy - Stealthy is a decentralized, end-to-end encrypted, p2p chat application.

  • oorja.io - Effortless video-voice chat with realtime collaborative features. Extensible using react components 🙌

  • TalktoMe - Skype alternative for audio/video conferencing based on WebRTC, but without the loss of packets.

  • CDNBye - CDNBye implements WebRTC datachannel to scale live/vod video streaming by peer-to-peer network using bittorrent-like protocol

  • Detox - Overlay network for distributed anonymous P2P communications entirely in the browser

  • Metastream - Watch streaming media with friends.

  • firepeer - secure signalling and authentication using firebase realtime database

  • Genet - Fat-tree overlay to scale the number of concurrent WebRTC connections to a single source (paper).

  • WebRTC Connection Testing - Quickly test direct connectivity between all pairs of participants (demo).

  • Firstdate.co - Online video dating for actually meeting people and not just messaging them

  • TensorChat - It's simple - Create. Share. Chat.

  • On/Office - View your desktop in a WebVR-powered environment

  • Cyph - Cryptographically secure messaging and social networking service, providing an extreme level of privacy combined with best-in-class ease of use

  • Ciphora - A peer-to-peer end-to-end encrypted messaging chat app.

  • Whisthub - Online card game Color Whist with the possibility to start a video chat while playing.

  • Brie.fi/ng - Secure anonymous video chat

  • Peer.School - Simple virtual classroom starting from the 1st class including video chat and real time whiteboard

  • FileFire - Transfer large files and folders at high speed without size limits.

  • safeShare - Transfer files easily with text and voice communication.

  • CubeChat - Party in 3D 🎉

  • Homely School - A virtual schooling system

  • AnyDrop - Cross-platform AirDrop alternative with an Android app available at Google Play

  • Share-Anywhere - Cross-platform file transfer

  • QuaranTime.io - The Activity board-game in video!

  • Trango - Cross-platform calling and file sharing solution.

  • P2PT - Use WebTorrent trackers as signalling servers for making WebRTC connections

  • Dots - Online multiplayer Dots & Boxes game. Play Here!

  • simple-peer-files - A simple library to easily transfer files over WebRTC. Has a feature to resume file transfer after uploader interruption.

  • WebDrop.Space - Share files and messages across devices. Cross-platform, no installation alternative to AirDrop, Xender. Source Code

  • Speakrandom - Voice-chat social network using simple-peer to create audio conferences!

  • Deskreen - A desktop app that helps you to turn any device into a secondary screen for your computer. It uses simple-peer for sharing entire computer screen to any device with a web browser.

  • Your app here! - send a PR!

license

MIT. Copyright (c) Feross Aboukhadijeh.

simple-peer's People

Contributors

buu700 avatar cgnonofr avatar dependabot[bot] avatar diegorbaquero avatar elavoie avatar feross avatar fiatexodus avatar fresheneesz avatar greenkeeper[bot] avatar greenkeeperio-bot avatar holtwick avatar joshontheweb avatar longsleep avatar markandrus avatar mding5692 avatar mreinstein avatar najibghadri avatar natzcam avatar nazar-pc avatar pavlobu avatar prashanthr avatar rahuldey12 avatar rationalcoding avatar raultsc avatar rvdleun avatar sagivo avatar samuelmaddock avatar subins2000 avatar t-mullen avatar vj-abishek avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

simple-peer's Issues

Full example please..

Could you please provide a folder with full example files?

As for me, this folder should contain:

  1. Some html page for browsers
  2. Some nodejs app
  3. Connection server?
  4. Relay server?

Thus we, the newbie developers, might got it all work and test and use as a starter kit for our apps.

Is that possible?... Thank you in advance!
Pavel

SessionDescription is NULL

I've used audio/video example from README file in my project and managed to get everything running, however when I rewrote everything to use my node.js + socket.io signaling server there started to be problems. What I'm trying to accomplish is streaming video directly to server, not to other clients.

After sending initial signal message from browser:

socket.on('signal', function(data) {
    simplePeer.signal(data);
});

I'm getting this error on server:

Error: SessionDescription is NULL.

After this, peer connection is closed and I can't go anywhere from there.
I'm using basic configuration on server side:

var SimplePeer = require('simple-peer')
var wrtc = require('wrtc')
var peer = new SimplePeer({ wrtc: wrtc })

Am I doing something wrong in here?

When is the 'ready' event fired?

I create two Peer objects in the same browser window and tried to send message from one to other. The code is almost same as that given in simple-peer readme:

var Peer = require('simple-peer');
var peer1 = new Peer({ initiator: true })
var peer2 = new Peer();

peer1.on('signal', function (data) {
  // when peer1 has signaling data, give it to peer2
  console.log('peer1 on signal')
  peer2.signal(data)
})

peer2.on('signal', function (data) {
  // same as above, but in reverse
  console.log('peer2 on signal')
  peer1.signal(data)
})

peer1.on('ready', function () {
  // wait for 'ready' event before using the data channel
  console.log('peer1 ready');                         
  peer1.send('hey peer2, how is it going?')
})

peer2.on('message', function (data) {
  // got a data channel message
  console.log('got a message from peer1: ' + data)   
})

I get these logs:

peer1 on signal
peer2 on signal
peer1 on signal
peer2 on signal
peer1 on signal
peer2 on signal

The ready event never seems to fired, and no message gets sent.

Simplepeer.min.js raising security error in Firefox.

Unable to load the page. The exception and html are below:

This is the error:
Security wrapper denied access to property valueOf on privileged Javascript object. Support for exposing privileged objects to untrusted content via exposedProps is being gradually removed - use WebIDL bindings or Components.utils.cloneInto instead. Note that only the first denied property access from a given global object will be reported.

HTML: https://gist.github.com/Lastalas/e3a157244877a9d7aa65

I'm not quite sure what else I can add. Does this sound in any way familiar?

Firefox 35.0.1
Ubuntu 64bit

Throttling signaling messages

Is there a way to throttle signaling messages? I'm trying to do the connection negotiation over Pusher client events, but it only allows 10 per second which is not enough.

Sending buffers fails over wrtc sometimes

When I run the unit tests for node.js, they fail:

# data send/receive Buffer
isbuffer true true
ok 24 data is Buffer
not ok 25 got correct message
  ---
    operator: deepEqual
    expected: |-
      <Buffer >
    actual: |-
      <Buffer 76 61 72 20 63 6f 6d 6d 6f 6e 20 3d 20 72 65 71 75 69 72 65 28 27 2e 2f 63 6f 6d 6d 6f 6e 27 29 0a 76 61 72 20 50 65 65 72 20 3d 20 72 65 71 75 69 72 ... >
    at: Peer.<anonymous> (/Users/paul/repos/simple-peer/test/binary.js:71:9)
  ...
isbuffer true true
FATAL ERROR: v8::ArrayBuffer::Externalize ArrayBuffer already externalized
^C

Bizarrely, that Buffer translates to:

var common = require('./common')
var Peer = requir...

I think the reason it's failing is because simple-peer isn't converting Buffers to UInt8Arrays, because isTypedArray returns true for... most Buffers? All Buffers? I'll try to make a pull request that fixes this.

MediaStream issue when not on same network

Hi, I am new to WebRTC but used this library to build an app with video chat. When I used it locally (with an Incognito browser) it worked fine, and when I tested with two computers on Heroku it worked fine as well. Now I am finding that when I have a chat between two users on different networks (or different states, countries, etc.), it doesn't work. Why might this be? I plugged in a bunch of console.logs and saved the incoming MediaStream as a global var to see if I could get the video to come in by playing around in the browser console, but no luck. Is this an issue with SimplePeer or a glitch in my code? It must be one or the other. Here is a Gist. https://gist.github.com/tgoldenberg/80ba89f193b99724ff26

It may be somewhat confusing. The example I based off of, the PusheRTC repo (on Github), uses a 'presence-chat', while I used a private 1-1 chat with Pusher. I was finding difficulties negotiating who would be the initiator:true peer, so I create an event that triggers the initiator:true. Everything else should seem fairly straightforward.

I really hope someone will be able to tell me what is going wrong, and how I can fix it. Thank you!

Audio streams don't always start in chrome

I'm using simple-peer to send audio streams (for positional audio in scenevr), but I'm having a case that about 70% of the time, if I don't have the javascript console open, the stream doesn't seem to have an audio in it, it's just silent. Sadly, if I run these tests with the console open, it seems to work 90% of the time. :(

Any ideas?

expose addStream on prototype

right now you can only specify the stream in the constructor

you should be able to do it lazily after the connection has been opened, that way you can start the connection process as soon as possible instead of handling camera access and connection in series

Remove "speed hack"

So, I knew that the "speed hack" shouldn't be necessary with SCTP data channels, but Chrome was still including the bandwidth line in the SDPs and so I figured I'd leave the speed hack in there.

But @fippo was making fun of me at the WebRTC meetup after Google I/O for still using it, so let's get rid of it :-)

iceConnectionStateChange state 'failed' should be handled as error

the 'failed' state from https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/iceConnectionState is currently not handled:

simple-peer/index.js

Lines 347 to 365 in ba0e925

if (iceConnectionState === 'connected' || iceConnectionState === 'completed') {
clearTimeout(self._reconnectTimeout)
self._pcReady = true
self._maybeReady()
}
if (iceConnectionState === 'disconnected') {
if (self.reconnectTimer) {
// If user has set `opt.reconnectTimer`, allow time for ICE to attempt a reconnect
clearTimeout(self._reconnectTimeout)
self._reconnectTimeout = setTimeout(function () {
self._destroy()
}, self.reconnectTimer)
} else {
self._destroy()
}
}
if (iceConnectionState === 'closed') {
self._destroy()
}

it should get handled as an error as currently it causes a silent hung fail state

Would be nice to get more information from getStats

Right now getStats() is handled internally and sets local/remote host/port. Would be nice if I we had an event to allow users to hook into the stats.

I'm thinking something like

peer.getStats(function(stats){})

and in internally it would do this https://github.com/feross/simple-peer/blob/master/index.js#L375-L395 and then pass it to our callback.

Currently my I'd like to know if the peer needed a TURN server or not, its kind of tricky currently to figure out which ice candidate was selected/successful especially since the last ice candidate always seems to be the TURN server I have configured.

how to send blob

I'm just curious how one would send a blob. It's hard for me to tell if the error is coming from chrome 47 or not.

the following code gives an error:

    var b = new Blob(new Uint32Array(123))
    client.send(b) // this is a simple-peer

Uncaught DOMException: Failed to execute 'send' on 'RTCDataChannel': Blob support not implemented yet(…)

'signal' event should emit strings

substack> feross: with simple-peer, how do I serialize the signal messages?
15:11 <•substack> they're just some objects
15:12 <•feross> oh, i thought the messages were strings
15:12 <•substack> it seems really inconvenient for them to be instances instead of data
15:12 <•substack> the payloads from the 'signal' event
15:12 <•substack> RTCSessionDescription {sdp: "v=0
15:12 <•substack> ↵o=- 3083488521651813894 2 IN IP4 127.0.0.1
15:12 <•substack> ↵s…id:data
15:12 <•substack> ↵a=sctpmap:5000 webrtc-datachannel 1024
15:12 <•substack> ↵", type: "offer"}
15:12 <•feross> simple-peer should stringify them
15:12 <•feross> you can just call JSON.stringify on those objects
15:13 <•feross> RTCSessionDescription is just a browser class that subclasses from Object
15:13 <•substack> ok
15:13 <•feross> But we should probably fix this in simple-peer, so people can just pass the opaque strings around
15:14 <•feross> would be a semver major change

reconnectTimer not working

(latest version off npm)

reconnectTimer option does nothing. reconnecting event is fired, but after the timeout the connection is not destroyed

Support backpressure

Right now, we just send as fast as possible. We should support backpressure and detect when bufferedAmount gets too high and pause for a while.

Relevant:

The solution implemented for simple-peer can also be used for websocket libraries like websocket-stream, since data channels and websockets have the same API, and thus, the same difficulties detecting when backpressure is needed.

cc @mafintosh, @maxogden

support lack of pc.getStats

right now this doesn't work on ios since webrtc getStats isn't implemented yet. this is being used in the internals of simple-peer to get local/remote address - is this needed or anything other than debug?

Binary messages not flowing on version 6.0.3

Just took the basic example and used the test payload from the unit tests: http://requirebin.com/?gist=426a5e6c340fd64b73ef329cbfa94baf

When inspecting the console, I see that it attempts to send but the message is never received by the other peer. If I switch the payload to a text string, it works no problem.

Using OS X, tested on

  • Chrome: 51.0.2700.0 canary (64-bit)
  • Chrome: 49.0.2623.110 (64-bit)
var SimplePeer = require('simple-peer')

var peer1 = new SimplePeer({ initiator: true })
var peer2 = new SimplePeer()

peer1.on('signal', function (data) {
  // when peer1 has signaling data, give it to peer2 somehow
  peer2.signal(data)
})

peer2.on('signal', function (data) {
  // when peer2 has signaling data, give it to peer1 somehow
  peer1.signal(data)
})

peer1.on('connect', function () {
  // wait for 'connect' event before using the data channel
  peer1.send(new Uint8Array([0, 1, 2])); //example from unit tests
  console.log('sent')
}) 

peer2.on('data', function (data) {
  console.log('got') //this never fires when using binary data
  console.log(JSON.stringify(data));
})

I tried packages 6.0.3-6.0.0 with the same behavior.

Cannot read property 'prototype' of undefined

Uncaught TypeError: Cannot read property 'prototype' of undefinedmessage: "Cannot read property 'prototype' of undefined"stack: (...)get stack: function () { [native code] }set stack: function () { [native code] }__proto__: Errorinherits_browser.js:5 inheritsindex.js:28 2.debugbuild.js:1 sbuild.js:1 (anonymous function)index.js:2 window.xVM682:2 (anonymous function)VM679:847 InjectedScript._evaluateOnVM679:780 InjectedScript._evaluateAndWrapVM679:646 InjectedScript.evaluate

The problem seems to be inherits(Peer, stream.Duplex).

Can't connect peers when on a different network

Thanks for writing simple-peer, really great to have a WebRTC library that I can use in both browser and node.js.

I'm playing around with SimplePeer but noticed that I can't connect peers when they are on a different network. I've put the usage example from the readme in a jsbin to have the simplest possible test:

http://output.jsbin.com/tomini/

The initiator correctly generates an offer, and when I paste the offer in the form of the receiver, it generates an answer. When I paste the answer in the initiators form however nothing happens, and after 5 or 10 seconds the peers on both sides send a closed (from both sides).

To verify whether the networks and devices I'm testing on don't have some issue I tested whether WebRTC by itself works using https://apprtc.appspot.com/. This indeed works just fine on all machines and phones I'm trying.

Any idea?

Error when offer is generated

I have locally installed simple-peer and I created the html file and bundle.js (using browserify) from the example in the usage section. I'm running the html locally on firefox and internet explorer, but when the offer is supposed to be generated, I get this String in my initiator (firefox):

{"type":"offer","sdp":"v=0
\r\no=mozilla...THIS_IS_SDPARTA-42.0 4294967295 0 IN IP4 0.0.0.0
\r\ns=-
\r\nt=0 0
\r\na=sendrecv
\r\na=fingerprint:sha-256 69:94:EB:39:ED:03:74:37:5F:C9:CF:6C:A1:E9:F5:8C:92:2D:B7:FA:7D:4B:91:ED:8D:77:B0:01:5D:05:A2:CC
\r\na=ice-options:trickle\r\na=msid-semantic:WMS *
\r\nm=application 56243 DTLS/SCTP 5000
\r\nc=IN IP4 209.89.144.167
\r\na=candidate:0 1 UDP 2130575615 169.254.56.152 56240 typ host
\r\na=candidate:2 1 UDP 2130444543 169.254.104.17 56241 typ host
\r\na=candidate:4 1 UDP 2130379007 2001:56a:70af:9e00:9d0a:c1c3:6d4e:2389 56242 typ host
\r\na=candidate:6 1 UDP 2122121471 192.168.1.80 56243 typ host
\r\na=candidate:7 1 UDP 1685921791 209.89.144.167 56243 typ srflx raddr 192.168.1.80 rport 56243
\r\na=sendrecv
\r\na=end-of-candidates
\r\na=ice-pwd:7dfce6b80ca0ce59b86f0bca8c0566f8
\r\na=ice-ufrag:9792e3a8
\r\na=mid:sdparta_0
\r\na=sctpmap:5000 webrtc-datachannel 256
\r\na=setup:actpass
\r\na=ssrc:3367038954 cname:{d41c4bc7-c377-41ed-a8e7-91bda9100e2f}
\r\n"}

I made sure simple-peer has all its dependencies on the node_modules folder created by npm. What could be wrong? any help/pointing to an appropriate reading is appreciated. Thanks a lot and have a great day!

Offer a way to munge the "local" offer

Would be great to give a way to patch the offer's SDP before setting it as a local description (like it is done for the "speed hack"). May be a function passed as an option to the constructor like:

new SimplePeer({
  sdpMunger: function(sdp) {
    // transform the SDP
    return sdp;
  }
})

I would need it to change to configuration of the audio codec (set it in stereo mode and change the ptime).

Is simple-peer supposed to work with wrtc?

I see that the unit tests are a little flaky when I run this with wrtc. Is this library supposed to work with wrtc? Or, if not, is there an alternative node WebRTC implementation that I should use?

Example flakiness:

# data send/receive text
ok 3 (unnamed assert)
ok 4 (unnamed assert)
ok 5 peer1 is initiator
ok 6 peer2 is not initiator
ok 7 should be equal
ok 8 should be equal
not ok 9 should be equal
  ---
    operator: equal
    expected: '192.168.0.7'
    actual:   '10.186.1.6'
    at: Peer.tryTest (/Users/paul/repos/simple-peer/test/basic.js:59:7)
  ...
not ok 10 should be equal
  ---
    operator: equal
    expected: 52618
    actual:   59272
    at: Peer.tryTest (/Users/paul/repos/simple-peer/test/basic.js:60:7)
  ...
ok 11 (unnamed assert)
ok 12 (unnamed assert)
ok 13 (unnamed assert)
ok 14 (unnamed assert)
ok 15 got correct message
ok 16 got correct message
ok 17 both peers closed

Signalling server?

I am a bit confused... doesn't this need a signalling server? How can I create one?

shim support

There are some shims (for example: https://code.google.com/p/webrtc4all/) that allow you to do webrtc all the way back to IE6. Crazy.

The API is supposed to be the same as the spec but it looks a little different from a first glance. Not going to be easy to drop it right in. I was curious if you had any ideas for how this should work with simple-peer

Stuff I can think of off the top of my head:

  • Create a layer that makes this shim conform to the spec, write to window and simple-peer will use it unknowingly as long as it behaves the same
  • simple-peer takes an implementation of webrtc as an option, but defaults to the browser's specified version
  • simple-peer adds support for this shim outright

LMK your thoughts 👍

Sauce tests hanging

Somewhere around September 4th the browser tests started hanging for me, I think due to a change at Sauce. Peer connections from Sauce's network to the outside world continue to work, so TURN can be used to work around the issue, but I don't think this is a real solution. I've sent an email to Sauce but haven't gotten a reply yet - can anyone else confirm / deny this problem?

Process hangs at "simple-peer [undefined] new peer { ...wrtc: { RTCIceCandidate, RTCPeerConnection, RTCSessionDescription } } +0ms"

I'm having some troubles running bittorrent-swarm with webrtc enabled on the server side. The process always seem to halt with the last debug message always coming from simple-peer. e.g.:

  bittorrent-swarm:peer new Peer 43.18.99.193:19130 +0ms
  bittorrent-swarm _drain numConns 0 maxConns 55 +0ms
  bittorrent-swarm drain (74 queued, 0/55 peers) +0ms
  bittorrent-swarm tcp connect attempt to 43.18.99.193:19130 +0ms
  bittorrent-swarm addPeer 70.54.126.231:34270 +1ms
  bittorrent-swarm:peer new Peer 70.54.126.231:34270 +0ms
  bittorrent-swarm _drain numConns 0 maxConns 55 +0ms
  bittorrent-swarm drain (75 queued, 0/55 peers) +0ms
  bittorrent-swarm tcp connect attempt to 70.54.126.231:34270 +0ms
  bittorrent-swarm addPeer 63.118.120.55:24230 +0ms
  bittorrent-swarm:peer new Peer 63.118.120.55:24230 +0ms
  bittorrent-swarm _drain numConns 0 maxConns 55 +0ms
  bittorrent-swarm drain (76 queued, 0/55 peers) +0ms
  bittorrent-swarm tcp connect attempt to 63.118.120.55:24230 +0ms
  bittorrent-swarm addPeer 70.115.127.51:34212 +0ms
  bittorrent-swarm:peer new Peer 70.115.127.51:34212 +0ms
  bittorrent-swarm _drain numConns 0 maxConns 55 +0ms
  bittorrent-swarm drain (77 queued, 0/55 peers) +0ms
  bittorrent-swarm tcp connect attempt to 70.115.127.51:34212 +1ms
  bittorrent-tracker:websocket-tracker generating 10 offers +19ms
  simple-peer [undefined] new peer { initiator: true, trickle: false, config: undefined, wrtc: { RTCIceCandidate: [Function: RTCIceCandidate], RTCPeerConnection: [Function: RTCPeerConnection], RTCSessionDescription: [Function: RTCSessionDescription] } } +0ms

Add support for node-webrtc

It would be cool if we were able to utilise this module in hybrid clients. In order to do this you should add the option to use node-webrtc eg. module.exports.hybrid = true. Thanks.

Empty file in 5.11.6

simplepeer.min.js is a empty file in the latest npm build

$ cat node_modules/simple-peer/simplepeer.min.js 

$ 

Error when initiator is true

var peer = new Peer({ initiator: true })

produces error:

[57803:1226/220911:ERROR:webrtcsession.cc(1384)] ConnectDataChannel called when data_channel_ is NULL.

in electron via electron-spawn

setting initiator to false does not cause an error.

Fails to initialize - remote.ipAddress

Running webtorrent-hybrid in node, attempting to seed an instant.io - generated/seeded magnet produces the following error:

self.remoteAddress = remote.ipAddress
                           ^
TypeError: Cannot read property 'ipAddress' of undefined at setActiveCandidates

How to use simple-peer with { trickle: true } ?

Moving from email...

I'm writing to You because I can't find any information on usage of Your module (simple peer) with ICE Trickle set to "true" for faster connection establishment.

At this moment I'm using simple socket.io server for signaling, and I'm able to connect to browsers when ICE Tricke is set to false. I would prefer to use this option for faster connections but I'm not sure how to do this. I think that I may want to use "addIceCandidate()" method on every signal with discovered candidate but there is no such method on "peer" object constructed through Your module.

I would be very gratefull for any kind of help.

Data channel stream race condition

There's something fishy with the stream implementation. A saw a bunch of test failures with this message recently:

<chrome 35 on Mac 10.9> console
# data send/receive as stream
<chrome 35 on Mac 10.9> data send/receive as stream
Error: got correct message
<chrome 35 on Mac 10.9> console
not ok 45 got correct message
<chrome 35 on Mac 10.9> console
  ---
<chrome 35 on Mac 10.9> console
    operator: equal
<chrome 35 on Mac 10.9> console
    expected: 'abc'
<chrome 35 on Mac 10.9> console
    actual:   ''
<chrome 35 on Mac 10.9> console
    at: Test.assert (https://todcjruqpf.localtunnel.me/__zuul/test-bundle.js:4457:13)
<chrome 35 on Mac 10.9> console
  ...
<chrome 35 on Mac 10.9> console

Full log: https://travis-ci.org/feross/simple-peer/builds/44808455

Feature: Unreliable DataChannels

I'm looking to use webRTC to create a pair of RTCDataChannels per peer:

  • tcp-like { reliable: true, ordered: true } transport
  • udp-like { reliable: false, ordered: false } transport

This may be out of the scope of simple-peer but is there a simple way of creating additional dataChannels for a peer?

Getting : Error: SessionDescription is NULL when calling peer.signal

Hello
My basic requirement is to stream audio and video to a simple-peer running within node.js.

I have written following code for node.js app:

require('events').EventEmitter.prototype._maxListeners = 1000;
var WebSocketClient = require('websocket').client;
var wrtc = require('wrtc');
var client = new WebSocketClient();
var counter = 0;
var sdp;
var ice;

var peerConnectionConfig = null;
var SimplePeer = require('simple-peer');
var peerConnection = undefined;

client.on('connectFailed', function(error) {
console.log('Connect Error: ' + error.toString());
});

client.on('connect', function(connection) {
console.log('WebSocket Client Connected');

connection.on('error', function(error) {
    console.log("Connection Error: " + error.toString());
});
connection.on('close', function() {
    console.log('echo-protocol Connection Closed');
});

connection.on('message', function(message) {

        if (peerConnection === undefined) {
            peerConnection = new SimplePeer({
                trickle: false,
                wrtc: wrtc
            });
            console.log('Created peer connection..');
        }
        console.log(' Started SimplePeer on node.. ');

        peerConnection.on('signal', function(data) {

            client.send(data);
            console.log(' sent sdp to server');

        });

        sdp = message.utf8Data;
        console.log("Received sdp: '" + sdp + "'");
        console.log(' Sending message to server: ');
        peerConnection.signal(JSON.parse(sdp));


});

});

client.connect('ws://10.112.198.241:8080/webrtc');


And I get following error in node.js when I do : peerConnection.signal(JSON.parse(sdp));

events.js:154
throw er; // Unhandled 'error' event
^

Error: SessionDescription is NULL.
at Error (native)

Can you pls suggest where am I wrong or it it an issue with either wrtc module or simple peer.

Thanks in advance.

Amit Verma

optionalDependency on wrtc is unwanted for web projects

Hi @feross

Continuing the discussion in node-webrtc/node-webrtc#194 (and the clutter of trying to solve it with --no-optional) - I see another downside of defining wrtc as an optionalDependency of simple-peer.

I have several projects that depends on simple-peer, because it's awesome :) These projects only use it in web pages, but have no interest for the webrtc stack for nodejs, and they get installed on cloud platforms only to serve those pages to users.

Now wrtc is always attempted to install along with simple-peer, and since wrtc is not yet providing binaries for all platforms, this also starts to build from source... and fails on occasion. So I think wrtc is still not yet in a stable status, but even if it was it is definitely not a small nifty library that can be dragged along anyplace with simple-peer (which is a small and nifty library).

Maybe use peerDependency instead so that if anyone wants to use simple-peer with wrtc it will simple depend on both?

Thanks!

Test failures for where local and remote ports are wrong

This failure happens for me in both wrtc and Firefox. This happens nondeterministically, maybe about 2/3 of the time with wrtc and 1/2 of the time with Firefox.

Sample wrtc test failure:

paul ~/repos/simple-peer master $ npm run test-node

> [email protected] test-node /Users/paul/repos/simple-peer
> echo 'DISABLED' && tape test/*.js

DISABLED
TAP version 13
# get config
# detect WebRTC support
ok 1 builtin webrtc support
# signal event gets emitted
ok 2 got signal event
# data send/receive text
ok 3 (unnamed assert)
ok 4 (unnamed assert)
ok 5 peer1 is initiator
ok 6 peer2 is not initiator
not ok 7 should be equal
  ---
    operator: equal
    expected: '192.168.0.2'
    actual:   '10.100.1.6'
    at: Peer.tryTest (/Users/paul/repos/simple-peer/test/basic.js:58:7)
  ...
not ok 8 should be equal
  ---
    operator: equal
    expected: 60221
    actual:   58969
    at: Peer.tryTest (/Users/paul/repos/simple-peer/test/basic.js:59:7)
  ...
not ok 9 should be equal
  ---
    operator: equal
    expected: '192.168.0.2'
    actual:   '10.100.1.6'
    at: Peer.tryTest (/Users/paul/repos/simple-peer/test/basic.js:61:7)
  ...
not ok 10 should be equal
  ---
    operator: equal
    expected: 62750
    actual:   58971
    at: Peer.tryTest (/Users/paul/repos/simple-peer/test/basic.js:62:7)
  ...
ok 11 (unnamed assert)
ok 12 (unnamed assert)
ok 13 (unnamed assert)
ok 14 (unnamed assert)
ok 15 got correct message
ok 16 got correct message
ok 17 both peers closed
# sdpTransform function is called
ok 18 got a string as SDP
# get config
# data send/receive Uint8Array
ok 19 data is Buffer
ok 20 got correct message
ok 21 data is Buffer
ok 22 got correct message
ok 23 both peers closed
# data send/receive Buffer
ok 24 data is Buffer
ok 25 got correct message
ok 26 data is Buffer
ok 27 got correct message
ok 28 both peers closed
# data send/receive ArrayBuffer
ok 29 data is Buffer
ok 30 got correct message
ok 31 data is Buffer
ok 32 got correct message
ok 33 both peers closed
# get config
# duplex stream: send data before "connect" event
ok 34 got peer1 "finish"
ok 35 (unnamed assert)
ok 36 got correct message
ok 37 got peer1 "end"
ok 38 (unnamed assert)
ok 39 got peer2 "finish"
ok 40 (unnamed assert)
ok 41 got peer2 "end"
ok 42 (unnamed assert)
# duplex stream: send data one-way
ok 43 got peer1 "finish"
ok 44 (unnamed assert)
ok 45 got correct message
ok 46 got peer1 "end"
ok 47 (unnamed assert)
ok 48 got peer2 "finish"
ok 49 (unnamed assert)
ok 50 got peer2 "end"
ok 51 (unnamed assert)
# get config
# disable trickle
ok 52 only one `signal` event
ok 53 only one `signal` event
ok 54 peer1 is initiator
ok 55 peer2 is not initiator
ok 56 got correct message
ok 57 got correct message
ok 58 both peers closed
# disable trickle (only initiator)
ok 59 only one `signal` event for initiator
ok 60 at least one `signal` event for receiver
ok 61 peer1 is initiator
ok 62 peer2 is not initiator
ok 63 got correct message
ok 64 got correct message
ok 65 both peers closed
# disable trickle (only receiver)
ok 66 at least one `signal` event for initiator
ok 67 only one `signal` event for receiver
ok 68 peer1 is initiator
ok 69 peer2 is not initiator
ok 70 got correct message
ok 71 got correct message
ok 72 both peers closed

1..72
# tests 72
# pass  68
# fail  4

Sample Firefox failure:

unreachable code after return statement client.js:6610:4
mutating the [[Prototype]] of an object will cause your code to run very slowly; instead create the object with the correct initial [[Prototype]] value using Object.create client.js:1045:3
TAP version 13 client.js:11280:16
# get config client.js:11280:16
# detect WebRTC support client.js:11280:16
ok 1 builtin webrtc support client.js:11280:16
ok 2 should not be equal client.js:11280:16
# signal event gets emitted client.js:11280:16
WebRTC interfaces with the "moz" prefix (mozRTCPeerConnection, mozRTCSessionDescription, mozRTCIceCandidate) have been deprecated. test-bundle.js:11:5306
ok 3 got signal event client.js:11280:16
# data send/receive text client.js:11280:16
ok 4 (unnamed assert) client.js:11280:16
ok 5 (unnamed assert) client.js:11280:16
ok 6 peer1 is initiator client.js:11280:16
ok 7 peer2 is not initiator client.js:11280:16
not ok 8 should be equal client.js:11280:16
  --- client.js:11280:16
    operator: equal client.js:11280:16
    expected: '192.168.0.2' client.js:11280:16
    actual:   '10.100.1.6' client.js:11280:16
  ... client.js:11280:16
not ok 9 should be equal client.js:11280:16
  --- client.js:11280:16
    operator: equal client.js:11280:16
    expected: 49554 client.js:11280:16
    actual:   62468 client.js:11280:16
  ... client.js:11280:16
not ok 10 should be equal client.js:11280:16
  --- client.js:11280:16
    operator: equal client.js:11280:16
    expected: undefined client.js:11280:16
    actual:   '10.100.1.6' client.js:11280:16
  ... client.js:11280:16
not ok 11 should be equal client.js:11280:16
  --- client.js:11280:16
    operator: equal client.js:11280:16
    expected: undefined client.js:11280:16
    actual:   56551 client.js:11280:16
  ... client.js:11280:16
not ok 12 (unnamed assert) client.js:11280:16
  --- client.js:11280:16
    operator: ok client.js:11280:16
    expected: true client.js:11280:16
    actual:   false client.js:11280:16
  ... client.js:11280:16
peer1.remoteFamily is undefined test-bundle.js:9687:0

Add testling badge back

Apparently testling should support testing webrtc code. From irc:

5:37 PM <feross> substack, pkrumins_: new question. i'm trying to test webrtc data channels code and it's failing https://ci.testling.com/feross/simple-peer
5:38 PM <feross> i think that's because the headless browser doesn't have webrtc compiled in, but that's just a guess
5:38 PM <feross> how are you launching chrome/firefox etc. on the remote testling service?
5:38 PM <feross> the remote service is not open source, right? otherwise, i'd just take a look for myself
5:41 PM <substack> it's not headless, it's an actual browser running on windows

Create renegotiation method

This should allow us to:

  • expose method to add streams .addStream #50
  • allow mutes and video interruption on the source side

@feross has any work been initiated regarding renegotiation?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.