1. 程式人生 > >PigeonCall:一款Android VoIP網路電話App架構分析

PigeonCall:一款Android VoIP網路電話App架構分析

1.概述

PigeonCall,中文名“飛鴿電話”,是一款Android平臺的VoIP網路電話應用,但只工作於區域網,支援給任意區域網內使用該App的其他使用者撥打網路電話,可以在各大應用市場下載安裝,也可以直接點選這裡直接下載。

本應用是我利用了斷斷續續將近大半年的業餘時間開發出來的,目的是想研究一下Android平臺的P2P語音傳輸技術,開發過程中重構了很多次,也嘗試了很多不同的方案,本文則是對此的一個總結,從巨集觀上分析了整個應用的架構和所涉及到的技術,歡迎持續關注本部落格,後續有時間會慢慢分享更多的細節。

2.需求分析

2.1 功能定義

本應用支援的功能如下所示:

(1) 運行於Android平臺

(2) 自動搜尋和顯示區域網內的其他使用者

(3) 支援撥打電話和來電提醒

(4) 通話過程流暢清晰無卡頓,低延時

2.2 效能指標

ITU-TG.114規定,對於高質量語音可接受的時延是300ms。一般來說,如果時延在300~400ms,通話的互動性比較差,但還可以接受。時延大於400ms時,則互動通訊非常困難。

2.3 開發難點

(1)低延遲,語音通話對延時非常敏感

(2)降低噪聲、回聲消除,靜音檢測(省流量)

(3)無伺服器,去中心化,全雙工P2P通訊

3 軟體架構

整個軟體分為四大模組: Android UI,VoipSdk(主控模組),裝置發現與通話協議,語音編解碼與傳輸模組,語音採集與輸出模組,如圖所示:

wKiom1bULRqS9-RxAACKddgIibo055.png

3.1 Android UI(平臺相關,採用Java開發)

Android UI 主要有2個介面,一個是 MainAcitivity,以列表的形式顯示當前區域網內的所有其他使用者,另一個則是電話撥打/接聽介面,當用戶點選撥打電話或者收到來電時顯示。

為了保證App進入後臺依然能夠收到來電訊息,因此需要開啟一個Service服務,該服務封裝了整個應用最核心的邏輯和介面,包括:搜尋區域網內其他使用者、撥打電話、監聽來電、語音傳輸等等。

UI介面如下所示,由於沒有美工,自己設計的介面不是很協調和美觀,這個後期再慢慢改進吧:

wKiom1bUMzGyhfO0AAJ9eBynAn8868.png

3.2 裝置發現與通話協議 (平臺無關,採用C++開發)

這一模組我研究和嘗試過三種方案,分別介紹如下:

3.2.1 成熟的 UPnP 框架

UPnP框架天生就是為對等網路連線(P2P)的結構設計的,可用於區域網之間的裝置發現、遠端服務呼叫。官方提供了各種實現了該協議框架的第三方庫,可以快速實現裝置發現功能。

UPnP協議規定,每個UPnP裝置節點通過組播來發送裝置描述、服務描述(XML文件),網路中的其他節點即可知道對方的資訊,以及所提供的服務,因此,我們需要設計一套簡單的通話協議的“服務描述”XML文件,包含:Make Call、Cancel Call、Accept Call、Refuse Call、End Call 等命令,這樣,其他的裝置節點即可通過"RPC"遠端過程呼叫的方式,實現通話的請求和響應過程。

這就是取樣UPnP方案的基本思路,我採用UPnP官網提供的"PlatinumKit"庫實現了這套功能,後來發現本應用並不需要搞得如此複雜,沒必要引入UPnP框架,因此又自己編寫了一套更加簡單的方案。

3.2.2 SIP協議

SIP協議被廣泛用於VoIP網路通話,但是更多地用於面向廣域網的語音電話應用場景,它需要一個SIP網路伺服器的參與,該網路伺服器負責各個SIP終端之間的會話建立、維護和終止。

本應用是區域網內的P2P網路電話,去中心化,並不需要"伺服器"的存在,因此並不適合採用SIP協議。

3.2.3 自定義裝置發現與通話協議

基於上述考慮,最終我選擇了自己來寫一套簡單且滿足本應用場景的裝置發現與通話協議。

首先,協議的網路傳輸部分採用UDP組播,相比與廣播包,對本地區域網的影響更小。其次,採用二進位制格式的協議,相比於XML、JSON等格式,效率更高,佔用頻寬更少。

