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