楊志勇 李衛鋒 張 盛
(清華大學深圳研究生院 廣東 深圳 518055)
近年來人工智能技術的快速發展,語音識別技術逐漸成熟,同時隨著Android智能手機和移動互聯網的普及,人們可以隨時隨地接入互聯網。如何通過手機實時查看家中的情況,以及家中出現各種狀況時能夠及時地通知到我們,成了大家迫切希望解決的問題。因此開發基于Android平臺的音視頻監控系統對改善人們的居住條件具有重大意義,未來發展空間巨大。
本文介紹了一種基于Android平臺的音視頻監控系統[1],該系統分為數據采集端和用戶手機APP監控端。數據采集端可以安裝在各種帶有攝像頭和錄音功能的Android終端上,用戶能夠通過語音喚醒系統,然后控制攝像頭的打開與關閉,同時還可以接收其他語音指令并通過云端服務器發送到用戶手機APP監控端。在用戶手機APP監控端可以對收到的語音指令做出對應的響應,同時也可以發送消息給數據采集端。因此,本系統可以非常方便地在數據采集端與手機APP監控端進行互動,大大增強了傳統監控系統的功能,同時可以根據需要隨時打開和關閉視頻監控,節約服務器資源和網絡帶寬,為監控系統提供了一個非常好的解決方案,其主要具有以下幾個特點:
1) 數據采集端可以直接安裝在Android移動終端上,不需要專用設備,可以很好地利用家中的平板電腦、手機等設備,做到靈活使用,一機多用。
2) 支持語音識別功能,能夠在數據采集端與用戶APP端進行消息互動,可根據需要開關監控設備。
3) 采用RTMP協議進行音視頻傳輸,Red5作為流媒體服務器,支持高清視頻,能夠動態設置是否在服務器上保存音視頻數據。
監控系統主要是由數據采集端、云端服務器和手機APP組成。數據采集端主要負責音視頻數據的采集和語音指令的識別處理;云端服務器則負責音視頻流媒體的傳輸、各種控制指令的解析和轉發;手機APP負責UI展示、消息接收、音視頻的解碼播放等功能[2-3],其總體框架如圖1所示。

圖1 智能監控系統總體框架圖
在數據采集端用戶通過語音與設備進行交互,設備檢測到人的聲音后會進行識別處理,然后執行相應的指令,采集端可以是手機、平板電腦等Android設備,通過連接路由器的Wi-Fi熱點或4G網絡等接入Internet,然后與服務器進行通信。手機APP通過網絡獲取服務器中的音視頻和各種指令數據,同時也可以發送指令到服務器上,進而轉發到對應的采集端。
監控系統的數據采集端和手機APP均采用Android系統開發,云端服務器采用Red5作為流媒體服務器,業務邏輯服務器使用Apache MINA網絡應用框架。
數據采集端是監控系統的核心模塊,主要包括指令識別以及音視頻的采集和推送功能。指令識別包括文本指令和語音指令。文本指令主要是指用戶通過手機APP發送過來的操作指令。語音指令一般為采集端通過麥克風獲取到的語音,然后轉換成對應的文本指令,其功能主要分為:針對采集端的內部指令和針對用戶APP的用戶指令。如果是內部指令如打開、關閉攝像頭等,則采集終端會執行相應的動作;如果是外部指令則發送給服務器,進而轉發到APP端由用戶進行處理。本系統語音指令采用百度語音識別技術,其具有識別率高、基礎服務免費、接入流程簡單等優勢。采集端指令識別的工作流程如圖2所示。

