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>

不要走开还有后续 ,增加信令版本

文章来源: webRTC【二】单机实现方案无信令版本