WebRtc10: 端对端1v1传输基本流程
媒体能力协商过程
RTCPeerConnection(核心类)
- 基本格式
pc = new RTCPeerConnection([configiration]);
RTCPeerConnection方法分类
- 媒体协商
- Stream/Track
- 传输相关方法
- 统计相关方法
媒体协商过程
协商状态变化
媒体协商方法
- createOffer
- createAnswer
- setLocalDescription
- setRemoeteDescription
createOffer
- 基本格式
aPromise = myPeerConnection.createOffer([options]);
createAnswer
- 基本格式
aPromise = myPeerConnection.createAnswer([options]);
setLocalDescription
- 基本格式
aPromise = myPc.setLocalDescription(sessionDescription);
setRemoeteDescription
- 基本格式
aPromise = myPc.setRemoeteDescription(sessionDescription);
Track方法
- addTrack
- removeTrack
addTrack
- 基本格式
rtpSender = myPc.addTrack(track, stream…); - 参数
track: 添加到RTCPeerConnection中的媒体轨
stream:指定track所在的stream
removeTrack
- 基本格式
myPc.removeTrack(rtpSender);
重要事件
- onnegotiationneeded
- onicecandidate
1:1连接的基本流程
实战:本机内的1:1音视频互通
index.html
<html><head><title>WebRTC PeerConnection</title></head><body><div><video id="localvideo" autoplay playsinline></video><video id="remotevideo" autoplay playsinline></video><div><button id="start">Start</button><button id="call">Call</button><button id="hangup">HangUp</button></div></div><script src="https://webrtc.github.io/adapter/adapter-latest.js"></script><script src="js/main.js"></script></body>
</html>
main.js
'use strict'var localVideo = document.querySelector('video#localVideo');
var remoteVideo = document.querySelector('video#remoteVideo');
var btnStart = document.querySelector('button#start');
var btnCall = document.querySelector('button#call');
var btnHangUp= document.querySelector('button#hangup');var localStream;
var pc1;
var pc2;function gotMediaStream(stream){localVideo.srcObject = stream;localStream = stream;
}function handleError(err){console.log("Failed to call getUserMedia", err);
}function start(){var constraints = {video: true,audio: false }if(!navigator.mediaDevices ||!navigator.mediaDevices.getUserMedia){return;}else {navigator.mediaDevices.getUserMedia(constraints).then(gotMediaStream).catch(handleError);}}function gotAnswerDescription(desc){pc2.setLocalDescription(desc);//send sdp to caller//recieve sdp from calleepc1.setRemoteDescription(desc);}function gotLocalDescription(desc){pc1.setLocalDescription(desc);//send sdp to callee//receive sdp from caller pc2.setRemoteDescription(desc); pc2.createAnswer().then(gotAnswerDescription).catch(handleError);
}function gotRemoteStream(e){if(remoteVideo.srcObject !== e.streams[0]){remoteVideo.srcObject = e.streams[0];}
}function call(){var offerOptions = {offerToReceiveAudio: 0,offerToReceiveVideo: 1 }pc1 = new RTCPeerConnection();pc1.onicecandidate = (e) => {// send candidate to peer// receive candidate from peerpc2.addIceCandidate(e.candidate).catch(handleError);console.log('pc1 ICE candidate:', e.candidate);}pc1.iceconnectionstatechange = (e) => {console.log(`pc1 ICE state: ${pc.iceConnectionState}`);console.log('ICE state change event: ', e);}pc2 = new RTCPeerConnection();pc2.onicecandidate = (e)=> {// send candidate to peer// receive candidate from peerpc1.addIceCandidate(e.candidate).catch(handleError);console.log('pc2 ICE candidate:', e.candidate);}pc2.iceconnectionstatechange = (e) => {console.log(`pc2 ICE state: ${pc.iceConnectionState}`);console.log('ICE state change event: ', e);}pc2.ontrack = gotRemoteStream;//add Stream to callerlocalStream.getTracks().forEach((track)=>{pc1.addTrack(track, localStream);});pc1.createOffer(offerOptions).then(gotLocalDescription).catch(handleError);}function hangup(){pc1.close();pc2.close();pc1 = null;pc2 = null;}btnStart.onclick = start;
btnCall.onclick = call;
btnHangUp.onclick = hangup;