本協議採用“T-L-V”連結格式,每個組播包由一個或多個“T-L-V”子包連結而成,示例如下:

wKioL1bULkjgQzIlAAAQaqGVwgc367.png

當前協議中已存在的子包如下所示:

wKioL1bULo3jjpkIAAAneIfbJXA746.png

每一個Device都有一個唯一的Id值,由 Source Id 和 Target Id 的值決定該組播包的傳送者和目標接受者,當 Target Id == 0 的時候,代表該組播包是發給所有人的。

由 Packet Id 決定此包的種類,不同種類的包有著不同的 optional 子包,例如:

wKioL1bUNTLhVZRxAAAo2rgmnhs657.png

Device Info 包是當前唯一發給所有人的組播包,用來通知區域網內其他物件自己的裝置名稱和IP地址,目前的設計是預設每個5秒鐘發一次,超過10s未收到包則認為該裝置已掉線。

具體協議實現的過程中,“T-L-V”協議部分,採用了我自己編寫的開源庫(TLV編解碼器),可以快速實現多個“T-L-V”格式的序列化與反序列化,而多播的部分則可以參考我的clib庫:multicast

3.3 語音編解碼傳輸模組(平臺無關,採用C++開發)

3.3.1 概述

一個完整的語音資料流圖如下所示,從採集到遠端播放,需要經過多項處理,包括:回聲消除、去噪、編碼、網路傳輸、解碼等等,本模組就是負責實現音訊資料的 "編解碼和網路傳輸" 部分。

wKioL1bULzjgYDr8AAAgJ_Z8-OU450.png

3.3.2 編解碼

一套雙聲道數字音訊若取樣頻率為44.1KHz,每樣值按16bit量化,則其位元速率為:44.1kHz*16bit*2 = 1.411Mbit/s

對於網路電話應用,語音傳輸是雙向的,因此上述位元速率還要乘以2,可見其資料量還是蠻大的,因此,必須進行編碼壓縮之後再通過網路進行傳輸,這樣才能達到更好的通話效果。

Opus是一個有損聲音編碼的格式,通過諸多的對比測試,低位元速率下Opus完勝曾經優勢明顯的HE AAC,中位元速率就已經可以媲敵碼比它率高出30%左右的AAC格式,而高位元速率下更接近原始音訊。因此非常適合作為VoIP語音電話首選的壓縮格式。

其官方網站:http://www.opus-codec.org,該網站上提供了基於C語言的編解碼庫,可以很容易地移植到其他平臺。

3.3.3 網路傳輸

網路傳輸協議可以選擇TCP、UDP或者RTP,像TCP這樣的可靠傳輸協議,通過超時和重傳機制來保證傳輸資料流中的每一個bit的正確性,從而帶來了明顯的延時,因此並不適合作為音視訊傳輸的首先方案。關於TCP與UDP/RTP的討論,網上資料很多,在此不再贅述,有興趣的朋友也可以看看我的這篇《為什麼要使用RTP》來了解一下RTP協議的種種好處。

本應用中,既可以採用RTP協議,也可以簡單地取樣UDP來完成語音資料的網路傳輸,如果取樣RTP協議,則可以考慮常見的RTP庫,包括:Jrtplib和ortp,前者是C++開發,後者採用C語言開發,都很不錯,我最後實現了兩個版本,一個是採用ortp,另一個是採用udp,其實,如果不做RTCP控制的話,還是採用udp更加簡單點。

3.3.4 去噪和回聲消除

去噪和回聲消除也是語音電話非常重要的一部分,必須得做,否則你會發現做出來的應用根本無法使用,噪音、嗞嗞聲和回聲影響實在是太大了,這也是做語音開發的難點所在,對噪聲、回聲、延時超級敏感,想做好,還需要下一番很大的功夫。

本應用採用了著名的Speex庫來完成去噪和回聲消除,它介面非常簡單易用,目前效果還不夠好,估計它的詳細配置我還研究得不夠,以後還需要繼續研究研究,慢慢優化通話效果。

3.3.5 語音採集輸出模組(平臺相關)

Android 語音的採集和輸出有兩種方案,第一種方案是採用 Android SDK提供的 Java 端的 API,即 MediaRecoder類(採集)和 AudioTrack類(播放)來完成,第二種方案則是採用Android NDK提供的 Android OpenSL ES 介面,在 Native 層直接完成語音的採集與輸出。

