Skip to content

Instantly share code, notes, and snippets.

@emehrkay
Last active May 4, 2021 10:43
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save emehrkay/1ea9a87a91e00b27843d9b71a3cce96c to your computer and use it in GitHub Desktop.
Save emehrkay/1ea9a87a91e00b27843d9b71a3cce96c to your computer and use it in GitHub Desktop.
simple webrtc video
class Video {
constructor(video){
this.video = video;
}
setStream(stream){
console.log('setting stream', stream)
this.video.srcObject = stream;
this.video.play();
}
}
class WS {
constructor(uri, local_video, peer_video){
this.uri = uri;
this.local_video = new Video(local_video);
this.peer_video = new Video(peer_video);
}
async connect(){
this.socket = new WebSocket(this.uri)
this.socket.onmessage = async (resp) => {
console.log('WEBSOCKT', resp)
let data = JSON.parse(resp.data);
switch(data.type){
case 'initiator':
await this.local_conn.connect();
break;
case 'responder':
this.remote_conn.connect(true);
break;
case 'ready_for_offer':
await this.local_conn.createOffer();
break
case 'offer':
this.remote_conn.receiveOffer(data);
break;
case 'answer':
this.local_conn.recieveAnswer(data);
break;
default:
if(data.candidate){
await this.local_conn.ac(data);
await this.remote_conn.ac(data);
}
}
};
this.local_conn = new Connection(this.socket, this.local_video, this.peer_video);
this.remote_conn = new Connection(this.socket, this.local_video, this.peer_video);
}
}
class Connection {
constructor(websocket, local, remote){
this.websocket = websocket;
this.local = local;
this.remote = remote;
}
async connect(recieve_offer=false){
try{
var constraints = {
audio: true,
video: true
};
this.stream = await navigator.mediaDevices.getUserMedia(constraints);
this.peer_conn = new RTCPeerConnection(null);
this.local.setStream(this.stream);
this.peer_conn.addEventListener('icecandidate', (e) => {
console.log('onicecandidate', e)
if(e.candidate){
this.websocket.send(JSON.stringify(e.candidate));
}
});
this.peer_conn.addEventListener('track', (e) => {
console.log('GOT REMOTE SGTREAM ', e)
this.remote.setStream(e.streams[0]);
})
if(recieve_offer){
this.readyForOffer();
}
this.stream.getTracks().forEach((track) => {
console.log('adding track', track)
this.peer_conn.addTrack(track, this.stream);
});
}catch(e){
console.log('CONNE ERR', e)
}
}
async ac(data){
if(this.peer_conn){
await this.peer_conn.addIceCandidate(data)
}
}
async createOffer(){
try{
const options = {
offerToReceiveAudio: 1,
offerToReceiveVideo: 1
};
let offer = await this.peer_conn.createOffer(options);
this.peer_conn.setLocalDescription(offer);
this.websocket.send(JSON.stringify(offer));
}catch(e){
console.warn('create offer err', e)
}
}
readyForOffer(){
const msg = {
'type': 'ready_for_offer'
};
this.websocket.send(JSON.stringify(msg));
}
async receiveOffer(offer){
try{
const desc = new RTCSessionDescription(offer);
await this.peer_conn.setRemoteDescription(desc);
const answer = await this.peer_conn.createAnswer();
this.peer_conn.setLocalDescription(answer);
this.websocket.send(JSON.stringify(answer));
}catch(e){
console.log('rec off err', e)
}
}
async recieveAnswer(answer){
try{
const desc = new RTCSessionDescription(answer);
await this.peer_conn.setRemoteDescription(desc);
console.log('recieved answer', desc)
}catch(e){
console.log('REC ANS ERR', e)
}
}
}
// test usage
(function(){
window.onload = async function(){
URI = location.href.replace('http', 'ws').replace('apartment', 'socket')
let local = document.querySelector('#local');
let remote = document.querySelector('#remote');
let ws = new WS(URI, local, remote);
await ws.connect();
window.ws = ws
console.log(ws)
}
}());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment