webrtc初探1

目标
可以实现双方视频通话和聊天


效果
webrtc初探1

 

webrtc初探1

 

代码

呼叫方

webrtc初探1
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .wrapp {
            width: 100%;
            text-align: center;
            border: red solid 1px;
        }

        .videos {
            display: flex;
        }

        .video {
            display: flex;
            justify-content: center;
            align-items: center;
            width: 50%;
            border: red solid 1px;
            height: 120px;
            position: relative;

        }

        .msgs {
            background-color: pink;
            width: 100%;
            height: 200px;
            margin: auto;
            overflow-y: scroll;
            padding: 10px;
            box-sizing: border-box;
        }

        .ipt {
            padding: 20px;

        }

        .open-video {
            left: 10px;
            top: 10px;
            position: absolute;
            z-index: 2;

        }

        .msg-content {
            display: flex;
            margin-bottom: 10px;
        }

        .head {
            border-radius: 50%;
            width: 30px;
            height: 30px;
        }

        .me {
            background-color: white;
            margin-left: 8px;
        }

        .other {
            margin-right: 8px;
            background-color: green;
        }

        .msg-ctxtype-me {
            flex-direction: row-reverse;

        }

        .content {
            background-color: #95ec69;
            padding: 4px;
            width: 50%;
            border-radius: 4px;
        }
    </style>
</head>

<body>
    <h1>发起端</h1>
    <div class="wrapp">
        <div class="videos">
            <div class="video">
                <video class="local-video" autoplay width="160" height="120"></video>
            </div>
            <div class="video">
                <video class="remote-video" autoplay width="160" height="120"></video>
            </div>
        </div>
        <div class="msgs"></div>
        <div class="ipt">
            <input type="text"> <button onclick="sendMsg()">发送</button>
        </div>
    </div>
    <script>
        // import {ws} from ‘./helper.js‘;

        const ws = new WebSocket("wss://dshvv.com:8888/my_ws");
        let icecandidated = false;
        const lc = new RTCPeerConnection()


        /*
         *  处理文字聊天消息相关
        */
        const dc = lc.createDataChannel("channel");
        const msgs = []; //所有的聊天内容 消息容器
        const updateMsgs = () => { // 每当有新消息时,更新聊天展示
            let el = ‘‘;
            msgs.forEach((msg) => {
                el += `<div class=msg-content msg-ctxtype-${msg.type}>
                        <div class=head ${msg.type}></div>
                        <div class=content>${msg.content}</div>
                    </div>`
            })
            msgsEl.innerHTML = el;
            document.querySelector(.msgs).lastChild.scrollIntoView(true);
        }
        // 收到新消息
        dc.onmessage = e => {
            msgs.push({
                type: other,
                content: e.data
            });
            updateMsgs();
        }
        // 发送消息
        const sendMsg = () => {
            const content = document.querySelector(input).value;
            msgs.push({
                type: me,
                content
            });
            dc.send(content);
            updateMsgs();
        }
        // 文字消息链接初始化
        dc.onopen = e => {
            msgs.push({
                type: me,
                content: 初始化链接成功
            });
            updateMsgs();
        }
        const msgsEl = document.querySelector(.msgs);


        /*
         *  认证唯一标识相关
        */
        ws.onopen = async () => {
            lc.onicecandidate = e => {
                if (!icecandidated) {
                    ws.send(JSON.stringify({// 将LocalDescription发给别人
                        event: "offer",
                        data: { sdp: lc.localDescription }
                    }));
                    icecandidated = true;
                }
            }
            lc.createOffer().then(o => lc.setLocalDescription(o)).then(a => console.log("set successfully!"))
        }
        ws.onmessage = (e) => {
            const msg = JSON.parse(e.data);
            if (msg.event === "answer") {
                const answer = msg.data.sdp;
                lc.setRemoteDescription(answer)
            }
        }

        /*
         *  视频推送
        */
        const openVideo = document.querySelector(.open-video);
        navigator.mediaDevices.getUserMedia({ audio: true, video: true }).then((localStream) => {
            document.querySelector(.local-video).srcObject = localStream;
            for (const track of localStream.getTracks()) {
                lc.addTrack(track, localStream);
                console.log(添加本地媒体流到本地peer connection);
            }
        });
        lc.ontrack = async (event) => {
            const remoteVideo = document.querySelector(.remote-video);
            remoteVideo.srcObject = event.streams[0];
        };
    </script>
</body>

</html>
View Code

 

接收方