兩種方案我都嘗試過,最後決定採用 Android OpenSL ES 方案,因為不需要頻繁在 Java 和 Native 層直接傳遞資料,無論是程式碼的編寫還是程式執行的效率,優勢都非常明顯。

有一個老外,Victor Lazzarini,封裝了一套 OpenSL ES 的 API,非常好用,可以作為參考,地址點選這裡

4. 小結

限於篇幅,本文只是簡單列出了本應用的一些關鍵的設計和方案,並沒有完全詳細地展開,真正著手實現的過程中,你會發現還有很多很有價值值得研究和積累的地方,原始碼我就不公開了,但我會慢慢寫一些文章剖析其中涉及到的技術,希望對Android音訊開發有興趣的小夥伴們自己動手實踐一下,這樣才能真正地得到提高,開發過程中有任何疑問歡迎來信 [email protected] 交流,也可以關注我的新浪微博 @盧_俊 或者微信公眾號 @Jhuster 獲取最新的文章和資訊。

相關推薦

PigeonCallAndroid VoIP網路電話App架構分析

1.概述 PigeonCall,中文名“飛鴿電話”,是一款Android平臺的VoIP網路電話應用,但只工作於區域網,支援給任意區域網內使用該App的其他使用者撥打網路電話,可以在各大應用市場下載安裝,也可以直接點選這裡直接下載。 本應用是我利用了斷斷續續將近大半年的業餘時間開發出來的,目的是想研

Android開發者必備推薦助力開發的開源APP

今天,給大家推薦一款小而精的開源應用,該應用是同事推薦給我的,我使用後感覺不錯遂在這兒分享給大家。 我們都知道,當我們新接觸一個 Android 專案想要快速熟悉程式碼時,最好的方式就是執行起來,從看得見的入手,一點點去除錯、捋程式碼。而事實上,大多數公司沒有那麼多時間讓你花幾天時間慢慢看,基本

Android逆向之旅---破解永久免費網路訪問工具

一、前言因為最近個人需要,想在手機上使用"高階搜尋",但是找了一圈發現都是需要收費的網路工具,奈何我沒錢,所以只能通過專業技能弄一個破解版的。二、應用分析下面就直接奔入主題。首先我們看到到期介面如下:提

類神經網路+工作圖譜+大資料+類人工智慧+內容視覺化企業軟體裡的逆天思維

如今市面上的CRM普遍以機械式的記錄和歸納為主,沒有一款真正實現智慧化的CRM管理軟體為企業所用。想象一下,如果我們使用了融合類神經網路、工作圖譜、大資料、類人工智慧和內容視覺化等理念的CRM,那麼,我們的工作會變成什麼樣子? 人脈關係管理是企業CRM的主要功能,目前的C

輪子系列能用易用好用的Android圖片輪播輪子

前言 Banner功能在Android開發中實在是太常見了,主要用於廣告輪播、商品照片輪播等等,如下圖: 今天我來手把手教你如何使用一個能用易用好用的Android圖片輪播輪子。 目錄 1. 實現輪播功能為什麼

Android開源你不可錯過的可愛&小資風格的載入等待控制元件庫

前言 Android開發中,載入等待的需求 非常常見 本文將帶來 一款 可愛 & 小資風格的載入等待Android自定義View控制元件的使用,希望你們會喜歡。 目錄 1. 簡介 一款 可愛 、清新 & 小

2017年自媒體人必備軟件免安裝錄屏軟件!

錄屏軟件 優酷錄屏軟件 現在自媒體這麽火,你還沒加入的就out啦,如果你是專門發視頻的自媒體人,那麽今天有福了,PCGOGO要推薦一款功能專一,免安裝的錄屏軟件給大家。 沒錯,就是:優酷桌面錄屏!為什麽那麽多錄屏軟件不推偏偏要推薦這一款呢?我主要是看上了他免安裝,免安裝

AMTEmuadobe軟件破解神器

adode 破解 Adobe系列軟件對大家來說應該都不陌生,PS、AI、DW、PR、FL等等都是設計師和愛好者必備軟件,軟件據用試用期,超期了需要付費才能使用。如何適合國情的使用adobe軟件呢,下面介紹一款簡單實用的破解工具--AMTEmu。 AMTEmu使用很簡

music-api-next支持網易、xiami和QQ音樂的JS爬蟲庫

dbm 穩定 javascrip earch arch github 服務器 ole http 音樂,無界 讓音樂無界 如果你苦於挑選一個全方位、多平臺、簡便易用的音樂爬蟲庫,music-api-next是不二選擇。 特性: 支持網易、蝦米和QQ三大主流音樂平臺 支持

