webrtc-RTCPeerConnection

/post/webrtc-rtcp article cover image

<Callout type="info"> 具体属性、方法和事件参考<a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection">RTCPeerConnection API</a> </Callout>

rtcpeerconnection

紧接着上个连接章节的步骤流程模拟实现一个本地RTCP连接demo。

js
const pc = new RTCPeerConnection()

方法分类

  • 媒体协商
    • createOffer
    • createAnswer
    • setLocalDescription
    • setRemoteDescription
  • 媒体协商时状态发生变化的事件
    • onnegotiationneeded
    • onicecandidate
  • Stream/Track
    • addTrack
    • removeTrack
  • 传输相关
  • 统计相关

媒体协商流程图

ice candidate

媒体协商demo

js
// 初始化获取媒体流
let localStream;
function init() {
	const localPlayer = $('#localPlayer');
	const constrains = { audio: false, video: true };

	navigator.mediaDevices.getUserMedia(constraints).then(stream => {
		localStream = stream;
		localPlayer.srcObject = stream;
	})
}
js
// 媒体协商
let pcCaller;
let pcReciever;
function negotiation() {
	pcCaller = new RTCPeerConnection();
	pcReciever = new RTCPeerConnection();

	// 调用者接收到候选者时触发
	pcCaller.onicecandidate = (e) => {
		// 接收者将调用者传输过来的candidate设置为候选者(两端互通)
		pcReciever.addIceCandidate(e.candidate);
		console.log('pcCaller ICE candidate:', e.candidate);
	}

	// 接受者接收到候选者时触发
	pcReciever.onicecandidate = (e) => {
		// 调用者将接受者传输过来的candidate设置为候选者(两端互通)
		pcCaller.addIceCandidate(e.candidate);
		console.log('pcReciever ICE candidate:', e.candidate);
	}
	// 获取到媒体信息时展示
	pcReciever.ontrack = (e) => {
		const remotePlayer = $('#remotePlayer');
		remotePlayer.srcObject = e.streams[0];
	}

	// 必须先添加媒体流确认格式等信息再进行媒体协商
	// 将本地采集的媒体流添加到调用者的PeerConnection中
	localStream.getTracks().forEach((track)=>{
		pcCaller.addTrack(track, localStream);
	});
	// 调用者创建offer
	const offerOptions = {
		offerToReceiveAudio: 0,
		offerToReceiveVideo: 1
	}
	pcCaller.createOffer(offerOptions).then(localDescription => {
		pcCaller.setLocalDescription(localDescription);
		// offer sdp
		console.log(localDescription.sdp);
		// 通过信令服务发送描述至被调用者
		// ...
		// 被调用者将传输过来的描述信息设置为远端描述
		pcReciever.setRemoteDescription(localDescription);
		// 被调用者设置应答
		pcReciever.createAnswer().then(answerDescription => {
			// 将被调用者描述设置为远端描述
			pcReciever.setLocalDescription(answerDescription);
			// answer sdp
			console.log(answerDescription.sdp)
			// 通过信令服务发送描述至调用者
			// ...
			// 调用者将被调用者传输过来的描述设置为远端描述
			pcCaller.setLocalDescription(answerDescription)
			// 连接完成 协商完成
		});
	});
}

关闭连接

js
pcCaller.close();
pcReciever.close();
pcCaller = null;
pcReciever = null;