1. 程式人生 > >基於C++實現視訊聊天軟體(一)

基於C++實現視訊聊天軟體(一)

初來乍到,接觸到音視訊領域,在這期間參考開原始碼和專案程式碼,用C++做了一個類似QQ的視訊聊天Demo,這裡將其中開源的視訊通訊技術分享給大家。

工具: vs2010,MFC製作介面,網路傳輸機制(Socket等),
VFW視訊採集,FFmpeg編解碼器,SDL播放

聊天與檔案傳輸

1. MFC介面

選擇做聊天軟體,首先要選取一個介面工具,做介面可不是底層的C++語言的強項,傳統的有微軟的MFC,比較龐大,開源的有QT、DirectUI,做出介面很炫,使用也比較簡單。但為配合vs2010,還是選擇了MFC這種適合底層語言的介面工程。
話不多說,直接上圖:
聊天介面
這裡寫圖片描述
怎麼樣,用MFC也可以做出很炫的介面的。以上兩個介面,可以理解一個客戶端,一個服務端,客戶端登入伺服器與其連線,然後兩者互發訊息進行聊天。
該聊天軟體的主要功能有:

  登入 
  文字聊天
  表情聊天
  檔案傳輸
  視訊聊天

下面介紹幾種實用的功能,基礎功能大家自己找資料補一下。

2. 編輯框CEdit的使用

在Properties面板上新增一個編輯框(Edit Control),右鍵點選屬性,修改ID,選上multiline、vertical scroll 和Auto Vscroll屬性,新增滾動條並且實現自動換行;如果要實現滾動條自動回滾到最下方,可新增如下程式碼(m_edit為該編輯框的Control變數)

m_edit.LineScroll(m_edit.GetLineCount());

依次建立傳送框、接收框,分別為其新增CString型數值變數m_editInput、m_editOutput,建立send按鈕,聊天軟體要實現的功能是:
(1)傳送框輸入的內容儲存起來,通過網路傳送出去
(2)傳送框的內容顯示到接收框上
參考程式碼如下:

void CclientDlg::OnBnClickedSendButton()
{ 
    UpdateData(TRUE);
    Send(m_editInput);  //網路傳送函式,需自己實現

    m_editOutput = m_editOutput + "\r\n   我:" +m_editInput; 
    m_editInput = "";   //清空傳送框

    UpdateData(FALSE);  
    m_editOutput.LineScroll(m_editOutput.GetLineCount());

}

3. 檔案對話方塊、傳送檔案

如果要向對方傳送檔案,我們希望實現這樣的功能:
點選”檔案“圖示按鈕,彈出檔案對話方塊,然後在本地計算機中選擇檔案,傳送出去。
MFC封裝了檔案對話方塊類CFileDialog,通過呼叫類函式,實現傳送檔案功能,看下面:

void CclientDlg::OnBnClickedFileButton()
{
    //設定過濾器
    TCHAR szFilter[] = _T("文字檔案(*.txt)|*.txt|所有檔案(*.*)|*.*||");
    // 構造開啟檔案對話方塊
    CFileDialog fileDlg(TRUE,_T("txt"),NULL,0,szFilter,this);
    CString strFilePath,strText;

    // 顯示開啟檔案對話方塊
    if (IDOK == fileDlg.DoModal())
    {
        TFileInfo tempFileInfo;
        strFilePath = fileDlg.GetPathName(); //獲取檔案路徑
        SetDlgItemText(IDC_INPUT_EDIT,strFilePath+" 正在上傳...");

        CStdioFile file2;
        if(!file2.Open( strFilePath ,CFile::modeRead)) //開啟檔案
            return;
        while(true)//按行迴圈讀取檔案內容存入strText
        {
            if(!file2.ReadString(strText))
                break;
            Send(strText);    //傳送出去
        }
    }
}