加密貨幣投資者切注意Mac應用程式被指會偷裝後門

網路安全公司Malwarebytes在本週一(10月29)釋出的訊息稱,其論壇成員1vladimir注意到一款名為“Coin Ticker”的Mac應用程式在上週末表現出了一些可疑的行為。Malwarebytes的Mac&Mobile總監Thomas Reed在經過分析後發現,它似乎隱蔽地安裝了兩個

ScreenToGif小而實用的螢幕錄製生成gif工具

因為寫部落格或工作等原因,經常需要錄製螢幕並製作gif圖。ScreenToGif使用了小半年了,給我的感覺就是“小而實用”,大小僅2M多(壓縮後才幾百K),但卻包含了錄製及常用的gif處理功能。 ScreenToGif:僅從名字就可以瞭解到它是一款螢幕轉gif圖的軟體

前端之路好用的的jQuery前端提示外掛(webui-popover)

  最近專案有點多,日記沒多少時間寫。哈哈。 今天介紹一款好用的提示控制元件  webui-popover 像popover(彈出框)這樣的外掛用處很廣,基本所有的社交網站都有。Bootstrap自帶的popover.js就實現了這個功能。但是在使用了幾天之

Dirhunt無需進行暴力破解攻擊即可列舉Web伺服器目錄的工具

工具介紹 Dirhunt是一款經過優化的Web爬蟲,主要功能是搜尋並分析伺服器目錄。如果目標伺服器開啟了“index of”模式之後,該工具將能夠幫助你發現很多有意思的東西。除此之外,如果伺服器沒有開啟目錄列舉功能的話,Dirhunt仍然可以正常工作。值得一提的是,如果目標伺服器使用了空白的in

NDN全棧 、命名資料網路(Named Data Networking)背景介紹

最近轉到 NDN 方向進行一些研究,中文資料太少,特整理本人部分經驗供廣大愛好者參考。 一:背景 現今的網際網路沙漏架構(hourglass architecture)以一個普世通用的網路層(network layer)為中心,也就是 IP[1]。在 1970

music-api-next支援網易、蝦米和QQ音樂的JS爬蟲庫

音樂,無界 讓音樂無界 如果你苦於挑選一個全方位、多平臺、簡便易用的音樂爬蟲庫,music-api-next是不二選擇。 特性: 支援網易、蝦米和QQ三大主流音樂平臺 支援音樂關鍵詞搜尋 支援音樂

music-api-next支援網易、xiami和QQ音樂的JS爬蟲庫

音樂,無界 讓音樂無界 如果你苦於挑選一個全方位、多平臺、簡便易用的音樂爬蟲庫,music-api-next是不二選擇。 特性: 支援網易、蝦米和QQ三大主流音樂平臺 支援音樂關鍵詞搜尋 支援音樂連結下載 支援音樂評論爬取 支援回撥和async/await寫法 支援webpack打包部署 支援pm2伺服

SmartRecom乾貨滿滿,助你進階的 App 專案

前言 SmartRecom 是一款基於行為設別和個性化推薦的電影與音樂播放器。咋一聽很高大上,哈哈,不過行為識別和個性化推薦的功能目前還不完善,暫時忽略。 本著學習 Android 技術的目的,SmartRecom 使用了多款流行開源框架,以及Android 中一些重

iOS開發之窺探UICollectionViewController(五)炫酷的圖片瀏覽元件

本篇部落格應該算的上CollectionView的高階應用了,從到今天的(五),可謂是由淺入深的窺探了一下UICollectionView的用法,這些用法不僅包括SDK中自帶的流式佈局(UICollectionViewDelegateFlowLayout)而且介紹瞭如何根據你的

SILVER搭配SKETCH的輕量移動原型工具

【譯者注】作為一款設計工具,Sketch只用了1年多時間,就迅速風靡於移動設計師之間,無論是我所在的團隊和公司,還是國內外各大設計組織,都對其推崇不已,“設計流是否支援Sketch”也成為移動原型工具的重要競爭力。本文是Silver移動原型工具作者在Medium上的

果斷收藏APP從設計稿到切圖過程全方位揭祕

9月17日凌晨,IOS9正式推送,它使用的字型最終還是變了,我下面寫的內容你們也要酌情更新,因為我寫的實在趕不上它更新的速度了 iOS9使用的西文字型由Helvetica Neue變更為 San Francisco, iOS9中文字型由此前的黑體-簡變更為蘋方黑體