徐珂航 宋曦 吳紅 張慶 李建兵
(1國網(wǎng)眉山供電公司,四川眉山 511402)
(2四川省電力公司,四川成都 610041)
統(tǒng)一通信Android客戶端語音消息的實現(xiàn)
徐珂航1宋曦2吳紅1張慶1李建兵1
(1國網(wǎng)眉山供電公司,四川眉山 511402)
(2四川省電力公司,四川成都 610041)
為了實現(xiàn)統(tǒng)一通信Android客戶端語音消息功能并減少網(wǎng)絡(luò)傳輸量,在使用XMPP的基礎(chǔ)之上,通過分析Smack 和Speex等關(guān)鍵技術(shù),結(jié)合移動設(shè)備自身的特性,設(shè)計了移動端語音消息的收發(fā)機制,高效地實現(xiàn)了Android客戶端的語音消息功能,并充分考慮用戶體驗,提供重發(fā)機制,通過移植Speex到Android平臺,使用其完成編解碼工作,極大地降低了壓縮后輸出文件的體積,減少了移動端的網(wǎng)絡(luò)傳輸量。最后說明了實現(xiàn)效果,指出了未來的研究方向。
語音消息Smack減少傳輸量XMPP Speex
統(tǒng)一通信(Unified Communication,UC)是一種將傳統(tǒng)的通信技術(shù)和飛速發(fā)展的計算機技術(shù)融合起來的新型通信模式。統(tǒng)一通信系統(tǒng)將語音電話、視頻、即時消息、數(shù)據(jù)文件、傳真和電子郵件等多種信息類型融為一體,從而增加辦公的靈活性,提高辦公效率[1]。
即時通信(Instant Messaging,IM)是統(tǒng)一通信的基本業(yè)務(wù)功能,通過即時通信發(fā)送文字、圖片、語音、文件等多媒體數(shù)據(jù),使得用戶能方便靈活的溝通,而不必局限于必須要強實時的通話才能完成信息的交換。IM系統(tǒng)中的語音消息更是提供了死板的文本交流之外的另一種更為豐富的選擇??蓴U展通訊和表示協(xié)議(Extensible Messaging and Presence Protocol,XMPP)作為一種基于XML的開放式標(biāo)準(zhǔn),已經(jīng)廣泛的被即時通信系統(tǒng)所應(yīng)用[2],但是XMPP協(xié)議并沒有具體的規(guī)定語音消息的收發(fā)。當(dāng)前主流的移動操作系統(tǒng)有Android和iOS,語音文件的格式需要通過一定的轉(zhuǎn)換才能在2種客戶端之間互通,并且移動端的文件傳輸在2G/3G網(wǎng)絡(luò)下對文件大小相當(dāng)敏感,傳輸操作必須要考慮如何節(jié)省網(wǎng)絡(luò)流量的消耗[3]。
文在XMPP的基礎(chǔ)上,制訂語音消息收發(fā)的流程,實現(xiàn)語音消息的收發(fā),并且利用Speex技術(shù)來完成語音的壓縮,解決不同移動客戶端之間的語音互通,從而提供了一種較好的統(tǒng)一通信Android客戶端語音消息的解決方案。
2.1 XMPP
XMPP是一個可擴展標(biāo)記語言XML應(yīng)用,它讓任何2個或多個網(wǎng)絡(luò)實體之間進行結(jié)構(gòu)化和可擴展的準(zhǔn)實時信息交流。XMPP的目標(biāo)是允許2個(或多個)實體通過網(wǎng)絡(luò)來交換相關(guān)的結(jié)構(gòu)化數(shù)據(jù)[4]。XMPP典型地使用分布式的“客戶端-服務(wù)器”體系結(jié)構(gòu)來實現(xiàn),客戶端需要連接到服務(wù)器來獲得對網(wǎng)絡(luò)的訪問,之后才被允許和其他實體交換XML節(jié)。這樣XMPP就提供一種異步的端到端的結(jié)構(gòu)化數(shù)據(jù)交換技術(shù),使得客戶端和服務(wù)器在一個分布式的可全球?qū)ぶ返木W(wǎng)絡(luò)中直接使用持久的XML流。
2.2 Smack on Android
Smack是一個XMPP協(xié)議的Java實現(xiàn),提供一套可擴展的API,aSmack是Smack在Android端的構(gòu)建。Smack使用Provider機制允許以定制XML的方式來增加新的功能。在開發(fā)過程中,XMPP服務(wù)器使用開源的OpenFire服務(wù)器,Smack位于客戶端,其作用是將客戶端服務(wù)器的信息交換和客戶端的的界面呈現(xiàn)連接起來,整個結(jié)構(gòu)如圖1所示。
圖1 Smack在系統(tǒng)中的地位
Smack中一個重要的機制是Provider,簡單來說Provider 是Packet的解析器,Packet是Smack與服務(wù)器之間通信的消息包,具體的XMPP實現(xiàn)就是由多個Packet來完成的。對于擴充的功能需要自定義客戶端與服務(wù)器通信的消息方式,這時只需要編寫自定義的Packet以及對應(yīng)的Provider,并注冊Provider,之后,Smack會將對應(yīng)的Packet分發(fā)給指定的Provider,整個擴充工作是以插件的形式完成,不需要修改Smack原有代碼。
2.3 Speex
Speex是一套開源、無專利保護的音頻壓縮格式,Speex工程著力于提供一個高性能語音編解碼方案來降低語音應(yīng)用的門檻。Speex具有多采樣率、多位率、高質(zhì)量等特性,而且對于丟包有一定的魯棒性,非常適合在移動設(shè)備上應(yīng)用[5]。另外,相對于其它編解碼器,Speex也很適合網(wǎng)絡(luò)應(yīng)用,在網(wǎng)絡(luò)應(yīng)用上有著自己獨特的優(yōu)勢。
語音傳輸類似文件數(shù)據(jù)的傳輸,XMPP中規(guī)定了3種數(shù)據(jù)傳輸方式:Out-of-Band Data、In-Band Bytestream、Socks5[6]。其中第1種方式適合傳輸?shù)谌椒?wù)器上的資源,第2種方式適合傳輸較小的數(shù)據(jù),通過直接攜帶在XML中進行傳輸,第3種方式通過建立點對點的連接或者使用服務(wù)器代理的方式,實現(xiàn)2個節(jié)點之間的直接傳輸。只要實現(xiàn)了基本的消息傳輸就能支持前2種方式,此外Smack提供了Socks5方式收發(fā)文件的支持。
3.1 在線語音的傳輸
根據(jù)用戶是否在線,語音消息的收發(fā)又有所不同,首先介紹在線語音消息的實現(xiàn)。
發(fā)送語音文件時,首先要解決的一個問題就是客戶端如何分辨發(fā)送方發(fā)送的是語音消息。為了解決這個問題,使用一個預(yù)先發(fā)送的文本消息來通知接收方,此消息包含了語音文件名和語音時長,客戶端收到此消息后就準(zhǔn)備接收之后發(fā)送的語音文件。因為此文本消息只是對語音消息的描述,客戶端不需要真正的將此語音消息顯示給用戶,而是首先將此消息放入接收隊列中,等語音文件接收完成之后,客戶端通知用戶有新消息送達(dá)。
文本消息的發(fā)送與接收使用Smack提供的Chat類,此類已經(jīng)實現(xiàn)了文本消息的收發(fā),Smack中廣泛的使用了觀察者模式,Chat類就是一個很好的例子,對于接收文本消息的處理,只需要一個實現(xiàn)了MessageListener接口的觀察者,并將觀察者添加到Chat對象中。當(dāng)事件發(fā)生后,被觀察者Chat對象會自動通知觀察者MessageListener,觸發(fā)相應(yīng)的處理函數(shù)。具體的步驟如下:
①根據(jù)聊天對象的JID從對話緩存中獲取對應(yīng)的Chat對象,如果緩存中沒有此JID的Chat對象,則創(chuàng)建Chat對象,并將其保存到對話緩存中;
于給Chat對象添加實現(xiàn)了MessageListener的觀察者,在觀察者的processMessage函數(shù)中完成消息接收的處理操作;
③調(diào)用Chat對象的消息發(fā)送函數(shù)發(fā)送形如“/~#〉filename&10〈V%~”的消息,“/~#〉”前綴表示此消息不是實際的文本消息,“〈V%~”后綴表示此消息是一條語音消息的描述,中間的內(nèi)容為文件名稱與語音時長(秒),二者由“&”符號連接。
整體來看,在線語音的發(fā)送流程如圖2所示。
圖2 在線語音傳輸流程
以上的流程是在每一步驟都能成功完成的預(yù)想下,實際的生產(chǎn)環(huán)境中有可能出現(xiàn)發(fā)送失敗的情況,本文將每一步都?xì)w為一個狀態(tài),根據(jù)各個狀態(tài)來實現(xiàn)消息的重發(fā),判斷是否需要顯示重發(fā)提示的流程如圖3所示。
圖3 判斷是否需要重發(fā)流程圖
3.2 離線語音的實現(xiàn)
上一節(jié)介紹了接收方在線時語音消息的接收與發(fā)送,當(dāng)接收方不在線時,點對點的連接就無法建立,因此不能繼續(xù)使用之前的方式發(fā)送消息。為了解決離線時的文件傳輸問題,采用將離線語音文件保存在服務(wù)器上的實現(xiàn)方式,當(dāng)接收方登錄之后,根據(jù)接收到的離線消息再從服務(wù)器以FTP的形式下載語音文件。
以Client A作為發(fā)送方,Client B作為接收方來描述問題,Client A發(fā)送離線語音消息的第一步同發(fā)送在線語音消息一致,客戶端首先發(fā)送語音描述消息,Smack已經(jīng)提供了文本消息的離線支持,所以直接發(fā)送即可。之后的操作就有所差異,完成第一步的操作之后,如果接收方Client B登錄,就會收到服務(wù)器發(fā)送來的離線文本消息,這時要解決的問題就是Client B如何得到實際的語音文件,前文已經(jīng)說過離線語音文件將會上傳到FTP服務(wù)器上,因此需要完成的操作就是Client A上傳語音文件到FTP服務(wù)器,而Client B登錄之后在適當(dāng)?shù)臅r刻下載語音文件。
關(guān)于語音文件的上傳,如果使用直接連接FTP服務(wù)器并上傳文件的方式,服務(wù)器首先要通知Client A FTP服務(wù)器的地址以及用戶名密碼,由于語音消息一般會頻繁發(fā)送,每次發(fā)送都需要獲知服務(wù)器通知的FTP服務(wù)器信息,無疑增加了移動端的網(wǎng)絡(luò)傳輸量;并且語音文件的大小一般也不是很大(100 K以下),基于這2點,本文采用的方式是先將語音文件轉(zhuǎn)換成base64格式的文本,以In-Band Bytestream的形式將文本發(fā)送到服務(wù)器。
離線語音的接收需要在服務(wù)器端增加操作,服務(wù)器在收到離線文本后,將文本保存到FTP服務(wù)器上,在Client B登錄之后,服務(wù)器給Client B發(fā)送下載文件的消息,加上之前發(fā)送的描述消息,Client B就能組成一條完整的語音離線消息,并呈現(xiàn)給用戶。離線語音的過程如圖4所示。
圖4 離線語音傳輸流程
4.1 Speex的Android移植
Speex是由C語言編寫的,目前已有Java的實現(xiàn)版本JSpeex,但是JSpeex在Android端的表現(xiàn)不夠理想,尤其是移動端的開發(fā)必須要提供良好的用戶體驗。因此本文使用本地調(diào)用的方法將Speex移植到Android端。具體的方式為:
①創(chuàng)建項目,在其中建立jni文件夾;
于將Speex源代碼中l(wèi)ibspeex和include文件夾拷貝到j(luò)ni目錄中;
③在jni目錄中建立Android.mk,內(nèi)容為編譯源文件列表;
④在jni目錄中添加Application.mk,內(nèi)容為APP_ABI:= armeabi armeabi-v7a;
⑤在目錄jni/include/speex/下創(chuàng)建配置類型頭文件speex_config_types.h,內(nèi)容如下:
#endif
⑥在命令行中切換到j(luò)ni目錄下輸入ndk-build命令,生成libs/armeabi目錄和libs/armeabi-v7a目錄;
⑦編寫調(diào)用本地方法的Speex工具類。
4.2 音頻捕獲與播放
編寫好的Speex工具類,使用本地方法encode編碼,使用本地方法decode解碼。當(dāng)錄音事件被觸發(fā)后,錄音的具體步驟如下:
①首先啟動SpeexRecorder線程;
于SpeexRecorder使用Android提供的AudioRecorder開始錄音;
③SpeexRecorder啟動SpeexEncoder線程開始編碼;
④錄音過程中,SpeexRecorder不斷將音頻數(shù)據(jù)放入緩沖區(qū)tempBuffer;
⑤SpeexEncoder不斷從緩沖區(qū)中取出音頻數(shù)據(jù)進行編碼,并存入spx文件中;
⑥不斷重復(fù)④和⑤操作,直到錄音結(jié)束。
播放的步驟與錄音正好相反,播放時SpeexDncoder不斷將編碼文件解碼放入緩沖區(qū),再使用Android提供的AudioTrack播放音頻。
Android中的MediaRecorder也提供了音頻壓縮功能,輸出格式為amr,表1是在音頻質(zhì)量類似情況下使用Speex與使用MediaRecorder輸出文件大小的對比,可以看出使用Speex能在不降低音頻質(zhì)量的情況下減少網(wǎng)絡(luò)的傳輸量。
表1 MediaRecorder與Speex輸出文件對比
用戶通過以上介紹的Android端語音消息功能即可完成語音消息的收發(fā),從而能以符合人類交流習(xí)慣的方式隨時隨地的進行弱實時性的溝通。實踐表明,本文提供的語音消息解決方案使通信雙發(fā)都獲得了比較好的用戶體驗。但是,在語音消息功能的實現(xiàn)過程中仍存在一些值得改進的地方。例如,從一個對應(yīng)用產(chǎn)品要求的角度來看,移動端的開發(fā)要更充分的分析用戶的使用習(xí)慣,提供更為合理以及人性化的UI與操作流程;播放語音時采用文件讀取與解碼播放同時進行的方式降低了客戶端的性能。這些都將是未來的研究方向。
[1]劉啟勝.統(tǒng)一通信的現(xiàn)狀及其發(fā)展前景分析[J].廣東通信技術(shù),2010,30(11):71-73.
[2]潘鳳,王華軍,苗放,等.基于XMPP協(xié)議和Openfire的即時通信系統(tǒng)的開發(fā)[J].計算機時代,2008(3):15-16,19.
[3]庾志成.移動互聯(lián)網(wǎng)的發(fā)展現(xiàn)狀和發(fā)展趨勢[J].移動通信, 2008(9):22-24.
[4]張彥,夏清國.Jabber/XMPP技術(shù)的研究與應(yīng)用[J].科學(xué)技術(shù)與工程,2007(6):1032-1035,1039.
[5]謝曉鋼,蔡駿,陳奇川,等.基于Speex語音引擎的VoIP系統(tǒng)設(shè)計與實現(xiàn)[J].計算機應(yīng)用研究,2007(12):320-323.
[6]李鯤鵬.基于Android的即時通訊平臺研究與實現(xiàn)[D].華南理工大學(xué),2013.
Implementation of Voice Message on UC Android Client
XU Ke-hang1,SONG Xi2,WU Hong1,ZHANG Qing1,LI Jian-bing1
(1 State Grid Meishan Power Supply Company,Meishan Sichuan 511402,China)
(2 Sichuan Electronic Power Corporation,Chengdu Sichuan 610041,China)
In order to implement the voice message function on the UC Android client and to reduce the network transmission traffic, the Rx/Tx mechanism of voice message on mobile client is designed by analyzing on key technologies such as Smack and Speex based on XMPP application and considering the characteristics of mobile equipment.This design implements efficiently the voice message functions on Android client and provides the resend mechanism by fully considering user experience.By migrating Speex to Android platform and making it complete CODEC,the size of output file is greatly decreased and the network transmission traffic of the mobile client is reduced.Finally,the implantation effect is presented,and the future research direction is pointed out.
voice message;Smack;reduce transmission traffic;XMPP;Speex
TN919.3
A
1008-1739(2015)06-59-4
定稿日期:2015-02-26