webrtc初探1
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .wrapp {
            width: 100%;
            text-align: center;
            border: red solid 1px;
        }

        .videos {
            display: flex;
        }

        .video {
            display: flex;
            justify-content: center;
            align-items: center;
            width: 50%;
            border: red solid 1px;
            height: 120px;
            position: relative;

        }

        .msgs {
            background-color: pink;
            width: 100%;
            height: 200px;
            margin: auto;
            overflow-y: scroll;
            padding: 10px;
            box-sizing: border-box;
        }

        .ipt {
            padding: 20px;

        }

        .open-video {
            left: 10px;
            top: 10px;
            position: absolute;
            z-index: 2;

        }

        .msg-content {
            display: flex;
            margin-bottom: 10px;
        }

        .head {
            border-radius: 50%;
            width: 30px;
            height: 30px;
        }

        .me {
            background-color: white;
            margin-left: 8px;
        }

        .other {
            margin-right: 8px;
            background-color: green;
        }

        .msg-ctxtype-me {
            flex-direction: row-reverse;

        }

        .content {
            background-color: #95ec69;
            padding: 4px;
            width: 50%;
            border-radius: 4px;
        }
    </style>
</head>

<body>
    <h1>接收端</h1>
    <div class="wrapp">
        <div class="videos">
            <div class="video">
                <video class="local-video" autoplay width="160" height="120"></video>
            </div>
            <div class="video">
                <video class="remote-video" autoplay width="160" height="120"></video>
            </div>
        </div>
        <div class="msgs"></div>
        <div class="ipt">
            <input type="text"> <button onclick="sendMsg()">发送</button>
        </div>
    </div>
    <script>
        // import {ws} from ‘./helper.js‘;

        const ws = new WebSocket("wss://dshvv.com:8888/my_ws");
        let icecandidated = false;
        const rc = new RTCPeerConnection();

        /*
         *  认证唯一标识相关
        */
        rc.onicecandidate = e => {
            console.log(onicecandidate执行,回应answer);
            if (!icecandidated) {
                ws.send(JSON.stringify({
                    event: "answer",
                    data: { sdp: rc.localDescription }
                }));
                icecandidated = true;
            }
        }
        ws.onmessage = (e) => {
            const msg = JSON.parse(e.data);
            if (msg.event === "offer") {
                const offer = msg.data.sdp;
                rc.setRemoteDescription(offer).then(a => console.log("offer set!"))
                rc.createAnswer().then(a => rc.setLocalDescription(a)).then(a => console.log("answer create!"))
            }
        }

        /*
         *  处理文字聊天消息相关
        */
        const msgs = []; //所有的聊天内容 消息容器
        const msgsEl = document.querySelector(.msgs);
        const updateMsgs = () => { // 每当有新消息时,更新聊天展示
            let el = ‘‘;
            msgs.forEach((msg) => {
                el += `<div class=msg-content msg-ctxtype-${msg.type}>
                        <div class=head ${msg.type}></div>
                        <div class=content>${msg.content}</div>
                    </div>`
            })
            msgsEl.innerHTML = el;
            document.querySelector(.msgs).lastChild.scrollIntoView(true);
        }
        rc.ondatachannel = e => {
            console.log(e);
            rc.dc = e.channel;
            rc.dc.onmessage = e => {
                console.log("new message from client!" + e.data);
                msgs.push({
                    type: other,
                    content: e.data
                });
                updateMsgs();
            }
            rc.dc.onopen = e => {
                console.log(初始化链接成功,e);
                msgs.push({
                    type: me,
                    content: 初始化链接成功
                });
                updateMsgs();
            }
        }
        const sendMsg = () => {
            const content = document.querySelector(input).value;
            msgs.push({
                type: me,
                content
            });
            rc.dc.send(content);
            updateMsgs();
        }
        

        /*
         *  视频接收
        */
        navigator.mediaDevices.getUserMedia({ audio: true, video: true }).then((localStream) => {
            document.querySelector(.local-video).srcObject = localStream;
            for (const track of localStream.getTracks()) {
                rc.addTrack(track, localStream);
                console.log(添加本地媒体流到本地peer connection);
            }
        });
        rc.ontrack = async (event) => {
            const remoteVideo = document.querySelector(.remote-video);
            remoteVideo.srcObject = event.streams[0];
        };
    </script>
</body>

</html>
View Code

 

webrtc初探1

上一篇:关于.net Framework向.net core的移植


下一篇:微信支付Native扫码支付模式二之CodeIgniter集成篇