圖2 指令識別處理流程
采集終端上電啟動后,會檢查是否有接收到用戶的文本指令,如果有則首先執行文本指令,如果沒有則初始化語音識別服務,等待喚醒。當檢測到特定的喚醒詞后,開啟指令識別功能,然后判斷指令是內部指令還是針對用戶的外部指令,如果是內部指令則直接執行,否則就發送到服務器,進而轉發給相應的用戶APP端。
音視頻的采集主要是獲取麥克風和攝像頭的音視頻數據,使用H.264進行編碼,然后對其進行RTMP協議封裝,最終發送到Red5流媒體服務器。在Android系統上Mediacodec類封裝了H.264的各種硬編解碼功能,它是Android在4.1中加入的API,是一種低級別的API,可以非常方便地訪問設備的媒體編解碼器,因此系統采用Mediacodec將音視頻編碼為H.264格式。音視頻傳輸采用RTMP(Real Time Messaging Protocol) 即實時消息傳輸協議,它是Adobe公司開發的為Flash播放器和服務器之間進行音視頻傳輸的一種開發協議,其運行在TCP協議之上,能夠支持點播、直播功能,并且具有低延遲的特點,其在視頻監控領域被廣泛使用。
云端服務器包含業務邏輯服務器和流媒體服務器。業務邏輯服務器主要負責處理用戶的注冊登錄、設備的上線、指令消息的轉發、消息推送等功能。流媒體服務器主要是進行音視頻的保存和轉發。
業務邏輯服務器采用Apache MINA框架[4],它是一種幫助用戶開發高性能和高穩定性的網絡應用框架,支持TCP和UDP傳輸,具有異步的、非阻塞的、事件驅動的API,同時還支持Java NIO特性,能夠非常方便地擴展各種功能的數據過濾特性,在整個網絡通信中能夠與應用程序互相隔離開來,客戶端和服務器只需要處理相應的業務邏輯即可。
流媒體服務器使用Red5[5-6],其為Java 語言開發、開放源代碼的Flash流媒體服務器,與Macromedia公司的Flash媒體服務器兼容,支持Linux、MacOS、Windows平臺。它的設計比較靈活,采用了插件的方式,可以非常方便的集成,能夠對FLV、MP3文件進行流化,目前已經有成千上萬的公司開始使用RED5,包括亞馬遜和Facebook等。在本系統中數據采集端和用戶APP監控端與云端服務器的交互流程如圖3所示。

圖3 采集端、APP和服務端通信框架圖
數據采集端設備啟動后會通過業務邏輯服務器進行設備的上線注冊,獲取流媒體的RTMP地址和消息的發送與接收,然后打開攝像頭推送視頻流到流媒體服務器。手機APP用戶登錄后,可以綁定采集端設備并獲取設備信息,如設備ID、RTMP地址等,從而可以向流媒體服務器獲取視頻流數據,同理也可以與業務服務器進行消息的發送與接收。
用戶APP監控端的主要功能為實現用戶注冊登錄、獲取設備信息、查看數據采集端設備發送過來的監控視頻等功能[7]。其操作流程如圖4所示。

圖4 用戶APP處理流程
用戶注冊登錄后會從服務器同步綁定的各種設備并展示在主界面上,如果沒有獲取到設備,則進入綁定設備列表進行綁定,綁定成功后會顯示設備圖標及名稱,點擊設備圖標會啟動一個新的Activity進入到設備的控制面板,從而可以執行針對設備的各種控制操作。圖5為注冊登錄及設備控制面板界面。

圖5 用戶APP登錄及設備控制面板
在設備的控制面板可以查看從數據采集端接收到的各種指令消息,點擊“查看監控畫面”即可打開流媒體播放器,播放采集端傳輸過來的音視頻數據。
系統中語音的正確識別、解析、轉發和執行是體現系統靈活性的關鍵。數據采集端將獲取的音視頻數據進行編碼封裝并發送到流媒體服務器,以及如何在手機APP上進行播放給系統的實現帶來了挑戰。
語音識別功能主要是通過對語音信號進行采集、特征提取、模式匹配等技術將其轉換為相應的文本消息,然后采用自然語言處理技術對文本消息進行語義解析[8-9],最終轉換成能夠被機器識別和理解的文本指令。系統中采用百度語音SDK進行開發,它集成了語音采集、語音預處理等功能,并且支持離在線融合技術,能夠根據網絡自動判斷使用本地引擎還是云端引擎。其采用的自然語言處理技術支持三十多個領域的語義理解,可以滿足大部分的語音交互場景,目前的識別準確率可以達到97%以上。數據采集端通過語音SDK獲取文本指令,然后根據其內容進行內部處理或者通過網絡發送到服務器進而推送到用戶APP端,同時用戶APP端也可以發送控制指令到服務器,然后推送到對應的采集端設備,達到了雙向通信功能。其內部實現流程如圖6所示。

