webRTC 單機實現方案無信令版本(二)

上一篇介紹可能是整體的流程,可能表述的太簡單,不過實現的時候還是需要一步一步的來實現,技術點有兩部分 [M] = method [E] = event

  • navigator.mediaDevices.getUserMedia
  • RTCPeerConnection
    • [M] addStream
    • [M] setLocalDescription
    • [M] setRemoteDescription
    • [M] createOffer
    • [M] createAnswer
    • [E] icecandidate
    • [M|E] addstream

首先html部分

<div id="main">
	<div>
		<video id="local" autoplay></video>
	</div>
	<div>
		<video id="remote" autoplay></video>
	</div>
</div>

js部分

async function initMedia() {
	let stream = await navigator.mediaDevices.getUserMedia({
		video: true
	});
	let video = document.querySelector('#local');
	video.srcObject = stream;
}

以上的應該是比較基礎的也不難理解,如果有不明白的地方可以自行解決

RTCPeerConnection

重點來說說 這個
一開始需要實例化下,因爲本次就介紹兩個端,就需要初始化兩個簡寫本地 和遠程

	var local = new RTCPeerConnection(null);
	var remote = new RTCPeerConnection(null);

實例化完成後本地端需要添加 本地的stream, 同時偵聽時間 icecandidate

	// 本地
	local.addstream(stream) //通過getUserMedia獲取
	local.addEventListener('icecandidate', handleLocalConnection, false);
	function handleLocalConnection(e){
		const iceCandidate = e.candidate;
		if (iceCandidate) {
			remote.addIceCandidate(new RTCIceCandidate(iceCandidate))
		}
	};
	//遠端
	remote.addEventListener('icecandidate', handleRemoteConnection, false)
	remote.addEventListener('addstream', function(){
		let video = document.querySelector('#remote')
			video.srcObject = e.stream;
	}, false);
	function handleRemoteConnection(e){
		const iceCandidate = e.candidate;
		if (iceCandidate) {
			local.addIceCandidate(new RTCIceCandidate(iceCandidate))
		}
	}

上面可能要注意 handleRemoteConnection , handleLocalConnection 這裏可以先思考下,因爲是無信令版本的, remote, local都能取到,如果真正兩個對端來調試需要怎麼配置信令服務器。
添加完成之後本地測開始呼叫 createOffer, 遠端並偵聽事件

	let offer = await local.createOffer();
	local.setLocalDescription(offer); //本地設置
	remote.setRemoteDescription(offer); //遠端設置

設置好之後遠程端開始應答 createAnswer

	let answer = await remote.createAnswer();
	remote.setLocalDescription(answer); //遠端設置
	local.setRemoteDescription(answer); //本地設置

寫到這裏基本上算完成了可以,
一下是整體代碼

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
	<title>webrtc_base</title>
	<style>
		#main{ overflow: hidden;}
		#main>div{
			width: 100px; height: 100px;
			margin: 10px;
			border:1px solid #ccc;
			float: left;
		}
		video{width: 100%; height: 100%; filter: grayscale(90%);}
	</style>
</head>
<body>

	<div id="main">

		<div>
			<video id="local" autoplay></video>
		</div>
		<div>
			<video id="remote" autoplay></video>
		</div>
	
	</div>

	<a href="javascript:;" onclick="initMedia()">開始</a>

	<script>
		
			var local = new RTCPeerConnection(null);
			var remote = new RTCPeerConnection(null);

		async function initMedia() {
			let stream = await navigator.mediaDevices.getUserMedia({
				video: true
			});
			let video = document.querySelector('#local');
			video.srcObject = stream;

			local.addEventListener('icecandidate', handleLocalConnection,false)
			local.addStream(stream);
			remote.addEventListener("addstream",function(e){
				let video = document.querySelector('#remote')
				video.srcObject = e.stream;
				console.log('onaddstream', e);
			}, false)

			remote.addEventListener('icecandidate', handleRemoteConnection,false)

			let offer = await local.createOffer({offerOptions: 1});
			console.log('createOffer', offer);
			local.setLocalDescription(offer);
			remote.setRemoteDescription(offer);
			let answer = await remote.createAnswer();
			console.log('createAnswer', answer);
			remote.setLocalDescription(answer);
			local.setRemoteDescription(answer);
		}

		function handleLocalConnection(e){
  			const iceCandidate = e.candidate;
  			if (iceCandidate) {
  				remote.addIceCandidate(new RTCIceCandidate(iceCandidate))
  			}
		}

		function handleRemoteConnection(e){
  			const iceCandidate = e.candidate;
  			if (iceCandidate) {
  				local.addIceCandidate(new RTCIceCandidate(iceCandidate))
  			}
		}


	</script>
</body>
</html>

不要走開還有後續 ,增加信令版本

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章