webrtc 视频 demo

webrtc网上封装的很多,demo很多都是一个页面里实现的,今天实现了个完整的 , A 发视频给 B

A webrtc.html作为offer 

<!DOCTYPE html>
<html id="home" lang="en">

    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scal
able=no">
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <style>

            p { padding: 1em; }

            li {
                border-bottom: 1px solid rgb(189, 189, 189);
                border-left: 1px solid rgb(189, 189, 189);
                padding: .5em;
            }

        </style>
    </head>

    <body>


            <script>
                 var mediaConstraints = {
                    optional: [],
                    mandatory: {
                        OfferToReceiveAudio: false,
                        OfferToReceiveVideo: true
                    }
                };
            </script>
            <script>
                var offerer
                    ,answererWin

                window.RTCPeerConnection = window.mozRTCPeerConnection || window.webkit
RTCPeerConnection;
                window.RTCSessionDescription = window.mozRTCSessionDescription || windo
w.RTCSessionDescription;
                window.RTCIceCandidate = window.mozRTCIceCandidate || window.RTCIceCand
idate;

                navigator.getUserMedia = navigator.mozGetUserMedia || navigator.webkitG
etUserMedia;
                window.URL = window.webkitURL || window.URL;

                window.iceServers = {
                    iceServers: [{
                            url: 'stun:23.21.150.121'
                        }
                    ]
                };
            </script>
            <script>
                /* offerer */
                    function offererPeer(video_stream) {
                        offerer = new RTCPeerConnection(window.iceServers)
                        offerer.addStream(video_stream)

                        offerer.onaddstream = function (event) {
                               // 本地显示video
                    }

                    offerer.onicecandidate = function (event) {
                        if (!event || !event.candidate) return
                        
                        sendToP2({
                            'action' : 'candidate',
                            'candidate' :event.candidate
                        })
                       
                    }

                    offerer.createOffer(function (offer) {
                        offerer.setLocalDescription(offer)
                        sendToP2({
                        'action' : 'create',
                        'offer':offer
                        })
                       
                    }, function() {}, mediaConstraints)
                }
            </script>
            <script>
                var video_constraints = {
                    mandatory: {},
                    optional: []
                }

                function getUserMedia(callback) {
                    var n = navigator
                    n.getMedia = n.webkitGetUserMedia || n.mozGetUserMedia
                    n.getMedia({
                        audio: false,
                        video: video_constraints
                    }, callback, onerror)

                    function onerror(e) {
                        alert(JSON.stringify(e, null, '	'))
                    }
                }
            </script>
            <script>
                function sendToP2(data){
                    answererWin.postMessage(JSON.stringify(data) ,
window.location)

                }
                function receiveMessage(data){
                    data = JSON.parse(data.data)
                    switch ( data.action) {
                        case 'answer' :
                            offerer.setRemoteDescription(ne
w RTCSessionDescription(data.answer))
                            break
                        case "candidate":
                            offerer.addIceCandidate(new RTC
IceCandidate(data.candidate))
                            break

                    }
                    console.log('msg' ,data)
                }


                window.addEventListener("message", receiveMessage, fals
e)
                answererWin = window.open('webrtc2.html' ,'t')
                getUserMedia(function (video_stream) {
                    offererPeer(video_stream)
                });
            </script>

    </body>

</html>

B webrtc2.html 作为answer

