基於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表情功能的製作)
先寫到這裡吧,本來是想寫關於視訊聊天傳輸的東西的,前邊的聊天介面就介紹了這麼多,下一章接著寫視訊傳輸,先放兩張圖片感受下效果,哈哈。。