Getting Started with Webrtc Video Communications

Getting Started with Webrtc Video Communications


WebRTC, named after Web Instant Messaging, is an open source W3C recommendation that was incorporated into the World Wide Web Consortium with the support of Google, Mozilla and Opera on June 1, 2011. It solves the problem of web browsers having real-time voice or video conversations.

For reprinting, please indicate the source: https://blog.csdn.net/a1151879477/article/details/97363772

development environment

  • The latest version of Google Browser, now 75.0.3770.142
  • An Android phone with the latest version of Google Browser installed
  • One external network server,
  • The websocket section uses the swoft php framework

Reference Links
https://www.cnblogs.com/fangkm/p/4364553.html In this article, the browser implementation of the specific process of network penetration is described.

https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection This is the API document for webrtc

The most important flowchart in the first article is:

  • Step 1: Create a Connection object, which is one of the important objects in webrtc Api
/*
 * Create connection object
 */
function createPeerConnection() {
  var mediaConstraints = {};
  return new RTCPeerConnection({
      iceServers: [
        {"urls":["stun:stun.l.google.com:19302"]}
      ]
  }, mediaConstraints);
}
    
var localClient = createPeerConnection();
var answerClient = createPeerConnection();

Step 2: Get the camera, microphone stream, echo after capture, and add stream like Connection object

navigator.mediaDevices.getUserMedia(mediaConstraints).then(localStream => {
 let localVideo = document.getElementById("local_video");
  //Set Echo
  localVideo.srcObject = localStream;
  localVideo.onloadedmetadata = function (e) {
      localVideo.play();
  };
  localVideo.volume = 0.0;
  
  console.log(localStream.getTracks());
  localStream.getTracks().forEach(track => localClient.addTrack(track, localStream));
});

Step 3: Create a Session and send the offer to a remote user

localClient.createOffer()
                .then(offer => {
                    localClient.setLocalDescription(offer)
                        .then(() => {
                            // Send offer to called
                            ws.send('user.offer:' + JSON.stringify({
                                user_id: getUserId(),
                                connectUserId: $this.data('id'),
                                offer: offer
                            }))
                        })
                })

Step 4 (Callee): Set the offer into the remoteDescription, generate the called answer, and send the called generated answer to the caller

const sessionDescription = new RTCSessionDescription(offer);
//Since the received format is json, it needs to be converted to RTCSessionDescription before it can be set successfully
answerClient.setRemoteDescription(sessionDescription);
answerClient.createAnswer()
    .then(answer => {
        answerClient.setLocalDescription(answer)
            .then(() => {
                //Send to caller answer
                ws.send('user.answer:' + JSON.stringify({
                    user_id: getUserId(),
                    answer: answer,
                    connectUserId: msg.connectUserId
                }))
            })
    });

Step 5 (Caller): Called offer sets remoteDescription in the same way

localClient.setRemoteDescription(new RTCSessionDescription(answer));

Step 6 (Caller): At this point the caller triggers the onicecandidate event, where it automatically retrieves information such as its server ip port and needs to be sent to the caller

answerClient.onicecandidate = function (e) {
    if (e.candidate) {
        ws.send('user.candidate:', JSON.stringify({
            user_id: getUserId(),
            candidateType: 'answerClient',
            connectUserId: remoteUserId,
            candidate: e.candidate
        }))
    }
    console.log('answerClient is on icecandidate');
};

Step 7 (Called): Called to receive candidate, call addIceCandidate() to record candidate, will also trigger the called onicecandidate event, need to do the same action to send to the caller, the caller also calls the addIceCandidate method to record information, when both network environments can penetrateThe ontrack method is called, and the steam stream is added to the video tag in the event event received.

// Call addIceCandidate
if (candidate.candidateType === 'officeClient') {
    answerClient.addIceCandidate(candidate)
} else {
    localClient.addIceCandidate(candidate)
}
answerClient.onicecandidate = function (e) {
    if (e.candidate) {
        ws.send('user.candidate:', JSON.stringify({
            user_id: getUserId(),
            candidateType: 'answerClient',
            connectUserId: remoteUserId,
            candidate: e.candidate
        }))


    }
    console.log('answerClient is on icecandidate');
};


localClient.onicecandidate = function (e) {
   if (e.candidate) {
       ws.send('user.candidate:', JSON.stringify({
           user_id: getUserId(),
           candidateType: 'offerClient',
           connectUserId: remoteUserId,
           candidate: e.candidate
       }))
   }
   console.log('answerClient is on icecandidate');
};

answerClient.ontrack = function (e) {
    remoteVideo.srcObject = e.streams[0];
};

localClient.ontrack = function(e){
    remoteVideo.srcObject = e.streams[0];
};

Issues found
Sometimes it fails to penetrate
Need to click on each other twice to display the picture, there is no picture on his side, at present there is no reason to find and need to continue to improve

GitHub address: https://github.com/meiyoufengzhengdexian/webrtc-demo

Tags: JSON Google network github

Posted on Thu, 25 Jul 2019 23:09:10 -0400 by genistaff