<!DOCTYPE html>
<html id="home" lang="en">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <link rel="stylesheet" href="https://www.webrtc-experiment.com/style.css">

        <style>
            audio, video {
                -moz-transition: all 1s ease;
                -ms-transition: all 1s ease;

                -o-transition: all 1s ease;
                -webkit-transition: all 1s ease;
                transition: all 1s ease;
                vertical-align: top;
            }

            p { padding: 1em; }

            li {
                border-bottom: 1px solid rgb(189, 189, 189);
                border-left: 1px solid rgb(189, 189, 189);
                padding: .5em;
            }

            .videos-container {
                display: inline-block;
                border: 2px solid black;
                padding: .1em;
                border-radius: 0.2em;
                margin: 2em .2em;
                background: white;
                vertical-align: top;
            }
            .videos-container h2 {
                border: 0;
                border-top: 1px solid black;
                margin: 0;
                text-align: center;
                display:block;
            }
            video {
                20em;
                height: 15em;
                background: black;
            }
        </style>
        <!-- for HTML5 el styling -->
        <script>
            document.createElement('article');
        </script>
    </head>

    <body>
        <article>
                       <div style="text-align:center;">
                <div class="videos-container">
                    <video id="peer1-to-peer2" autoplay controls></video>
                     <h2>Offerer-to-Answerer</h2>

                </div>
            </div>
            <script>
                 var mediaConstraints = {
                    optional: [],
                    mandatory: {
                        OfferToReceiveAudio: true,
                        OfferToReceiveVideo: true
                    }
                };
            </script>
            <script>
                var offerer, answerer;
                var offererToAnswerer = document.getElementById('peer1-to-peer2');

                window.RTCPeerConnection = window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
                window.RTCSessionDescription = window.mozRTCSessionDescription || window.RTCSessionDescription;
                window.RTCIceCandidate = window.mozRTCIceCandidate || window.RTCIceCandidate;

                navigator.getUserMedia = navigator.mozGetUserMedia || navigator.webkitGetUserMedia;
                window.URL = window.webkitURL || window.URL;

                window.iceServers = {
                    iceServers: [{
                            url: 'stun:23.21.150.121'
                        }
                    ]
                };
            </script>
            <script>
                /* answerer */

                function answererPeer(offer, video_stream) {
                    answerer = new RTCPeerConnection(window.iceServers);
                   // answerer.addStream(video_stream);

                    answerer.onaddstream = function (event) {
                        offererToAnswerer.src = URL.createObjectURL(event.stream);
                        offererToAnswerer.play();
                    };

                    answerer.onicecandidate = function (event) {
                        if (!event || !event.candidate) return;
                        sendToP1({
                        'action' : 'candidate',
                        'candidate' :event.candidate
                        })
                        //offerer.addIceCandidate(event.candidate);
                    };

                    answerer.setRemoteDescription(new RTCSessionDescription(offer));
                    answerer.createAnswer(function (answer) {
                        answerer.setLocalDescription(answer);
                        sendToP1({
                            'action' : 'answer' ,
                            'answer' : answer
                        })
                        //offerer.setRemoteDescription(answer);
                    }, function() {}, mediaConstraints);
                }

                function receiveMessage(data){
                    data = JSON.parse(data.data)
                    console.log(data)
                    switch(data.action){
                        case "create":
                            answererPeer(data.offer , data.stream)
                            break
                        case "candidate":
                            answerer.addIceCandidate(new RTCIceCandidate(data.candidate))
                            break
                    }
                }
                window.addEventListener("message", receiveMessage, false)

                function sendToP1(data) {
                    opener.postMessage(JSON.stringify(data) , window.location)
                }
            </script>


        </article>



    </body>

</html>

demo用 postMessage传递数据, 业务使用可以用websocket

A 先 createOffer ,生成的offer 供自己setLocalDescription ,并发给B

B 拿A的offer ,setRemoteDescription(offer) , 然后 createAnswer ,生成的answer 供自己setLocalDescription ,并发给A

A 拿B的answer 设置 setRemoteDescription(answer)

A onicecandidate 事件被触发 将得到的通道发给B

B addIceCandidate(new RTCIceCandidate(candidate)) 建立通道

B onicecandidate 事件被触发 将得到的通道发给A

A addIceCandidate(new RTCIceCandidate(candidate)) 建立通道

通道建立后视频就可以共享了

参考网址

http://www.html5rocks.com/en/tutorials/webrtc/basics/?redirect_from_locale=fr
https://github.com/muaz-khan/WebRTC-Experiment/blob/master/demos/client-side.html

原文地址:https://www.cnblogs.com/vaal-water/p/4274571.html