圖6 APP與數據采集端通信
服務器收到用戶APP端和數據采集端的指令后,都需要對指令進行解析、重組,并將信息同步到MySQL數據庫中進行保存記錄,然后再發送給對應的接收方。
系統的音視頻編碼器分別采用AAC和H.264格式進行編碼。AAC是針對音頻數據而設計的一種壓縮格式,其具有非常高效的編碼算法,支持多聲道,具有很高的數據壓縮比,在網絡傳輸中應用非常普遍。H.264是MPEG4之后開發的新一代數字視頻壓縮算法,具有碼率低,支持高質量的圖像數據,并且具有非常好的網絡適應能力和糾錯恢復功能,同時在大多數Android系統上能夠通過MediaCodec進行硬編碼。
在Android系統上音頻數據通過調用AudioRecord進行采集,采樣率使用44.1 kHz,音頻格式使用ENCODING_PCM_16BIT,音頻通道使用CHANNEL_CONFIGURATION_STEREO。在錄音之前首先調用new AudioRecord初始化AudioRecord。然后新建一個AudioRecordThread線程,在此線程中開啟錄音操作,然后把錄取的音頻數據發送到回調函數onRecvAudioData中進行編碼處理,核心代碼如下:
//初始化AudioRecord
mAudioRecord=new
AudioRecord(MediaRecorder.AudioSource.MIC,sampleRate,audioChannel,audioFormat, buffsize);
//開啟錄音線程進行錄音
AudioRecordThread=new Thread(new Runnable() {
public void run() {
//開始錄音
mAudioRecord.startRecording();
audioData, 0, dataSize);
//獲取audioData音頻數據
……
//編碼音頻數據
onRecvAudioData(audioData)
}
});
視頻數據的采集通過調用Camera接口的回調函數onPreviewFrame獲取,其部分實現代碼如下:
Public Camera.PreviewCallback
getPreviewCallback() {
return new Camera.PreviewCallback() {
public void onPreviewFrame(final byte[] data, final Camera camera) {
//data為攝像頭圖像數據
}
};
}
RTMP協議主要用來在FLV(Flash Video)和服務器之間進行音視頻通信[10],因此編碼后的音視頻數據需要封裝成FLV可以識別的數據格式。FLV格式分為Header和Body二部分,而Body則由一個個Tag組成,所以在發送數據時需要先發送Header。以下為RTMP初始化的部分代碼。
rtmp=RTMP_Alloc();
//分配RTMP實例
RTMP_Init(rtmp);
//進行RTMP初始化
//設置RTMP連接超時時間
rtmp->Link.timeout=timeOut;
//設置RTMP的URL
RTMP_SetupURL(rtmp,(char*)url.c_str());
//使能寫功能
RTMP_EnableWrite(rtmp);
//開始連接RTMP服務器
if (!RTMP_Connect(rtmp, NULL)) {
return -1;
}
//連接RTMP流
if (!RTMP_ConnectStream(rtmp, 0)) {
LOGI(″RTMP_ConnectStream error″);
return -1;
}
由于RTMP的流媒體服務器不對音視頻數據進行解碼和播放,在發送數據之前,需要將音視頻的編碼信息發送到流媒體服務器,因此首先需要獲取音視頻的編碼參數。而編碼參數SPS(序列參數集)、PPS(圖像參數集)正好包含在MediaCodec編碼后的前二幀視頻數據中,同時也是FLV視頻中Body數據的首個Tag,因此調用pushSpsPpsData函數先提取SPS和PPS進行發送。同理對于AAC音頻數據通過調用pushAudioInfo函數發送其編碼信息到流媒體服務器。最終都是調用RTMP_SendPacket(RTMP*r,RTMPPacket*packet,int queue)函數進行發送,其內部基于TCP協議進行實現。
在本監控系統中,用戶可以根據需要選擇是否在流媒體服務器上保存數據,因此在設備采集端RTMP初始化時可以選擇live、record、append三種模式,其中live模式為不保存數據,record模式為保存數據,append為追加模式保存數據。如設置live模式則設置對應的標志位rtmp->Link.lFlags |=0x40; record模式為0x80,append為0x100。
在用戶APP端視頻的播放采用Google開源的ExoPlayer播放器,其能夠支持HTTP動態自適應流,能夠非常方便地自定義設計和擴展。整個音視頻的采集播放流程如圖7所示。

圖7 音視頻采集播放流程
系統的測試中,云端服務器采用阿里云的Linux平臺服務器,配置為CPU 1核,內存1 GB,網絡為1 Mbps,數據采集端和用戶APP端分別在Wi-Fi和4G網絡的情況下,發送音視頻可以非常流暢的顯示,其數據采集端和用戶APP端的監控畫面顯示如圖8所示,左邊手機為采集端,通過攝像頭獲取音視頻數據,右邊手機為用戶APP端,正常獲取到了采集端的音視頻。

圖8 采集端(左)和APP端(右)
隨著移動互聯網、人工智能技術的發展,語音識別、圖像分析技術變得越來越成熟,這些技術引入到視頻監控領域會大大增強監控系統的功能。通過增加語音識別功能,改變了傳統監控系統只能單方面通信的功能,而引入云端服務器、用戶監控端可以讓用戶隨時隨地查看監控系統,增加了監控系統的可用性,提供了一個非常有效的解決方案。