Monday, 24 May 2021

WebRTC Video Conference Change the quality of video NodeJS

I am trying to create a video conference app using the tutorial https://youtu.be/DvlyzDZDEq4 . I want to add one feature to change the quality of video( not the resolution of the video ) user can see like we have in YouTube videos auto, high picture quality etc. I am very new to WebRTC and Peer library so any help is appreciated. Thank you.

script.js

const socket = io('/')
const videoGrid = document.getElementById('video-grid')
const myPeer = new Peer(undefined, {
  host: '/',
  port: '3001'
})
const myVideo = document.createElement('video')
myVideo.muted = true
const peers = {}
navigator.mediaDevices.getUserMedia({
  video: true,
  audio: true
}).then(stream => {
  addVideoStream(myVideo, stream)

  myPeer.on('call', call => {
    call.answer(stream)
    const video = document.createElement('video')
    call.on('stream', userVideoStream => {
      addVideoStream(video, userVideoStream)
    })
  })

  socket.on('user-connected', userId => {
    connectToNewUser(userId, stream)
  })
})

socket.on('user-disconnected', userId => {
  if (peers[userId]) peers[userId].close()
})

myPeer.on('open', id => {
  socket.emit('join-room', ROOM_ID, id)
})

function connectToNewUser(userId, stream) {
  const call = myPeer.call(userId, stream)
  const video = document.createElement('video')
  call.on('stream', userVideoStream => {
    addVideoStream(video, userVideoStream)
  })
  call.on('close', () => {
    video.remove()
  })

  peers[userId] = call
}

function addVideoStream(video, stream) {
  video.srcObject = stream
  video.addEventListener('loadedmetadata', () => {
    video.play()
  })
  videoGrid.append(video)
}

room.ejs

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <script>
    const ROOM_ID = "<%= roomId %>"
  </script>
  <script defer src="https://unpkg.com/peerjs@1.2.0/dist/peerjs.min.js"></script>
  <script src="/socket.io/socket.io.js" defer></script>
  <script src="script.js" defer></script>
</head>
<body>
  <div id="video-grid"></div>
</body>
</html>

server.js

const express = require('express')
const app = express()
const server = require('http').Server(app)
const io = require('socket.io')(server)
const { v4: uuidV4 } = require('uuid')

app.set('view engine', 'ejs')
app.use(express.static('public'))

app.get('/', (req, res) => {
  res.redirect(`/${uuidV4()}`)
})

app.get('/:room', (req, res) => {
  res.render('room', { roomId: req.params.room })
})

io.on('connection', socket => {
  socket.on('join-room', (roomId, userId) => {
    socket.join(roomId)
    socket.to(roomId).broadcast.emit('user-connected', userId)

    socket.on('disconnect', () => {
      socket.to(roomId).broadcast.emit('user-disconnected', userId)
    })
  })
})

server.listen(3000)

Updated Script.js

const socket = io('/zoom')
const videoGrid = document.getElementById('video-grid')
const myPeer = new Peer(undefined, {
  host: '/',
  port: '3002'
})
let pc;
const myVideo = document.createElement('video')
myVideo.muted = true
const peers = {}
let myVideoStream;
navigator.mediaDevices.getUserMedia({
  video: true,
  audio: true
}).then(stream => {
  myVideoStream = stream;
  addVideoStream(myVideo, stream,user)
  
  myPeer.on('call', call => {
    call.answer(stream)
    const video = document.createElement('video')
    call.on('stream', userVideoStream => {
      addVideoStream(video, userVideoStream,user)
    })
  })
  socket.on("user-connected", (userId, username) => 
  { console.log("checking "+ username); 
    setTimeout(function () 
    { connectToNewUser(userId, stream); 
      console.log("zoooom "+ username); 
     
    }, 1000); 
  });
  
  let text = $("input");
  // when press enter send message
  $('html').keydown(function (e) {
    if (e.which == 13 && text.val().length !== 0) {
      socket.emit('message', text.val());
      text.val('')
    }
  });
  socket.on("createMessage", (message, username) => {
    //$("ul").append(`<li class="message"><b>${username}</b><br/>${message}</li>`);
    scrollToBottom()
  })
})

