This content originally appeared on DEV Community and was authored by Deepak
we talk about web rtc communication to like video
calling web application, audio calling application using simple peer.
npm install simple-peer
simple peer library directly communicate with browser without any extra library or api.
server.js
io.on('connection', function(socket){
debug('a user connected');
io.emit('peer', {
peerId: socket.id
})
socket.on('disconnect', reason => {
io.emit('unpeer', {
peerId: socket.id,
reason
})
})
socket.on('signal', msg => {
debug('signal received', msg)
const receiverId = msg.to
const receiver = io.sockets.connected[receiverId]
if (receiver) {
const data = {
from: socket.id,
...msg
}
debug('sending signal to', receiverId)
io.to(receiverId).emit('signal', data);
} else {
debug('no receiver found', receiverId)
}
})
});
client.js
import React, { Component } from 'react';
import Peer from 'simple-peer'
import io from 'socket.io-client'
const debug = require('debug')('screen-share:app')
const ioUrl = 'http://localhost:4000/'
const enableTrickle = true
class App extends Component {
state = {
peers: {},
stream: null
}
constructor() {
super()
this.onMedia = this.onMedia.bind(this)
this.createPeer = this.createPeer.bind(this)
this.getMedia(this.onMedia, err => {
this.setState({
mediaErr: 'Could not access webcam'
})
debug('getMedia error', err)
})
}
componentDidUpdate() {
if (this.stream && this.video && !this.video.srcObject) {
debug('set video stream', this.video, this.stream)
this.video.srcObject = this.stream
}
this.attachPeerVideos()
}
attachPeerVideos() {
Object.entries(this.state.peers).forEach(entry => {
const [peerId, peer] = entry
if (peer.video && !peer.video.srcObject && peer.stream) {
debug('setting peer video stream', peerId, peer.stream)
peer.video.setAttribute('data-peer-id', peerId)
peer.video.srcObject = peer.stream
}
})
}
getMedia(callback, err) {
const options = { video: true, audio: true }
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
return navigator.mediaDevices.getUserMedia(options)
.then(stream => callback(stream))
.catch(e => err(e))
}
return navigator.getUserMedia(options, callback, err)
}
onMedia(stream) {
this.stream = stream
this.forceUpdate() // we have stream
this.socket = io(ioUrl)
this.socket.on('peer', msg => {
const peerId = msg.peerId
debug('new peer poof!', peerId)
if (peerId === this.socket.id) {
return debug('Peer is me :D', peerId)
}
this.createPeer(peerId, true, stream)
})
this.socket.on('signal', data => {
const peerId = data.from
const peer = this.state.peers[peerId]
if (!peer) {
this.createPeer(peerId, false, stream)
}
debug('Setting signal', peerId, data)
this.signalPeer(this.state.peers[peerId], data.signal)
})
this.socket.on('unpeer', msg => {
debug('Unpeer', msg)
this.destroyPeer(msg.peerId)
})
}
createPeer(peerId, initiator, stream) {
debug('creating new peer', peerId, initiator)
const peer = new Peer({initiator: initiator, trickle: enableTrickle, stream})
peer.on('signal', (signal) => {
const msgId = (new Date().getTime())
const msg = { msgId, signal, to: peerId }
debug('peer signal sent', msg)
this.socket.emit('signal', msg)
})
peer.on('stream', (stream) => {
debug('Got peer stream!!!', peerId, stream)
peer.stream = stream
this.setPeerState(peerId, peer)
})
peer.on('connect', () => {
debug('Connected to peer', peerId)
peer.connected = true
this.setPeerState(peerId, peer)
peer.send(this.serialize({
msg: 'hey man!'
}))
})
peer.on('data', data => {
debug('Data from peer', peerId, this.unserialize(data))
})
peer.on('error', (e) => {
debug('Peer error %s:', peerId, e);
})
this.setPeerState(peerId, peer)
return peer
}
destroyPeer(peerId) {
const peers = {...this.state.peers}
delete peers[peerId]
this.setState({
peers
})
}
serialize(data) {
return JSON.stringify(data)
}
unserialize(data) {
try {
return JSON.parse(data.toString())
} catch(e) {
return undefined
}
}
setPeerState(peerId, peer) {
const peers = {...this.state.peers}
peers[peerId] = peer
this.setState({
peers
})
}
signalPeer(peer, data) {
try {
peer.signal(data)
} catch(e) {
debug('sigal error', e)
}
}
renderPeers() {
return Object.entries(this.state.peers).map(entry => {
const [peerId, peer] = entry
debug('render peer', peerId, peer, entry)
return <div key={peerId}>
<video ref={video => peer.video = video}></video>
</div>
})
}
render() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">WebRTC Video Chat</h1>
</header>
{this.state.mediaErr && (
<p className="error">{this.state.mediaErr}</p>
)}
<div id="me">
<video id="myVideo" ref={video => this.video = video} controls></video>
</div>
<div id="peers">{this.renderPeers()}</div>
</div>
);
}
}
export default App;
This content originally appeared on DEV Community and was authored by Deepak
Deepak | Sciencx (2022-01-08T04:18:08+00:00) video calling App in React JS using Simple Peer. Retrieved from https://www.scien.cx/2022/01/08/video-calling-app-in-react-js-using-simple-peer/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.