自從在博客園發佈開源即時通訊系統GG(QQ高仿版)以來,結識了不少作IM的朋友,而後我和個人夥伴們也接到了不少與IM相關的項目。相比在發佈GG以前難以接到項目的情況相比,如今簡直太幸福了,雖然作項目很辛苦,但畢竟有錢賺,那辛苦也值了。 html
飲水思源,這裏要感謝博客園提供了這麼好的一個平臺,讓咱們能展示本身的實力,提高咱們的知名度,而後才能接到了更多項目。因此,我強烈建議那些但願接項目、接私單的朋友,都來博客園寫博客吧,寫出本身的知名度後,真是好處多多!算法
言歸正傳,前段時間作了個在線教育培訓的項目,與視頻會議比較相似,因此了,我打算像GGTalk開源即時通信系統同樣,搞一個開源視頻會議系統並把實現的原理和源碼都分享出來,讓有興趣的朋友能夠參考下。繼承GG的名稱,我把這個開源視頻會議系統命名爲GGMeeting,目前版本爲1.0,後續功能會不斷加強。 數據庫
通常而言,視頻會議的主要核心功能是:多人語音聊天、多人視頻聊天、公共電子白板、會議房間管理。本文咱們將介紹視頻會議系統的主要功能及其實現原理,後面有空在介紹詳細每一個功能的詳細實現細節。
windows
想要直接下載體驗的朋友請點擊:「源碼下載中心」 服務器
在視頻會議中,網絡語音通話一般多對多的的,但就模型層面來講,咱們討論一個方向的通道就能夠了。一方說話,另外一方則聽到聲音。看似簡單而迅捷,可是其背後的流程倒是至關複雜的。咱們將其通過的各個主要環節簡化成下圖所示的概念模型:網絡
這是一個最基礎的模型,由五個重要的環節構成:採集、編碼、傳送、解碼、播放。工具
語音採集指的是從麥克風採集音頻數據,即聲音樣本轉換成數字信號。其涉及到幾個重要的參數:採樣頻率、採樣位數、聲道數。測試
假設咱們將採集到的音頻幀不通過編碼,而直接發送,那麼咱們能夠計算其所須要的帶寬要求,仍以上例:320*100 =32KBytes/s,若是換算爲bits/s,則爲256kb/s。這是個很大的帶寬佔用。而經過網絡流量監控工具,咱們能夠發現採用相似QQ等IM軟件進行語音通話時,流量爲3-5KB/s,這比原始流量小了一個數量級。而這主要得益於音頻編碼技術。 因此,在實際的語音通話應用中,編碼這個環節是不可缺乏的。目前有不少經常使用的語音編碼技術,像G.72九、iLBC、AAC、SPEEX等等。優化
當一個音頻幀完成編碼後,便可經過網絡發送給通話的對方。對於語音對話這樣Realtime應用,低延遲和平穩是很是重要的,這就要求咱們的網絡傳送很是順暢。編碼
當對方接收到編碼幀後,會對其進行解碼,以恢復成爲可供聲卡直接播放的數據。
完成解碼後,便可將獲得的音頻幀提交給聲卡進行播放。
若是僅僅依靠上述的技術就能實現一個效果良好的應用於廣域網上的語音對話系統,那就太easy了。正是因爲不少現實的因素爲上述的概念模型引入了衆多挑戰,使得網絡語音系統的實現不是那麼簡單,其涉及到不少專業技術。一個「效果良好」的語音對話系統應該達到以下幾點:低延遲,背景噪音小,聲音流暢、沒有卡、停頓的感受,沒有迴音。
對於低延遲,只有在低延遲的狀況下,才能讓通話的雙方有很強的Realtime的感受。固然,這個主要取決於網絡的速度和通話雙方的物理位置的距離,就單純軟件的角度,優化的可能性很小。
(1)迴音消除
如今你們幾乎都已經都習慣了在語音聊天時,直接用PC或筆記本的聲音外放功能。當使用外放功能時,揚聲器播放的聲音會被麥克風再次採集,傳回給對方,這樣對方就聽到了本身的迴音。
迴音消除的原理簡單地來講就是,迴音消除模塊依據剛播放的音頻幀,在採集的音頻幀中作一些相似抵消的運算,從而將回聲從採集幀中清除掉。這個過程是至關複雜的,由於它還與你聊天時所處的房間的大小、以及你在房間中的位置有關,由於這些信息決定了聲波反射的時長。 智能的迴音消除模塊,能動態調整內部參數,以最佳適應當前的環境。
(2)噪聲抑制
噪聲抑制又稱爲降噪處理,是根據語音數據的特色,將屬於背景噪音的部分識別出來,並從音頻幀中過濾掉。有不少編碼器都內置了該功能。
(3)抖動緩衝區
抖動緩衝區(JitterBuffer)用於解決網絡抖動的問題。所謂網絡抖動,就是網絡延遲一會大一會小,在這種狀況下,即便發送方是定時發送數據包的(好比每100ms發送一個包),而接收方的接收就沒法一樣定時了,有時一個週期內一個包都接收不到,有時一個週期內接收到好幾個包。如此,致使接收方聽到的聲音就是一卡一卡的。
JitterBuffer工做於解碼器以後,語音播放以前的環節。即語音解碼完成後,將解碼幀放入JitterBuffer,聲卡的播放回調到來時,從JitterBuffer中取出最老的一幀進行播放。
JitterBuffer的緩衝深度取決於網絡抖動的程度,網絡抖動越大,緩衝深度越大,播放音頻的延遲就越大。因此,JitterBuffer是利用了較高的延遲來換取聲音的流暢播放的,由於相比聲音一卡一卡來講,稍大一點的延遲但更流暢的效果,其主觀體驗要更好。
固然,JitterBuffer的緩衝深度不是一直不變的,而是根據網絡抖動程度的變化而動態調整的。當網絡恢復到很是平穩通暢時,緩衝深度會很是小,這樣由於JitterBuffer而增長的播放延遲就能夠忽略不計了。
(4)靜音檢測
在語音對話中,要是當一方沒有說話時,就不會產生流量就行了。靜音檢測就是用於這個目的的。靜音檢測一般也集成在編碼模塊中。靜音檢測算法結合前面的噪聲抑制算法,能夠識別出當前是否有語音輸入,若是沒有語音輸入,就能夠編碼輸出一個特殊的的編碼幀(好比長度爲0)。特別是在多人視頻會議中,一般只有一我的在發言,這種狀況下,利用靜音檢測技術而節省帶寬仍是很是可觀的。
(5)混音
在視頻會議中,多人同時發言時,咱們須要同時播放來自於多我的的語音數據,而聲卡播放的緩衝區只有一個,因此,須要將多路語音混合成一路,這就是混音算法要作的事情。
視頻通話的概念模型與語音徹底一致:
攝像頭採集指的是從捕捉攝像頭採集到的每一幀視頻圖像。在windows系統上,一般使用VFW技術或DirectShow技術來實現。採集視頻的兩個關鍵參數是幀頻(fps)和分辨率。
通常而言,一個攝像頭能夠支持多種不一樣的採集分辨率和採集幀頻,而不一樣的攝像頭支持的分辨率的集合不同。好比如今有不少高清攝像頭能夠支持30fps的1920*1080的圖像採集。
編碼用於壓縮視頻圖像,同時也決定了圖像的清晰度。視頻編碼經常使用的技術是H.26三、H.26四、MPEG-四、XVID等。
當對方接收到編碼的視頻幀後,會對其進行解碼,以恢復成一幀圖像,而後在UI的界面上繪製出來。
相比於語音,視頻的相關處理要簡單一些。
(1)動態調整視頻的清晰度
在Internet上,網絡速度是實時動態變化的,因此,在視頻會議中,爲了優先保證語音的通話質量,須要實時調整視頻的相關參數,其最主要的就是調整編碼的清晰度,由於清晰度越高,對帶寬要求越高,反之亦然。
好比,當檢測網絡繁忙時,就自動下降編碼的清晰度,以下降對帶寬的佔用。
(2)自動丟棄視頻幀
一樣網絡繁忙時,還有一個方法,就是發送方是主動丟棄要發送的視頻幀,這樣在接收方看來,就是幀頻fps下降了。
在視頻會議中,電子白板的功能是很重要的。一般會議的主持人會在白板上畫圖進行講解,而後其它的人能同步觀看和操做電子白板的內容。
一般的電子白板都支持以下功能:線段、箭頭線、雙箭頭線,水平肘型鏈接符、垂直肘型鏈接符,矩形、三角形、橢圓(圓),文本,自由曲線,插入圖片,激光筆。
在實現上,電子白板主要是使用GDI+技術。
對於電子白板的同步,其原理是這樣的:好比,當操做者在白板上繪製一個圖像時,這個操做會被封裝成一個Command對象(命令模式),而後,經過網絡廣播發送給會議中的其它人。當其餘人接收到這個Command對象時,就將其轉換成一個白板操做來執行,這樣各個白板的內容就自動同步了。
對於那些動態建立視頻會議室,在用完以後就動態將其銷燬的一般的視頻會議應用場景來講,使用動態組來表示會議房間,是很是恰當的。
所謂「動態組」,就是在服務器內存中動態建立的組,不須要序列化存儲到好比數據庫或磁盤中,須要的時候就建立一個,而後加入多個成員進行組內溝通,當再也不使用的時候,就直接從內存中銷燬了。
基於Socket技術,咱們能夠在服務端實現DynamicGroupManager類來對動態組進行管理。
雖然,動態組僅僅存在於內存之中,可是,在項目須要時,咱們仍然能夠將其某些重要的信息持久化到數據庫中存儲。而後,在服務器重啓時,能夠從DB中加載重要的房間信息。
GGMeeting的當前版本爲2.0,已經實現了上述的4個主要功能,你們能夠下載源碼研究下。
特別說明一下:
GG項目和GGMeeting項目中,只要是我寫的代碼,所有都放出來了
廣告:若是您有相似視頻會議系統、在線培訓系統、IM系統須要定製開發的,能夠聯繫咱們哦:) QQ:2027224508
運行效果截圖:
部署說明:
(1)將GGMeeting.Server部署到服務器上,並運行起來。
(2)修改Client配置文件GGMeeting.exe.config中的ServerIP的值。
(3)運行第一個Client實例,以隨機賬號進入測試房間。
(4)在別的機器上繼續運行Client,以隨機賬號進入測試房間,你們便可在測試房間中進行視頻會議。
注意:語音視頻數據都是實時採集、實時播放的數據,因此測試時,服務器的帶寬要求最好是獨享帶寬,共享帶寬通常沒法知足實時語音視頻的要求。
________________________________________________________________________
歡迎和我探討關於 GG 開源即時通信系統和 GGMeeting開源視頻會議系統 的一切,個人QQ:2027224508,多多交流!
你們有什麼問題和建議,能夠留言,也能夠發送email到我郵箱:2027224508@qq.com。
若是你以爲還不錯,請粉我,順便再頂一下啊