socket.on('user-disconnected', (userId, username) => {
  $("ul").append(`<span class="messageHeader"><small>${username} Left Meeting</small></span>`);
  if (peers[userId]) peers[userId].close()
})
const offerOptions = {
  offerToReceiveAudio: 0,
  offerToReceiveVideo: 1
};
myPeer.on('open', id => {
  const servers = null;
  pc1 = new RTCPeerConnection(servers);
  pc1.createOffer({
    offerToReceiveAudio: 0,
    offerToReceiveVideo: 1
  })
      .then((desc)=>{const videobitrate = 20000;
        return pc1.setLocalDescription(desc);
       /* let offer = pc1.localDescription;
        console.log("offer "+pc1.localDescription);
        // Set bandwidth for video
        offer.sdp = offer.sdp.replace(/(m=video.*\r\n)/g, `$1b=AS:125\r\n`);
      pc1.setLocalDescription(offer);*/}).then(()=>{
        let offer = pc1.localDescription;
        console.log("offer "+pc1.localDescription);
        // Set bandwidth for video
        offer.sdp = offer.sdp.replace(/(m=video.*\r\n)/g, `$1b=AS:20000\r\n`);
       return pc1.setLocalDescription(offer);
      }).then(()=>{console.log(pc1.localDescription.sdp)})
      .catch((err)=>{ console.log('Failed to set session description: ' + err);});
  console.log("user mypeer"+user);
  
  socket.emit('join-room', ROOM_ID,id,user);
})

function connectToNewUser(userId, stream) {
  const call = myPeer.call(userId, stream)
  const servers = null;
  pc2 = new RTCPeerConnection(servers);
  pc2.createOffer({
    offerToReceiveAudio: 0,
    offerToReceiveVideo: 1
  })
      .then((desc)=>{const videobitrate = 20000;
        return pc2.setLocalDescription(desc);
       /* let offer = pc1.localDescription;
        console.log("offer "+pc1.localDescription);
        // Set bandwidth for video
        offer.sdp = offer.sdp.replace(/(m=video.*\r\n)/g, `$1b=AS:125\r\n`);
      pc1.setLocalDescription(offer);*/}).then(()=>{
        let offer = pc2.localDescription;
        console.log("offer "+pc2.localDescription);
        // Set bandwidth for video
        offer.sdp = offer.sdp.replace(/(m=video.*\r\n)/g, `$1b=AS:20000\r\n`);
       return pc2.setLocalDescription(offer);
      }).then(()=>{console.log(pc2.localDescription.sdp)})
      .catch((err)=>{ console.log('Failed to set session description: ' + err);});

  const video = document.createElement('video')
  call.on('stream', userVideoStream => {
    addVideoStream(video, userVideoStream,user)
  })
  call.on('close', () => {
    video.remove()
  })

  peers[userId] = call
}

function addVideoStream(video, stream,username) {
  video.srcObject = stream
  console.log("adding video")
  video.addEventListener('loadedmetadata', () => {
    video.play()
  })
  videoGrid.append(video)
  video.insertAdjacentHTML('beforebegin',`<b style="color:white">${username}</b>`);
}

const scrollToBottom = () => {
  var d = $('.main__chat_window');
  d.scrollTop(d.prop("scrollHeight"));
}


const muteUnmute = () => {
  const enabled = myVideoStream.getAudioTracks()[0].enabled;
  if (enabled) {
    myVideoStream.getAudioTracks()[0].enabled = false;
    setUnmuteButton();
  } else {
    setMuteButton();
    myVideoStream.getAudioTracks()[0].enabled = true;
  }
}

const playStop = () => {
  console.log('object')
  let enabled = myVideoStream.getVideoTracks()[0].enabled;
  if (enabled) {
    myVideoStream.getVideoTracks()[0].enabled = false;
    setPlayVideo()
  } else {
    setStopVideo()
    myVideoStream.getVideoTracks()[0].enabled = true;
  }
}

const setMuteButton = () => {
  const html = `
    <i class="fas fa-microphone"></i>
    <span>Mute</span>
  `
  document.querySelector('.main__mute_button').innerHTML = html;
}

const setUnmuteButton = () => {
  const html = `
    <i class="unmute fas fa-microphone-slash"></i>
    <span>Unmute</span>
  `
  document.querySelector('.main__mute_button').innerHTML = html;
}

const setStopVideo = () => {
  const html = `
    <i class="fas fa-video"></i>
    <span>Stop Video</span>
  `
  document.querySelector('.main__video_button').innerHTML = html;
}

const setPlayVideo = () => {
  const html = `
  <i class="stop fas fa-video-slash"></i>
    <span>Play Video</span>
  `
  document.querySelector('.main__video_button').innerHTML = html;
}



from WebRTC Video Conference Change the quality of video NodeJS

No comments:

Post a Comment