當然這裡只是最簡單的文字檔案,如果是圖片、視訊等檔案,可以借用網路傳輸工具Socket實現,在專案中,我有很好的網路傳輸工具,直接拿來用了。

4. 為按鈕新增圖片

為了介面美觀,有時我們需要為按鈕新增相應的圖片,如表情點陣圖、檔案點陣圖、視訊點陣圖,以及通過點選按鈕實現點陣圖的切換,如暫停、取消點陣圖。接下來就介紹為按鈕新增點陣圖的方法。

1. 對話方塊上建立按鈕資源IDC_BUTTON時選擇 owner draw (自己畫); 
    (注:選擇自畫時,Bitmap屬性一定要設定False,不然會出錯)
2.  在對話方塊.h檔案內定義點陣圖按鈕物件 CBitmapButton m_button;
3. 匯入準備好的點陣圖到資源中,並修改ID (如:IDB_START);
4. 在初始化函式 BOOL CclientDlg::OnInitDialog() 中 新增如下程式碼:
{
    BOOL start = 0;
    m_button.LoadBitmaps(IDB_START,IDB_PAUSE);
    m_button.SubclassDlgItem(IDC_PAUSE_BUTTON,this);
    m_button.SizeToContent();
}

如果我們想通過點選按鈕,實現兩種點陣圖的切換,可以這樣實現:

void CclientDlg::OnBnClickedPauseButton()
{
    //轉換開始、暫停圖示
    if(!start)
    {
        m_button.LoadBitmaps(IDB_START);   //切換到開始
        m_button.SizeToContent();  
        start = 0;
    }
    else
    {
        m_button.LoadBitmaps(IDB_PAUSE);   //切換到暫停
        m_button.SizeToContent(); 
        start = 1;
    }
    //記得重新整理按鈕
    Invalidate();
}

5. 顯示進度條

在檔案上傳時,當我們想知道上傳的進度,可以通過繪製進度條類實現。
進度條控制在MFC類庫中的封裝類為CProgressCtrl,通常僅作為輸出類控制,所以其操作主要是設定進度條的範圍和當前位置,並不斷地更新當前位置。過程很簡單,可以實現基本的顯示功能,如下:

1. 對話方塊上新增一條進度條IDC_PROGRESS 和一個靜態文字框 IDC_STATIC
2. 在對話方塊.h檔案內定義進度條物件 CProgressCtrl MyProCtrl;
3. 對話方塊.cpp檔案中繫結物件:
    void CclientDlg::DoDataExchange(CDataExchange* pDX)
    {  
        DDX_Control(pDX, IDC_PROGRESS_up, MyProCtrl);
    }
4. OnInitDialog()進度條初始化
    MyProCtrl.SetRange(0,100);
    MyProCtrl.SetPos(0);
5. 計算上傳進度百分比Rate,然後這樣
{
    MyProCtrl.SetPos(lParamRate*100);      //進度條移動
    CString str;
    str.Format(_T("%d%%"),lParamRate*100);
    GetDlgItem(IDC_STATIC2)->SetWindowText(str); //顯示百分比
    if (lParamRate == 1)           //上傳結束時,更新圖示
    {
        m_button.LoadBitmaps(IDB_START);  
        m_button.SizeToContent();  
        start = 0;
        Invalidate();
    }
}

6. 表情聊天

進一步,如果想實現類似QQ表情的聊天形式,可以進一步實現,過程就有點麻煩了,還好有大神們的”前車之鑑“,MFC RichEdit就是比較好的工具,做出來也很炫,感興趣的可以點開參考:
CRichEditCtrlEx支援靜態表情聊天類的使用
向Richedit插入動態Gif的實現(關於QQ表情功能的製作)

先寫到這裡吧,本來是想寫關於視訊聊天傳輸的東西的,前邊的聊天介面就介紹了這麼多,下一章接著寫視訊傳輸,先放兩張圖片感受下效果,哈哈。。

這裡寫圖片描述
這裡寫圖片描述

目錄