webrtc 实时视频 .net websocket后台

这篇文章主要参考了 Webrtc WebSocket实现音视频通讯,非常感谢提供代码

前端部分完全是从这篇文章复制过来的,只是修改了webscket的url与stun服务器的地址,还有加入了webrtc-adapterjs ,至于做什么,可以点击链接进行了解

前端代码部分(主要来自开头提及的博文)

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>

    <body>
        Welcome<br/><input id="text" type="text" />
        <button onclick="send()">发送消息</button>
        <hr/>
        <button onclick="closeWebSocket()">关闭WebSocket连接</button>
        <hr/>
        <div id="message"></div>

        <video id="vid1" width="320" height="240" autoplay></video>
        <video id="vid2" width="320" height="240" autoplay></video><br>
        <a id="create" href="webrtc.html#true" onclick="init()">点击此链接新建聊天室</a><br>
        <p id="tips" style="background-color:red">请在其他浏览器中打开:http://此电脑 加入此视频聊天</p>

        <script type="text/javascript" src="http://cdn.staticfile.org/webrtc-adapter/zv4.1.1/adapter.min.js"></script>
        <script type="text/javascript">
            navigator.getUserMedia = navigator.getUserMedia ||
                navigator.webkitGetUserMedia ||
                navigator.mozGetUserMedia;

            var isCaller = window.location.href.split('#')[1];
            var websocket = null;
            //判断当前浏览器是否支持WebSocket
            if('WebSocket' in window) {
                websocket = new WebSocket("ws://192.168.31.175:8181");
            } else {
                alert('当前浏览器 Not support websocket')
            }

            //连接发生错误的回调方法
            websocket.onerror = function() {
                setMessageInnerHTML("WebSocket连接发生错误");
            };

            //连接成功建立的回调方法
            websocket.onopen = function() {
                setMessageInnerHTML("WebSocket连接成功");
            }

            // 创建PeerConnection实例 (参数为null则没有iceserver,即使没有stunserver和turnserver,仍可在局域网下通讯)
            var pc = new window.RTCPeerConnection(null);

            // 发送ICE候选到其他客户端
            pc.onicecandidate = function(event) {
                setMessageInnerHTML("我看看 1");
                if(event.candidate !== null) {
                    setMessageInnerHTML("我看看 2");
                    websocket.send(JSON.stringify({
                        "event": "_ice_candidate",
                        "data": {
                            "candidate": event.candidate
                        }
                    }));
                }
            };

            //接收到消息的回调方法
            websocket.onmessage = function(event) {
                setMessageInnerHTML("接收到的信息");
                setMessageInnerHTML(event.data);
                if(event.data == "new user") {
                    console.log("new user");
                    location.reload();
                } else {
                    var json = JSON.parse(event.data);
                    console.log('onmessage: ', json);
                    //如果是一个ICE的候选,则将其加入到PeerConnection中,否则设定对方的session描述为传递过来的描述
                    if(json.event === "_ice_candidate") {
                        pc.addIceCandidate(new RTCIceCandidate(json.data.candidate));
                    } else {
                        pc.setRemoteDescription(new RTCSessionDescription(json.data.sdp));
                        // 如果是一个offer,那么需要回复一个answer
                        if(json.event === "_offer") {
                            pc.createAnswer(sendAnswerFn, function(error) {
                                console.log('Failure callback: ' + error);
                            });
                        }
                    }
                }
            }

            //连接关闭的回调方法
            websocket.onclose = function() {
                setMessageInnerHTML("WebSocket连接关闭");
            }

            //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
            window.onbeforeunload = function() {
                closeWebSocket();
            }

            //将消息显示在网页上
            function setMessageInnerHTML(innerHTML) {
                document.getElementById('message').innerHTML += innerHTML + '<br/>';
            }

            //关闭WebSocket连接
            function closeWebSocket() {
                websocket.close();
            }

            //发送消息
            function send() {
                var message = document.getElementById('text').value;
                websocket.send(message);
            }

            // stun和turn服务器
            var iceServer = {
                "iceServers": [{
                    "url": "stun:stunserver.org"
                }, {
                    "url": "turn:numb.viagenie.ca",
                    "username": "[email protected]",
                    "credential": "muazkh"
                }]
            };

            // 如果检测到媒体流连接到本地,将其绑定到一个video标签上输出
            pc.onaddstream = function(event) {
                document.getElementById('vid2').src = URL.createObjectURL(event.stream);
            };

            // 发送offer和answer的函数,发送本地session描述
            var sendOfferFn = function(desc) {
                    pc.setLocalDescription(desc);
                    websocket.send(JSON.stringify({
                        "event": "_offer",
                        "data": {
                            "sdp": desc
                        }
                    }));
                },
                sendAnswerFn = function(desc) {
                    pc.setLocalDescription(desc);
                    websocket.send(JSON.stringify({
                        "event": "_answer",
                        "data": {
                            "sdp": desc
                        }
                    }));
                };

            // 获取本地音频和视频流
            navigator.getUserMedia({
                    "audio": true,
                    "video": true
                },
                function(stream) {
                    //绑定本地媒体流到video标签用于输出
                    document.getElementById('vid1').src = URL.createObjectURL(stream);
                    document.getElementById('vid1').muted = true;
                    //向PeerConnection中加入需要发送的流
                    pc.addStream(stream);
                    //如果是发起方则发送一个offer信令
                    if(isCaller) {
                        pc.createOffer(sendOfferFn, function(error) {
                            console.log('Failure callback: ' + error);
                        });
                    }
                },
                function(error) {
                    //处理媒体流创建失败错误
                    console.log('getUserMedia error: ' + error);
                });

            window.onload = function() {
                if(isCaller == null || isCaller == undefined) {
                    var tips = document.getElementById("tips");
                    tips.remove();
                } else {
                    var create = document.getElementById("create");
                    create.remove();
                }
            };

            function init() {
                location.reload();
            }
        </script>

    </body>

</html>
View Code

提及博文的java部分,我用了.net 控制台程序简单实现了一个(Fleck 可以在vs的管理nuget程序包中获得)

static void Main(string[] args)
        {
            //客户端url以及其对应的Socket对象字典
            IDictionary<string, IWebSocketConnection> dic_Sockets = new Dictionary<string, IWebSocketConnection>();


            var server = new WebSocketServer("ws://192.168.31.175:8181");

            //出错后重启
            server.RestartAfterListenError = true;

            server.Start(socket =>
            {
                socket.OnOpen = () => {
                    //获取客户端网页的url
                    string clientUrl = socket.ConnectionInfo.ClientIpAddress + ":" + socket.ConnectionInfo.ClientPort;
                    dic_Sockets.Add(clientUrl, socket);
                    Console.WriteLine(DateTime.Now.ToString() + "|服务器:和客户端网页:" + clientUrl + " 建立WebSock连接!");
                    
                };
                socket.OnClose = () =>  //连接关闭事件
                {
                    string clientUrl = socket.ConnectionInfo.ClientIpAddress + ":" + socket.ConnectionInfo.ClientPort;
                    //如果存在这个客户端,那么对这个socket进行移除
                    if (dic_Sockets.ContainsKey(clientUrl))
                    {
                        //注:Fleck中有释放
                        //关闭对象连接 
                        //if (dic_Sockets[clientUrl] != null)
                        //{
                        //dic_Sockets[clientUrl].Close();
                        //}
                        dic_Sockets.Remove(clientUrl);
                    }
                    Console.WriteLine(DateTime.Now.ToString() + "|服务器:和客户端网页:" + clientUrl + " 断开WebSock连接!");
                };
                socket.OnMessage = message =>  //接受客户端网页消息事件
                {
                    string clientUrl = socket.ConnectionInfo.ClientIpAddress + ":" + socket.ConnectionInfo.ClientPort;
                    foreach (var item in dic_Sockets.Where(a=>a.Key!=clientUrl))
                    {
                        item.Value.Send(message);
                    }
                    //Console.WriteLine(DateTime.Now.ToString() + "|服务器:【收到】来客户端网页:" + clientUrl + "的信息:\n" + message);
                };
                socket.OnBinary = b => {
                  
                };
            });

            Console.ReadKey();
        }
View Code

记录完毕,这个东西仅仅只是个demo,可以拿来玩一下

猜你喜欢

转载自www.cnblogs.com/cdyy/p/9971892.html
今日推荐