對SignalR不瞭解的人能夠直接移步下面的目錄html
- -,我又來了,今天廢話很少說,咱們直接來實現Web視頻聊天.web
採用的技術以下:canvas
HTML5 WebRTC服務器
SignalR2.2.0app
localResizeIMG3(前端圖像壓縮技術,開源)ide
效果如圖(馬賽克你懂的,Demo效果比較簡陋):post
首先咱們來看看前端的實現,主要是經過HTML5的WebRTC技術獲取視頻流 轉換成圖片 而後採用壓縮後定時發送的技術給到SignalR服務端.測試
咱們先來看看獲取視頻流的JS,文字我就很少解釋了,你們直接看註釋便可優化
//獲取視頻流代碼塊 var canvas = document.getElementById("canvas"), //取得canvas實例 context = canvas.getContext("2d"), //取得2D畫板 video = document.getElementById("video"),//取得視頻標籤 videoObj = { "video": true }, //設置獲取視頻 errBack = function (error) { console.log("Video capture error: ", error.code); }; //設置錯誤回發信息 if (navigator.getUserMedia) { // 標準獲取視頻語法 navigator.getUserMedia(videoObj, function (stream) { video.src = stream; video.play(); }, errBack); } else if (navigator.webkitGetUserMedia) { // Webkit內核語法 navigator.webkitGetUserMedia(videoObj, function (stream) { video.src = window.webkitURL.createObjectURL(stream); var data = window.webkitURL.createObjectURL(stream); video.play(); }, errBack); } else if (navigator.mozGetUserMedia) { // 火狐內核語法 navigator.mozGetUserMedia(videoObj, function (stream) { video.src = window.URL.createObjectURL(stream); video.play(); }, errBack); } //執行定時程序 window.setInterval(function () { context.drawImage(video, 0, 0, 320, 240); var type = 'jpg'; var imgData = canvas.toDataURL(type);
//使用localResizeIMG3壓縮圖像. lrz(imgData, { quality: 0.1, //壓縮率 done: function (results) { var data = results; chat.server.sendImage(data.base64); //var reader = new FileReader(); // $("#canvas2").attr("src", data.base64); } }); }, 500)
這樣,咱們就獲取到了相關的數據(PS:獲取到的圖像大小約爲4800個長度的字符串,壓縮率0.1壓縮後爲2300個長度,自行根據帶寬修改壓縮率)
下面咱們看看SignalR的實現代碼(關鍵方法已經標黃):
[HubName("getMessage")] public class TestHub : Hub { public void SendMessage(string aaaa) { Clients.All.broadcastMessage(aaaa); } public void SendImage(string imagedata) { //獲取圖像數據,轉發給其餘客戶端 Clients.Others.showimage(new {id=Context.ConnectionId,data=imagedata}); } public override System.Threading.Tasks.Task OnConnected() { Clients.Others.addKuang(Context.ConnectionId); return base.OnConnected(); } public override System.Threading.Tasks.Task OnDisconnected(bool stopCalled) { Clients.All.romeKuang(Context.ConnectionId); return base.OnDisconnected(stopCalled); } }
咱們來看看前端的SignalR的實現代碼:
// 這裏是註冊集線器調用的方法,和1.0不一樣的是須要chat.client後註冊,1.0則不須要 var chat = $.connection.getMessage; chat.client.broadcastMessage = function (name) { // HTML編碼的顯示名稱和消息。 var encodedMsg = $('<div />').text(name).html(); // 將消息添加到該頁。 $('#messsagebox').append('<li>' + encodedMsg + '</li>'); }; //獲取圖片數據,並實時顯示 chat.client.showimage = function (data) { if ($("#" + data.id).length<=0) { var html = '<div style="float: left; border: double" id="div' + data.id + '">\ <img id="'+ data.id + '" width="320" height="240">\ <br />\ <span>用戶'+ data.id + '</span>\ </div>' $("#contextdiv").append(html) } $("#" + data.id).attr("src", data.data); } // 獲取用戶名稱。 $('#username').html(prompt('請輸入您的名稱:', '')); // 設置初始焦點到消息輸入框。 $('#message').focus(); // 啓動鏈接,這裏和1.0也有區別 $.connection.hub.start().done(function () { $('#send').click(function () { var message = $('#username').html() + ":" + $('#message').val() // 這裏是調用服務器的方法,一樣,首字母小寫 chat.server.sendMessage(message); // 清空輸入框的文字並給焦點. $('#message').val('').focus(); }); });
這樣,咱們很簡單的就完成了HTML5+SignalR2.0的視頻聊天程序.
因爲這是一個簡單的Demo,因此並無考慮到應用於生產環境的問題,文章中實現的是視頻羣聊,因此對帶寬要求很高(畢竟數據所有須要從服務器交換出去,基本測試爲4人須要2M帶寬,在壓縮率0.1的狀況下),若是你要應用於生產環境,仍是須要進一步的優化,好比通訊的間隔,最好是單人互相通訊之類的各類狀況...,就說到這裏,Over..