第一章 WebRTC入门
1.1 绪论
WebRTC是Web Real-Time Communications (RTC) 。WebRTC是一个基于标准化技术的行业性项目,旨在将实时通信功能引入到所有浏览器中,并通过标准的[HTML5]标签和JavaScript APl使这些功能可为Web开发者所用,目前由万维网联盟( World Wide Web Consortium (W3C))和互联网工程任务组(Internet Engineering Task Force (IETF))联合负责WebRTC的标准化工作。
1.2 资源
- adapter.js
- webrtc官网https://webrtc.org/
- W3C Spec (getUserMedia): http://w3c.github.io/mediacapture-main/getusermedia.html
- W3C Spec (WebRTC 1.0: Real-time Communication Between Browsers): http://dev.w3.org/2011/webrtc/editor/webrtc.html
https://www.w3.org/TR/webrtc/- ❤❤❤ w3c标准: WebRTC1.0 浏览器间的实时通信(网易云信翻译版,在yasepix@163.com中有)
- W3C Spec (mediacapture-streams): https://www.w3.org/TR/mediacapture-streams/
- W3C Spec (WebRTC Stats): http://w3c.github.io/webrtc-stats/
- W3C Spec (Screen Capture): https://w3c.github.io/mediacapture-screen-share/
1.3 Simple Peer-to-peer Example
const signaling = new SignalingChannel(); // handles JSON.stringify/parse
const constraints = {audio: true, video: true};
const configuration = {iceServers: [{urls: 'stuns:stun.example.org'}]};
const pc = new RTCPeerConnection(configuration);
// send any ice candidates to the other peer
pc.onicecandidate = ({candidate}) => signaling.send({candidate});
// let the "negotiationneeded" event trigger offer generation
pc.onnegotiationneeded = async () => {
try {
await pc.setLocalDescription(await pc.createOffer());
// send the offer to the other peer
signaling.send({desc: pc.localDescription});
} catch (err) {
console.error(err);
}
};
// once media for a remote track arrives, show it in the remote video element
pc.ontrack = (event) => {
// don't set srcObject again if it is already set.
if (remoteView.srcObject) return;
remoteView.srcObject = event.streams[0];
};
// call start() to initiate
async function start() {
try {
// get a local stream, show it in a self-view and add it to be sent
const stream = await navigator.mediaDevices.getUserMedia(constraints);
stream.getTracks().forEach((track) => pc.addTrack(track, stream));
selfView.srcObject = stream;
} catch (err) {
console.error(err);
}
}
signaling.onmessage = async ({desc, candidate}) => {
try {
if (desc) {
// if we get an offer, we need to reply with an answer
if (desc.type == 'offer') {
await pc.setRemoteDescription(desc);
const stream = await navigator.mediaDevices.getUserMedia(constraints);
stream.getTracks().forEach((track) => pc.addTrack(track, stream));
await pc.setLocalDescription(await pc.createAnswer());
signaling.send({desc: pc.localDescription});
} else if (desc.type == 'answer') {
await pc.setRemoteDescription(desc);
} else {
console.log('Unsupported SDP type. Your code may differ here.');
}
} else if (candidate) {
await pc.addIceCandidate(candidate);
}
} catch (err) {
console.error(err);
}
};
从这个程序中抽取几个基本的对象出来,以后各节详细解析。这几个对象是:
- navigator.mediaDevices.getUserMedia
- RTCPeerConnection
- SignalingChannel