如何實現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版與在線用戶聊天時,聊天內容並不是保存在雲端的所以用戶下線後記錄會被清空。     

 

若測試過程中遇到任何問題,可以聯繫QQ:1500207630