{"_id":"simple-peer-light","_rev":"2-2f4667f40d2d287a013b1c74fc8e5c61","name":"simple-peer-light","dist-tags":{"latest":"9.10.0"},"versions":{"1.0.0":{"name":"simple-peer-light","description":"Simple, light-weight WebRTC video/voice and data channels","version":"1.0.0","author":{"name":"Gregor Mitscha-Baude","email":"gregor.mitscha-baude@gmx.at"},"bugs":{"url":"https://github.com/mitschabaude/simple-peer-light/issues"},"dependencies":{},"devDependencies":{"airtap":"^3.0.0","babel-minify":"^0.5.1","bowser":"^2.11.0","browserify":"^17.0.0","coveralls":"^3.1.0","nyc":"^15.1.0","prettier-bytes":"^1.0.4","simple-get":"^4.0.0","speedometer":"^1.1.0","standard":"*","string-to-stream":"^3.0.1","tape":"^5.0.1","thunky":"^1.1.0","wrtc":"^0.4.6","ws":"^7.3.1"},"keywords":["data","data channel","data channel stream","data channels","p2p","peer","peer","peer-to-peer","stream","video","voice","webrtc","webrtc stream"],"license":"MIT","main":"index.js","repository":{"type":"git","url":"git://github.com/mitschabaude/simple-peer-light.git"},"scripts":{"build":"minify index.js --sourceType module --outFile simplepeer.min.js","build-browserify":"browserify -s SimplePeer -r . | minify > simplepeer.min.js","size":"npm run build && cat simplepeer.min.js | gzip | wc -c","test":"standard && npm run test-node && npm run test-browser","test-browser":"airtap --coverage -- test/*.js","test-browser-local":"airtap --coverage --local -- test/*.js","test-node":"WRTC=wrtc tape test/*.js","coverage":"nyc report --reporter=text-lcov | coveralls"},"gitHead":"17df15cac5c1bbb412575d008df8e93c85e1ca39","homepage":"https://github.com/mitschabaude/simple-peer-light#readme","_id":"simple-peer-light@1.0.0","_nodeVersion":"14.15.3","_npmVersion":"6.14.8","dist":{"integrity":"sha512-F5tPuIb4j0Sjv9ZK1w57iaqCeGcf3s8XgZEUKR0LE710TxutBd4yzqGyLMA+Vg5anMwi9oyWOld9xL4aMSwLyA==","shasum":"2a9b478cf70d8f7e8885f7ba3544877dd6377582","tarball":"https://registry.npmjs.org/simple-peer-light/-/simple-peer-light-1.0.0.tgz","fileCount":9,"unpackedSize":71056,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJf9ColCRA9TVsSAnZWagAAWPEP/11LwINJoAcLvgJmq1gP\nd8UaepZYAFAlKOSWXl22MhxszhwTfSaoJhogykFLAIXSoxFhMIJjxkb22Itx\n6L2rdQARF88vr2d9BkF+dA18jmo+V3ugjFVagvLzMIXYNUjSUeLdGahRsgx7\nCyqZ6XyH0dx+k4dDHO3PM1ZEAvW1Tj7MCyAHSm80Gamw60wiol3nJlHW5azK\nb9FYzmRLKjrVGbOXSWypxQGHvLHtab1gsqdkHfb9RGQtO2rkDEh90sewg3Y0\nducmXyr09wkOLP6satHKPetbBPPPHck37NTmGS5xfZZNfFCHkNKhVSVU3HG7\nj1MXvfY+WtLLZ9C03Q45DLNrBihIL0o1RHw12JjwR4dmsTnlaoQUpVqoO6iJ\nxx1UmY+zP7+GiPLHNG4GWXY8B9Nd8bvr3GzuDZ8PRM4Hg0QiYJLULFb2PGby\n4uvMEUHYEw6eGXCsL/fKhAFVeEdKNZsLn9hnV0984R1YZIeAUA11aryIkYrZ\nE3JZYt+41bzDyE3WAn9GSq4U+uqE+YXrPtO9dYLpbVSjj/qkA98O6TffmJ0g\ncxi26IGyjczPjUZEYlm+b/gJRxNRCA1WZw/TaOeYQuqLvGLsW7IQfZieTp6J\n7CTXGssQsWp67RKk6HkY96zUEkZcA2bM9voIe7pDCTl5ktzwmqOqg3ldolh6\nOnNy\r\n=cvR9\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDHDL0mSFwKLEEr6bN7qCMCR86GwZ10JysvdqeEcSOICQIhAISYdFDCeooIbUBmckLwX1JCZUGYwcz0QQnIDyKnR2yh"}]},"_npmUser":{"name":"mitschabaude","email":"gregor.mitscha-baude@gmx.at"},"directories":{},"maintainers":[{"name":"mitschabaude","email":"gregor.mitscha-baude@gmx.at"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/simple-peer-light_1.0.0_1609837092800_0.36770580906786354"},"_hasShrinkwrap":false},"9.10.0":{"name":"simple-peer-light","description":"Simple, light-weight WebRTC video/voice and data channels","version":"9.10.0","author":{"name":"Gregor Mitscha-Baude","email":"gregor.mitscha-baude@gmx.at"},"bugs":{"url":"https://github.com/mitschabaude/simple-peer-light/issues"},"dependencies":{},"devDependencies":{"airtap":"^3.0.0","babel-minify":"^0.5.1","bowser":"^2.11.0","browserify":"^17.0.0","coveralls":"^3.1.0","nyc":"^15.1.0","prettier-bytes":"^1.0.4","simple-get":"^4.0.0","speedometer":"^1.1.0","standard":"*","string-to-stream":"^3.0.1","tape":"^5.0.1","thunky":"^1.1.0","wrtc":"^0.4.6","ws":"^7.3.1"},"keywords":["data","data channel","data channel stream","data channels","p2p","peer","peer","peer-to-peer","stream","video","voice","webrtc","webrtc stream"],"license":"MIT","main":"index.js","repository":{"type":"git","url":"git://github.com/mitschabaude/simple-peer-light.git"},"scripts":{"build":"minify index.js --sourceType module --outFile simplepeer.min.js","build-browserify":"browserify -s SimplePeer -r . | minify > simplepeer.min.js","size":"npm run build && cat simplepeer.min.js | gzip | wc -c","// test":"standard && npm run test-node && npm run test-browser","test":"standard && npm run test-node","test-browser":"airtap --coverage -- test/*.js","test-browser-local":"airtap --coverage --local -- test/*.js","test-node":"WRTC=wrtc tape test/*.js","coverage":"nyc report --reporter=text-lcov | coveralls"},"gitHead":"719a9cbb2239c96c7e7ce5e227882acd56505915","homepage":"https://github.com/mitschabaude/simple-peer-light#readme","_id":"simple-peer-light@9.10.0","_nodeVersion":"14.16.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-E0INlXmVy2XvVkyMallKYQlcTAD8S0ov+goSVDGD2k9vwkjBCOyFmESoUsv0Pi7P3nSh6TuMIIi+S/YRok9WLg==","shasum":"6f3699b80e4b6d3a9374a865e1a8e497aa623afb","tarball":"https://registry.npmjs.org/simple-peer-light/-/simple-peer-light-9.10.0.tgz","fileCount":9,"unpackedSize":73788,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgWGgZCRA9TVsSAnZWagAARnAP/3kv32FH8O5FZJOrWiY/\n7xJe9PQ3feGZcxhxhxGTzpTtq9EdeEsGDW5se4rP3BHmxPqNxEV9wTjG96Q0\nenDjTmjpklB34roU2D/75hBt0nkU7tP3WTwUUIU1o43d13JO8kcK/7OMuzeV\noR8zL1ZU5jHZOPivJ07HdU+/YGt7djwZgdsnUM0lRA5IJC0aEX8vb04/lai/\nyZQxySU4PjZ3TZvH3Ne7KEMMbedMlXEDeE9SJNyqCiA+yu+yiGzM4BM0MouU\nuCJlatfqcqXrcBj4JNTvjW1LqUI1MbDvB5IH3Rg6dhVvspLyisIRajt7EGkx\nqJLwfZTP1I/ic2F/2nuhCmJtiiYv+8UOwxXfrMgcq6kh3GsFdQNCJcWSDk+J\nPD6tAwH4FqROz9d/zdiAUDHnwZteaPdix6q/EL/StauKpAExrlztTHVuZtBs\n1G0UCg6M5f3hg8q5iwBVnHb5h3jSdb91hdg148DotRpZTFfjL6oqrDcXOJv0\nQmtNVWJVhCO5eXHRkeW11rfXab20TM1vT1Te+2AIxUjI7V0yYHm9oFAxO1Rd\nJFGn96NNwkf1tepPcZ3J5MGy0HjiwCiLKkBdhInNBZOJqd8Clqwy1Y+nHE9m\nSyyQ6aY1i96XPWBaMYDxfuflulfYuNrhQsFU2Kec2gj0yHCy2f89+P1vlI0W\nMyPi\r\n=0U9u\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCnup9rVt/xZzZTKFQYPuXPs2o9eI7TpS4uQduunEnsLgIgHu0bvQdC2Ysclr9bNU8TkaAMsAMAgCjW4W/rb/5c99s="}]},"_npmUser":{"name":"mitschabaude","email":"gregor.mitscha-baude@gmx.at"},"directories":{},"maintainers":[{"name":"mitschabaude","email":"gregor.mitscha-baude@gmx.at"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/simple-peer-light_9.10.0_1616406552551_0.34548043569566556"},"_hasShrinkwrap":false}},"time":{"created":"2021-01-05T08:58:12.800Z","1.0.0":"2021-01-05T08:58:12.947Z","modified":"2022-05-17T21:32:49.727Z","9.10.0":"2021-03-22T09:49:12.746Z"},"maintainers":[{"name":"mitschabaude","email":"gregor.mitscha-baude@gmx.at"}],"description":"Simple, light-weight WebRTC video/voice and data channels","homepage":"https://github.com/mitschabaude/simple-peer-light#readme","keywords":["data","data channel","data channel stream","data channels","p2p","peer","peer","peer-to-peer","stream","video","voice","webrtc","webrtc stream"],"repository":{"type":"git","url":"git://github.com/mitschabaude/simple-peer-light.git"},"author":{"name":"Gregor Mitscha-Baude","email":"gregor.mitscha-baude@gmx.at"},"bugs":{"url":"https://github.com/mitschabaude/simple-peer-light/issues"},"license":"MIT","readme":"# simple-peer-light [![npm][npm-image]][npm-url] [![downloads][downloads-image]][downloads-url] [![javascript style guide][standard-image]][standard-url]\n\n[npm-image]: https://img.shields.io/npm/v/simple-peer-light.svg\n[npm-url]: https://npmjs.org/package/simple-peer-light\n[downloads-image]: https://img.shields.io/npm/dm/simple-peer-light.svg\n[downloads-url]: https://npmjs.org/package/simple-peer-light\n[standard-image]: https://img.shields.io/badge/code_style-standard-brightgreen.svg\n[standard-url]: https://standardjs.com\n\nThis is a light-weight, browser-friendly fork of [feross/simple-peer](https://github.com/feross/simple-peer):\n\n- Zero external dependencies\n- Bundle size reduced from 28 kB to **5 kB** (minified, gzipped)\n- Can be directly imported in a `<script type=\"module\">` without bundling\n\n**Caveats compared to [feross/simple-peer](https://github.com/feross/simple-peer)**\n\n- _No stream API._ The `Peer` class does not inherit from `Duplex`. Instead, it has only the essential `EventEmitter` methods `.on()`, `.off()`, `.once()` and `.emit()`.\n- _Browser only._ Because `index.js` uses an ESM export instead of CJS, it does not work in node.\n- _No tests._ Browser tests can't be run because they rely on CJS. However, the tests were updated to reflect the API changes and they all pass if a CJS export is used in `index.js`.\n\nThe documentation below is updated to reflect these changes.\n\nRegarding ongoing development in `simple-peer`, the strategy for this repo is to keep merging in upstream changes while maintaining the initial diff. We will update the npm package accordingly and our versioning will track the version of `simple-peer` 1:1, to make it obvious at what point of the release history we are.\n\n## features\n\n- concise, **node.js style** API for [WebRTC](https://en.wikipedia.org/wiki/WebRTC)\n- supports **video/voice streams**\n- supports **data channel**\n  - text and binary data\n- supports advanced options like:\n\n  - enable/disable [trickle ICE candidates](http://webrtchacks.com/trickle-ice/)\n  - manually set config options\n  - transceivers and renegotiation\n\n- [install](#install)\n- [examples](#usage)\n  - [A simpler example](#a-simpler-example)\n  - [data channels](#data-channels)\n  - [video/voice](#videovoice)\n  - [dynamic video/voice](#dynamic-videovoice)\n- [api](#api)\n- [error codes](#error-codes)\n- [connecting more than 2 peers?](#connecting-more-than-2-peers)\n- [memory usage](#memory-usage)\n- [connection does not work on some networks?](#connection-does-not-work-on-some-networks)\n- [license](#license)\n\n## install\n\n```\nnpm install simple-peer-light\n```\n\nThis package works in the browser without modification. The `simplepeer.min.js` script is just a minified version for usage without a build pipeline.\n\n## usage\n\nLet's create an html page that lets you manually connect two peers:\n\n```html\n<html>\n  <body>\n    <style>\n      #outgoing {\n        width: 600px;\n        word-wrap: break-word;\n        white-space: normal;\n      }\n    </style>\n    <form>\n      <textarea id=\"incoming\"></textarea>\n      <button type=\"submit\">submit</button>\n    </form>\n    <pre id=\"outgoing\"></pre>\n    <script type=\"module\">\n      import Peer from './simplepeer.min.js';\n      const p = new Peer({\n        initiator: location.hash === '#1',\n        trickle: false,\n      });\n\n      p.on('error', err => console.log('error', err));\n\n      p.on('signal', data => {\n        console.log('SIGNAL', JSON.stringify(data));\n        document.querySelector('#outgoing').textContent = JSON.stringify(data);\n      });\n\n      document.querySelector('form').addEventListener('submit', ev => {\n        ev.preventDefault();\n        p.signal(JSON.parse(document.querySelector('#incoming').value));\n      });\n\n      p.on('connect', () => {\n        console.log('CONNECT');\n        p.send('whatever' + Math.random());\n      });\n\n      p.on('data', data => {\n        console.log('data: ' + data);\n      });\n    </script>\n  </body>\n</html>\n```\n\nVisit `index.html#1` from one browser (the initiator) and `index.html` from another\nbrowser (the receiver).\n\nAn \"offer\" will be generated by the initiator. Paste this into the receiver's form and\nhit submit. The receiver generates an \"answer\". Paste this into the initiator's form and\nhit submit.\n\nNow you have a direct P2P connection between two browsers!\n\n### A simpler example\n\nThis example create two peers **in the same web page**.\n\nIn a real-world application, _you would never do this_. The sender and receiver `Peer`\ninstances would exist in separate browsers. A \"signaling server\" (usually implemented with\nwebsockets) would be used to exchange signaling data between the two browsers until a\npeer-to-peer connection is established.\n\n### data channels\n\n```js\nimport Peer from 'simple-peer-light';\n\nvar peer1 = new Peer({initiator: true});\nvar peer2 = new Peer();\n\npeer1.on('signal', data => {\n  // when peer1 has signaling data, give it to peer2 somehow\n  peer2.signal(data);\n});\n\npeer2.on('signal', data => {\n  // when peer2 has signaling data, give it to peer1 somehow\n  peer1.signal(data);\n});\n\npeer1.on('connect', () => {\n  // wait for 'connect' event before using the data channel\n  peer1.send('hey peer2, how is it going?');\n});\n\npeer2.on('data', data => {\n  // got a data channel message\n  console.log('got a message from peer1: ' + data);\n});\n```\n\n### video/voice\n\nVideo/voice is also super simple! In this example, peer1 sends video to peer2.\n\n```js\nimport Peer from 'simple-peer-light';\n\n// get video/voice stream\nnavigator.mediaDevices\n  .getUserMedia({\n    video: true,\n    audio: true,\n  })\n  .then(gotMedia)\n  .catch(() => {});\n\nfunction gotMedia(stream) {\n  var peer1 = new Peer({initiator: true, stream: stream});\n  var peer2 = new Peer();\n\n  peer1.on('signal', data => {\n    peer2.signal(data);\n  });\n\n  peer2.on('signal', data => {\n    peer1.signal(data);\n  });\n\n  peer2.on('stream', stream => {\n    // got remote video stream, now let's show it in a video tag\n    var video = document.querySelector('video');\n\n    if ('srcObject' in video) {\n      video.srcObject = stream;\n    } else {\n      video.src = window.URL.createObjectURL(stream); // for older browsers\n    }\n\n    video.play();\n  });\n}\n```\n\nFor two-way video, simply pass a `stream` option into both `Peer` constructors. Simple!\n\nPlease notice that `getUserMedia` only works in [pages loaded via **https**](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia#Encryption_based_security).\n\n### dynamic video/voice\n\nIt is also possible to establish a data-only connection at first, and later add\na video/voice stream, if desired.\n\n```js\nimport Peer from 'simple-peer-light'; // create peer without waiting for media\n\nvar peer1 = new Peer({initiator: true}); // you don't need streams here\nvar peer2 = new Peer();\n\npeer1.on('signal', data => {\n  peer2.signal(data);\n});\n\npeer2.on('signal', data => {\n  peer1.signal(data);\n});\n\npeer2.on('stream', stream => {\n  // got remote video stream, now let's show it in a video tag\n  var video = document.querySelector('video');\n\n  if ('srcObject' in video) {\n    video.srcObject = stream;\n  } else {\n    video.src = window.URL.createObjectURL(stream); // for older browsers\n  }\n\n  video.play();\n});\n\nfunction addMedia(stream) {\n  peer1.addStream(stream); // <- add streams to peer dynamically\n}\n\n// then, anytime later...\nnavigator.mediaDevices\n  .getUserMedia({\n    video: true,\n    audio: true,\n  })\n  .then(addMedia)\n  .catch(() => {});\n```\n\n## api\n\n### `peer = new Peer([opts])`\n\nCreate a new WebRTC peer connection.\n\nA \"data channel\" for text/binary communication is always established, because it's cheap and often useful. For video/voice communication, pass the `stream` option.\n\nIf `opts` is specified, then the default options (shown below) will be overridden.\n\n```\n{\n  initiator: false,\n  channelConfig: {},\n  channelName: '<random string>',\n  config: { iceServers: [{ urls: 'stun:stun.l.google.com:19302' }, { urls: 'stun:global.stun.twilio.com:3478?transport=udp' }] },\n  offerOptions: {},\n  answerOptions: {},\n  sdpTransform: function (sdp) { return sdp },\n  stream: false,\n  streams: [],\n  trickle: true,\n  allowHalfTrickle: false,\n  wrtc: {}, // RTCPeerConnection/RTCSessionDescription/RTCIceCandidate\n}\n```\n\nThe options do the following:\n\n- `initiator` - set to `true` if this is the initiating peer\n- `channelConfig` - custom webrtc data channel configuration (used by [`createDataChannel`](https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/createDataChannel))\n- `channelName` - custom webrtc data channel name\n- `config` - custom webrtc configuration (used by [`RTCPeerConnection`](https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection) constructor)\n- `offerOptions` - custom offer options (used by [`createOffer`](https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/createOffer) method)\n- `answerOptions` - custom answer options (used by [`createAnswer`](https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/createAnswer) method)\n- `sdpTransform` - function to transform the generated SDP signaling data (for advanced users)\n- `stream` - if video/voice is desired, pass stream returned from [`getUserMedia`](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia)\n- `streams` - an array of MediaStreams returned from [`getUserMedia`](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia)\n- `trickle` - set to `false` to disable [trickle ICE](http://webrtchacks.com/trickle-ice/) and get a single 'signal' event (slower)\n- `wrtc` - custom webrtc implementation, mainly useful in node to specify in the [wrtc](https://npmjs.com/package/wrtc) package. Contains an object with the properties:\n  - [`RTCPeerConnection`](https://www.w3.org/TR/webrtc/#dom-rtcpeerconnection)\n  - [`RTCSessionDescription`](https://www.w3.org/TR/webrtc/#dom-rtcsessiondescription)\n  - [`RTCIceCandidate`](https://www.w3.org/TR/webrtc/#dom-rtcicecandidate)\n\n### `peer.signal(data)`\n\nCall this method whenever the remote peer emits a `peer.on('signal')` event.\n\nThe `data` will encapsulate a webrtc offer, answer, or ice candidate. These messages help\nthe peers to eventually establish a direct connection to each other. The contents of these\nstrings are an implementation detail that can be ignored by the user of this module;\nsimply pass the data from 'signal' events to the remote peer and call `peer.signal(data)`\nto get connected.\n\n### `peer.send(data)`\n\nSend text/binary data to the remote peer. `data` can be any of several types: `String`,\n`ArrayBufferView` (`Uint8Array`,\netc.), `ArrayBuffer`, or `Blob` (in browsers that support it).\n\nNote: If this method is called before the `peer.on('connect')` event has fired, then an exception will be thrown.\n\n### `peer.addStream(stream)`\n\nAdd a `MediaStream` to the connection.\n\n### `peer.removeStream(stream)`\n\nRemove a `MediaStream` from the connection.\n\n### `peer.addTrack(track, stream)`\n\nAdd a `MediaStreamTrack` to the connection. Must also pass the `MediaStream` you want to attach it to.\n\n### `peer.removeTrack(track, stream)`\n\nRemove a `MediaStreamTrack` from the connection. Must also pass the `MediaStream` that it was attached to.\n\n### `peer.replaceTrack(oldTrack, newTrack, stream)`\n\nReplace a `MediaStreamTrack` with another track. Must also pass the `MediaStream` that the old track was attached to.\n\n### `peer.addTransceiver(kind, init)`\n\nAdd a `RTCRtpTransceiver` to the connection. Can be used to add transceivers before adding tracks. Automatically called as neccesary by `addTrack`.\n\n### `peer.destroy([err])`\n\nDestroy and cleanup this peer connection.\n\nIf the optional `err` parameter is passed, then it will be emitted as an `'error'`\nevent on the stream.\n\n### `Peer.WEBRTC_SUPPORT`\n\nDetect native WebRTC support in the javascript environment.\n\n```js\nimport Peer from 'simple-peer-light';\n\nif (Peer.WEBRTC_SUPPORT) {\n  // webrtc support!\n} else {\n  // fallback\n}\n```\n\n### `peer.on('signal', data => {})`\n\nFired when the peer wants to send signaling data to the remote peer.\n\n**It is the responsibility of the application developer (that's you!) to get this data to\nthe other peer.** This usually entails using a websocket signaling server. This data is an\n`Object`, so remember to call `JSON.stringify(data)` to serialize it first. Then, simply\ncall `peer.signal(data)` on the remote peer.\n\n(Be sure to listen to this event immediately to avoid missing it. For `initiator: true`\npeers, it fires right away. For `initatior: false` peers, it fires when the remote\noffer is received.)\n\n### `peer.on('connect', () => {})`\n\nFired when the peer connection and data channel are ready to use.\n\n### `peer.on('data', data => {})`\n\nReceived a message from the remote peer (via the data channel).\n\n`data` will be either a `String` or a `Uint8Array`.\n\n### `peer.on('stream', stream => {})`\n\nReceived a remote video stream, which can be displayed in a video tag:\n\n```js\npeer.on('stream', stream => {\n  var video = document.querySelector('video');\n  if ('srcObject' in video) {\n    video.srcObject = stream;\n  } else {\n    video.src = window.URL.createObjectURL(stream);\n  }\n  video.play();\n});\n```\n\n### `peer.on('track', (track, stream) => {})`\n\nReceived a remote audio/video track. Streams may contain multiple tracks.\n\n### `peer.on('close', () => {})`\n\nCalled when the peer connection has closed.\n\n### `peer.on('error', (err) => {})`\n\nFired when a fatal error occurs. Usually, this means bad signaling data was received from the remote peer.\n\n`err` is an `Error` object.\n\n## error codes\n\nErrors returned by the `error` event have an `err.code` property that will indicate the origin of the failure.\n\nPossible error codes:\n\n- `ERR_WEBRTC_SUPPORT`\n- `ERR_CREATE_OFFER`\n- `ERR_CREATE_ANSWER`\n- `ERR_SET_LOCAL_DESCRIPTION`\n- `ERR_SET_REMOTE_DESCRIPTION`\n- `ERR_ADD_ICE_CANDIDATE`\n- `ERR_ICE_CONNECTION_FAILURE`\n- `ERR_SIGNALING`\n- `ERR_DATA_CHANNEL`\n- `ERR_CONNECTION_FAILURE`\n\n## connecting more than 2 peers?\n\nThe simplest way to do that is to create a full-mesh topology. That means that every peer\nopens a connection to every other peer. To illustrate:\n\n![full mesh topology](img/full-mesh.png)\n\nTo broadcast a message, just iterate over all the peers and call `peer.send`.\n\nSo, say you have 3 peers. Then, when a peer wants to send some data it must send it 2\ntimes, once to each of the other peers. So you're going to want to be a bit careful about\nthe size of the data you send.\n\nFull mesh topologies don't scale well when the number of peers is very large. The total\nnumber of edges in the network will be ![full mesh formula](img/full-mesh-formula.png)\nwhere `n` is the number of peers.\n\nFor clarity, here is the code to connect 3 peers together:\n\n#### Peer 1\n\n```js\n// These are peer1's connections to peer2 and peer3\nvar peer2 = new Peer({initiator: true});\nvar peer3 = new Peer({initiator: true});\n\npeer2.on('signal', data => {\n  // send this signaling data to peer2 somehow\n});\n\npeer2.on('connect', () => {\n  peer2.send('hi peer2, this is peer1');\n});\n\npeer2.on('data', data => {\n  console.log('got a message from peer2: ' + data);\n});\n\npeer3.on('signal', data => {\n  // send this signaling data to peer3 somehow\n});\n\npeer3.on('connect', () => {\n  peer3.send('hi peer3, this is peer1');\n});\n\npeer3.on('data', data => {\n  console.log('got a message from peer3: ' + data);\n});\n```\n\n#### Peer 2\n\n```js\n// These are peer2's connections to peer1 and peer3\nvar peer1 = new Peer();\nvar peer3 = new Peer({initiator: true});\n\npeer1.on('signal', data => {\n  // send this signaling data to peer1 somehow\n});\n\npeer1.on('connect', () => {\n  peer1.send('hi peer1, this is peer2');\n});\n\npeer1.on('data', data => {\n  console.log('got a message from peer1: ' + data);\n});\n\npeer3.on('signal', data => {\n  // send this signaling data to peer3 somehow\n});\n\npeer3.on('connect', () => {\n  peer3.send('hi peer3, this is peer2');\n});\n\npeer3.on('data', data => {\n  console.log('got a message from peer3: ' + data);\n});\n```\n\n#### Peer 3\n\n```js\n// These are peer3's connections to peer1 and peer2\nvar peer1 = new Peer();\nvar peer2 = new Peer();\n\npeer1.on('signal', data => {\n  // send this signaling data to peer1 somehow\n});\n\npeer1.on('connect', () => {\n  peer1.send('hi peer1, this is peer3');\n});\n\npeer1.on('data', data => {\n  console.log('got a message from peer1: ' + data);\n});\n\npeer2.on('signal', data => {\n  // send this signaling data to peer2 somehow\n});\n\npeer2.on('connect', () => {\n  peer2.send('hi peer2, this is peer3');\n});\n\npeer2.on('data', data => {\n  console.log('got a message from peer2: ' + data);\n});\n```\n\n## memory usage\n\nIf you call `peer.send(buf)`, `simple-peer-light` is not keeping a reference to `buf`\nand sending the buffer at some later point in time. We immediately call\n`channel.send()` on the data channel. So it should be fine to mutate the buffer\nright afterward.\n\n## connection does not work on some networks?\n\nIf a direct connection fails, in particular, because of NAT traversal and/or firewalls,\nWebRTC ICE uses an intermediary (relay) TURN server. In other words, ICE will first use\nSTUN with UDP to directly connect peers and, if that fails, will fall back to a TURN relay\nserver.\n\nIn order to use a TURN server, you must specify the `config` option to the `Peer`\nconstructor. See the API docs above.\n\n[![js-standard-style](https://cdn.rawgit.com/feross/standard/master/badge.svg)](https://github.com/feross/standard)\n\n## license\n\nMIT. Copyright (c) [Feross Aboukhadijeh](http://feross.org).\n","readmeFilename":"README.md"}