Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

📡 Simple WebRTC video, voice, and data channels

License

NotificationsYou must be signed in to change notification settings

feross/simple-peer

Repository files navigation

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 thefull job description.

features

  • concise,node.js style API forWebRTC
  • works in node and the browser!
  • supportsvideo/voice streams
  • supportsdata channel
  • supports advanced options like:

This package is used byWebTorrent andmany others.

install

npm install simple-peer

This package works in the browser withbrowserify. Ifyou do not use a bundler, you can use thesimplepeer.min.js standalone scriptdirectly in a<script> tag. This exports aSimplePeer constructor onwindow. Wherever you seePeer in the examples below, substitute that withSimplePeer.

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><textareaid="incoming"></textarea><buttontype="submit">submit</button></form><preid="outgoing"></pre><scriptsrc="simplepeer.min.js"></script><script>constp=newSimplePeer({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>

Visitindex.html#1 from one browser (the initiator) andindex.html from anotherbrowser (the receiver).

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

Now you have a direct P2P connection between two browsers!

A simpler example

This example create two peersin the same web page.

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

data channels

varPeer=require('simple-peer')varpeer1=newPeer({initiator:true})varpeer2=newPeer()peer1.on('signal',data=>{// when peer1 has signaling data, give it to peer2 somehowpeer2.signal(data)})peer2.on('signal',data=>{// when peer2 has signaling data, give it to peer1 somehowpeer1.signal(data)})peer1.on('connect',()=>{// wait for 'connect' event before using the data channelpeer1.send('hey peer2, how is it going?')})peer2.on('data',data=>{// got a data channel messageconsole.log('got a message from peer1: '+data)})

video/voice

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

varPeer=require('simple-peer')// get video/voice streamnavigator.mediaDevices.getUserMedia({video:true,audio:true}).then(gotMedia).catch(()=>{})functiongotMedia(stream){varpeer1=newPeer({initiator:true,stream:stream})varpeer2=newPeer()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 tagvarvideo=document.querySelector('video')if('srcObject'invideo){video.srcObject=stream}else{video.src=window.URL.createObjectURL(stream)// for older browsers}video.play()})}

For two-way video, simply pass astream option into bothPeer constructors. Simple!

Please notice thatgetUserMedia only works inpages loaded viahttps.

dynamic video/voice

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

varPeer=require('simple-peer')// create peer without waiting for mediavarpeer1=newPeer({initiator:true})// you don't need streams herevarpeer2=newPeer()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 tagvarvideo=document.querySelector('video')if('srcObject'invideo){video.srcObject=stream}else{video.src=window.URL.createObjectURL(stream)// for older browsers}video.play()})functionaddMedia(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 inopts.wrtc as a parameter (seethe constructor options):

varPeer=require('simple-peer')varwrtc=require('wrtc')varpeer1=newPeer({initiator:true,wrtc:wrtc})varpeer2=newPeer({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 thestream option.

Ifopts 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 totrue if this is the initiating peer

  • channelConfig - custom webrtc data channel configuration (used bycreateDataChannel)

  • channelName - custom webrtc data channel name

  • config - custom webrtc configuration (used byRTCPeerConnection constructor)

  • offerOptions - custom offer options (used bycreateOffer method)

  • answerOptions - custom answer options (used bycreateAnswer method)

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

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

  • streams - an array of MediaStreams returned fromgetUserMedia

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

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

  • objectMode - set totrue to create the stream inObject Mode. In this mode, incoming string data is not automatically converted toBuffer objects.

peer.signal(data)

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

Thedata will encapsulate a webrtc offer, answer, or ice candidate. These messages helpthe peers to eventually establish a direct connection to each other. The contents of thesestrings 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 callpeer.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 (seebuffer),ArrayBufferView (Uint8Array,etc.),ArrayBuffer, orBlob (in browsers that support it).

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

peer.addStream(stream)

Add aMediaStream to the connection.

peer.removeStream(stream)

Remove aMediaStream from the connection.

peer.addTrack(track, stream)

Add aMediaStreamTrack to the connection. Must also pass theMediaStream you want to attach it to.

peer.removeTrack(track, stream)

Remove aMediaStreamTrack from the connection. Must also pass theMediaStream that it was attached to.

peer.replaceTrack(oldTrack, newTrack, stream)

Replace aMediaStreamTrack with another track. Must also pass theMediaStream that the old track was attached to.

peer.addTransceiver(kind, init)

Add aRTCRtpTransceiver to the connection. Can be used to add transceivers before adding tracks. Automatically called as neccesary byaddTrack.

peer.destroy([err])

Destroy and cleanup this peer connection.

If the optionalerr 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.

varPeer=require('simple-peer')if(Peer.WEBRTC_SUPPORT){// webrtc support!}else{// fallback}

duplex stream

Peer objects are instances ofstream.Duplex. They behave very similarly to anet.Socket from the node corenet module. The duplex stream reads/writes to the datachannel.

varpeer=newPeer(opts)// ... signaling ...peer.write(newBuffer('hey'))peer.on('data',function(chunk){console.log('got a chunk',chunk)})

events

Peer objects are instance ofEventEmitter. Take a look at thenodejs events documentation for more information.

Example of removing all registeredclose-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 tothe other peer. This usually entails using a websocket signaling server. This data is anObject, so remember to callJSON.stringify(data) to serialize it first. Then, simplycallpeer.signal(data) on the remote peer.

(Be sure to listen to this event immediately to avoid missing it. Forinitiator: truepeers, it fires right away. Forinitatior: false peers, it fires when the remoteoffer 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 aString or aBuffer/Uint8Array (seebuffer).

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

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

peer.on('stream',stream=>{varvideo=document.querySelector('video')if('srcObject'invideo){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 anError object.

error codes

Errors returned by theerror event have anerr.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 peeropens a connection to every other peer. To illustrate:

full mesh topology

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

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

Full mesh topologies don't scale well when the number of peers is very large. The totalnumber of edges in the network will befull mesh formulawheren 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 peer3varpeer2=newPeer({initiator:true})varpeer3=newPeer({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 peer3varpeer1=newPeer()varpeer3=newPeer({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 peer2varpeer1=newPeer()varpeer2=newPeer()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 callpeer.send(buf),simple-peer is not keeping a reference tobufand sending the buffer at some later point in time. We immediately callchannel.send() on the data channel. So it should be fine to mutate the bufferright afterward.

However, beware thatpeer.write(buf) (a writable stream method) does not havethe same contract. It will potentially buffer the data and callchannel.send() at a future point in time, so definitely don't assume it'ssafe 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 useSTUN with UDP to directly connect peers and, if that fails, will fall back to a TURN relayserver.

In order to use a TURN server, you must specify theconfig option to thePeerconstructor. See the API docs above.

js-standard-style

Who is usingsimple-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. Seeguide.

  • 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 alternativewith 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.

About

📡 Simple WebRTC video, voice, and data channels

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

 

Packages

No packages published

[8]ページ先頭

©2009-2025 Movatter.jp