如何實現Web視頻聊天?


      在網頁里實現文字聊天是比較容易的,但若要實現視頻聊天,就比較麻煩了。這里,我們將實現一個簡單的網頁版視頻聊天Demo,可以支持所有類型的瀏覽器。

      本Demo除了視頻聊天功能外,還包含以下功能:

1.上下線通知:假設所有用戶都是好友,任何一個用戶上線,都會出現在其他人的好友列表中,下線則會從好友列表中移除。

2.掉線后會自動進行斷線重連。

3.當同名的用戶登陸時,會把前面的用戶擠掉。

4.所有在線用戶之間進行文字聊天。

5.與在線好友進行視頻聊天。 

一. Demo運行效果

    先來看看Demo的最終效果吧!文字聊天:

    

     視頻聊天:

    

 

二. JS 實現過程

1.實現賬號登錄

    登錄界面如下:     

    

打開視頻聊天demo網頁時,會出現登錄界面,輸入視頻服務器IP、賬號(使用隨機生成的就可以),點擊登錄按鈕就可以登錄到視頻聊天服務器。

調用ESFramework框架的RapidPassiveEngine()的initialize方法,以及OMCS框架的MultimediaManager的Initialize方法以完成登錄。

登錄成功后會自動進入用戶主界面。

        //OMCS登錄
        $('#Singin').bind("click", function () {
            this.multimediaManager = MultimediaManagerFactory.GetSingleton();
            var id = document.getElementById("userID").value;//用戶id
            var posw = document.getElementById("logonPassword").value;//用戶密碼
            var serverIP = document.getElementById("serverIP").value;//ip地址
            // var serverPort = document.getElementById("serverPort").value;//端口
            try {
                if (this.multimediaManager.Connected() == true) {
                    this.multimediaManager.Initialize(id, posw, serverIP, 9900);         
                } else {
                    alert("登錄失敗");
                    console.log("多媒體webSocket還未連成功");
                }
            }
            catch (ex) {
                console.log(ex);
            }
        })
        //ESFramework登錄
        $('#Singin').bind("click", function () {                       
            engine.initialize({
                serverIP: serverIP,//服務器IP
                serverPort: serverPort,//服務器端口
                userID: userID,//登錄用戶名
                useWss: false,
                logonPassword: hex_md5(logonPassword),//md5后的密碼
                heartBeat: 5000,//心跳間隔時間(單位為ms)
                callBackTimeout: 5000,//回調方法超時時間(單位為ms)
                maxLengthOfUserID: 11,//設置用戶名最大長度
                customizeHandler: new CustomizeHandler(),//用戶自定義消息處理器
                loginResutCallBack: function (loginResult) {//登錄結果回調方法
                    if (loginResult.logonResult == 0) {//登錄成功
                        $("#chatBox").html("登錄服務器成功");
                        document.getElementById('loginid').innerHTML = '當前賬號 '+userID;
                        document.getElementById('login').style.display = 'none';
                        document.getElementById('main').style.display = 'block'                      
                        //esf登錄
                        engine.ContactsOutter.addEventListener(new contractsListener());//注冊聯系人事件
                        engine.BasicOutter.addEventListener(new basicListener());//注冊基礎事件
                        
            });
    };

2. 實現文字聊天

使用通信框架最基礎的需求就是收發信息,ESFramework(WebSocket)底層已經為我們封裝好了所有與信息收發相關的操作,  當RapidPassiveEngine被new出來以后,RapidPassiveEngine對象就實例化了CustomizeOutter 屬性,在對象的initialize函數被調用后,即可調用CustomizeOutter 里面的相關函數來發送消息,以及實現customizeHandler后就可以處理收到的信息。

Web端可以收到來自其它客戶端或服務端的信息、大數據塊、以及同步調用。

(1)發送文字聊天消息

發送文字聊天信息可時通過調用CustomizeOutter中send()來進行操作,再發送前點擊在線用戶即可改變targetUser的值從而綁定你要發送信息的對象。

//選擇聊天對象
function selectUser(userid) {
    var selfid = document.getElementById('userID').value;
    targetUser = userid;
    $("#chatBox").html("正在與" + userid + "對話中.....");
    var shows = document.getElementById('showfather').children;
    //console.log(shows);
    for (var i= 0; i < shows.length; i++) {
        if (shows[i].id != (userid + 'show')) {
            shows[i]. className='othershow'
        }
        document.getElementById(userid + 'show').className = 'shownow'
    }
}

發送信息時可以自定義不同的參數,從而判斷出不同的消息類型。

//發送信息    
$("#btn").bind("click", function () { if ($(".bottomtext").val() == "") { alert("不能發送空消息~"); return; } else if (targetUser.length == 0) { alert("未選中目標用戶~"); return; } else { value = $(".bottomtext").val();
var selfid=document.getElementById('userID').value; appendContent(
"自己", value,selfid); $(".bottomtext").val(""); var time = []; var info = util.getbytes(value); //以下為與服務端定義的協議體 var stream = new OStream(time); var bodyLen = 4 + 4 + info.length + 4; stream.writeInt32(bodyLen); stream.writeInt32(info.length); stream.write(info); stream.writeInt32(1);//發送時間 距離2016.01.01 00:00:00的總秒數 engine.CustomizeOutter.send(0, stream.getBytesArray(), targetUser); } })

(2)處理文字聊天消息

當我們收到其他在線用戶或者服務端發來的信息時,通過實現customizeHandler接口來獲取和處理信息。

我們在用戶登錄時調用initialize方法時轉入即可自動處理接收到的信息,接收到的信息我們通過判斷信息類型來執行不同的操作。

  function CustomizeHandler() {
            
            this.handleInformation = function (sourceUserID, informationType, info) {
                if (informationType == 0)//聊天消息
                {                  
                } else if (informationType == 1)//視頻消息
                {                            
                } else if (informationType == 2) {                               
                } else if (informationType == 3) {
                }

(3)渲染顯示文字聊天消息

通過appendOtherContent和appendContent函數將信息在頁面中渲染出來通過傳入的對象OppositeID不同將收到的信息渲染到不同的聊天窗口。並且通過selectUser來切換到發送信息的用戶的窗口。

function appendContent(sendName, content, OppositeID) {
        Time = getTime();
        $("#" + OppositeID).append('<div class="selfstyle"><p class="selfname">' + sendName + ":" + Time + '</p><p>' + content + '</p></div>');
        $("#" + OppositeID).animate({ scrollTop: 99999 });
    }

    function appendOtherContent(sendName, content, OppositeID) {
        Time = getTime();
        selectUser(OppositeID);
        var showid = OppositeID + 'show'
        $("#" + showid).append('<div class="otherstyle"><p class="othername">' + sendName + ":" + Time + '</p><p>' + content + '</p></div>');
        $("#" + showid).animate({ scrollTop: 99999 });

 3. 實現視頻聊天

      視頻聊天功能可以讓你與服務器上的在線用戶進行視頻聊天,通過OMCS服務插件來實現攝像頭和麥克風的連接,所以在使用前必須打開OMCS視頻服務Web插件才能正常使用。

(1)點擊視頻聊天后先通過CustomizeOutter 的send向對方發送消息類型為1的視頻連接請求數據,同時打開視頻聊天的窗口並且打開自己的攝像頭和麥克風連接

(2)視頻連接對象收到數據類型為1的視頻連接請求后出接受視頻連接的聊天框,可以選擇接受或拒絕.

         當視頻連接對象選擇接受視頻聊天,則會同時連接自己和對方的攝像頭麥克風;

         當對方拒絕時,則關閉視頻連接的請求。

         選擇過后將會發送一條消息類型為2的消息給視頻的發起者。

(3)視頻發起者收到數據為2的回復后,會進行判斷對方的選擇是接受還是拒絕,若是接受則開始連接對方的攝像頭,拒絕則關閉自己的攝像頭麥克風和視頻連接窗口。

(4)當某一方關閉連接或者斷開連接時會發送一條消息類型為3的消息發給另一方,收到類型為3的消息后會斷開自己的攝像頭和麥克風連接。

在連接過程中也可通過視頻聊天窗口的控件,控制自己的攝像頭麥克風的開啟和關閉。

發送視頻請求時間如下(接受拒絕和關閉同理)

$('#videomic').bind('click', function () {     
        if (targetUser.length == 0) {
            alert("未選中視頻聊天用戶~");
            return;
        } else {
            value = 'null';
            console.log(value);
            document.getElementById('VideoMic').style.display = 'block';
            document.getElementById('VideoHeardTxt').innerHTML = '連接中...';
            document.getElementById('VideoSelf').src = 'img/video.jpg'
            document.getElementById('VideoOther').src = 'img/head.jpg'
            ConnertVideoSelf(userID, 'VideoSelf')
            appendContent(selfid, "我發送了視頻請求");
            var time = [];
            var info = util.getbytes(value);
            //以下為與服務端定義的協議體
            var stream = new OStream(time);
            var bodyLen = 4 + 4 + info.length + 4;
            stream.writeInt32(bodyLen);
            stream.writeInt32(info.length);
            stream.write(info);
            stream.writeInt32(1);//發送時間  距離2016.01.01 00:00:00的總秒數
            var userID = document.getElementById('userID').value;         
            engine.CustomizeOutter.send(1, null, targetUser);
        }
    })

視頻麥克風連接事件如下

var microphoneConnector, dynamicCameraConnector;
var cameraArr = [];
var micArr = [];
function Connectvideo(destID, whichimg) {
    var a = document.getElementById(whichimg);
    this.dynamicCameraConnector = new DynamicCameraConnector();
    this.dynamicCameraConnector.ConnectEnded = connectEnded;  //連接成功監聽 this.dynamicCameraConnector.Disconnected = disconnected;  //連接關閉監聽 this.dynamicCameraConnector.OwnerOutputChanged = videoOutput;
    this.dynamicCameraConnector.SetAutoReconnect(true);
    this.dynamicCameraConnector.AutoReconnectSucceed = videocl;
    this.dynamicCameraConnector.SetViewer(a);
    this.dynamicCameraConnector.BeginConnect(destID);//開始攝像頭的連接
    cameraArr.push(this.dynamicCameraConnector);
    this.microphoneConnector = new MicrophoneConnector();
    this.microphoneConnector.ConnectEnded = microphone;
    this.microphoneConnector.OwnerOutputChanged = micOutput;
    this.microphoneConnector.SetAutoReconnect(true);
    this.microphoneConnector.AutoReconnectSucceed = miccl;
    this.microphoneConnector.BeginConnect(destID);//開始麥克風的連接
    micArr.push(this.microphoneConnector);
}

視頻聊天的幾個特性:

(1)一方發起視頻對話請求,對方同意后,即可開始視頻對話。 

(2)在對話的過程中,任何一方都可以掛斷,以終止對話。 

(3)在對話的過程中,任何一方掉線,都會自動終止對話。 

(4)點擊右下角較小視頻窗口,會放大該視頻顯示窗口。

(5)Web版的視頻聊天可以與pc版視頻聊天互通。

 

三. 網頁視頻聊天Demo源碼下載

1. 視頻聊天Demo Web端 源碼(JavaScript)

2. 視頻聊天Demo 服務端+PC端 源碼

      當運行本Demo 的 Web端時,如果尚未安裝OMCS視頻服務Web插件,網頁會自動提示下載安裝。

      完成安裝后,刷新網頁,會提示啟動插件,點擊同意啟動后,再次刷新網頁即可進行正常登錄了。Web插件以托盤形式運行,如下圖所示:   

      

      如果不想自己編譯服務端和PC客戶端,可以直接下載我們已經編譯好的可直接運行的部署版本: VideoChat.Exe.rar

      部署版本壓縮包里的服務端可以放到公網的服務器上,雙擊exe即可運行。PC客戶端修改VideoChat.exe.config配置文件中的IP為公網服務器的IP,即可運行PC客戶端測試。

      如此,PC客戶端和Web端即可互通,以進行文字聊天和視頻聊天。

 

四. 注意事項

1. 首先將服務端部署到服務器上,雙擊exe運行起來,然后再登錄Web端和PC客戶端測試。

2. 一台電腦只能運行一個Demo Web端。

3. 測試視頻聊天時,兩個用戶最好在不同的房間,以防止聲音相互干擾。

4. Web版與在線用戶聊天時,聊天內容並不是保存在雲端的所以用戶下線后記錄會被清空。     

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM