陳名松+黃高見++邱曉金++許笑
摘 要: 為了實(shí)現(xiàn)一種價(jià)格低廉、便攜式無線監(jiān)控系統(tǒng)來滿足智能家居的應(yīng)用要求。采用一種無線路由作為終端,在手機(jī)上開發(fā)APK作為客戶端接收顯示視頻數(shù)據(jù),在終端上編譯安裝SDK包,配置內(nèi)核USB攝像頭的驅(qū)動(dòng),并改寫內(nèi)核的USB攝像頭驅(qū)動(dòng)程序使其支持?jǐn)z像頭的使用。實(shí)驗(yàn)結(jié)果表明,可以在安卓系統(tǒng)手機(jī)上運(yùn)行APK自動(dòng)連接路由器發(fā)出的WiFi信號(hào),實(shí)現(xiàn)視頻數(shù)據(jù)的清晰監(jiān)控。
關(guān)鍵詞: 智能家居; 便攜式無線監(jiān)控系統(tǒng); APK; 嵌入式應(yīng)用; 安卓開發(fā)
在智能家居[1]快速發(fā)展的今天,對(duì)便捷、智能的視頻監(jiān)控系統(tǒng)要求也越來越高。目前存在的視頻監(jiān)控設(shè)備雖多但是價(jià)格不低,本文開發(fā)的監(jiān)控系統(tǒng)低于市場(chǎng)價(jià)格的200%~300%,而且設(shè)備體積小、安裝攜帶非常方便。隨著視頻監(jiān)控在家庭中應(yīng)用的范圍越來越廣,這個(gè)監(jiān)控系統(tǒng)很有意義。開發(fā)APK,對(duì)視頻數(shù)據(jù)進(jìn)行實(shí)時(shí)地監(jiān)控以及拍照存儲(chǔ),通過視頻服務(wù)器對(duì)數(shù)據(jù)進(jìn)行采集存儲(chǔ)與傳輸,并在Linux平臺(tái)下進(jìn)行shell腳本的應(yīng)用開發(fā),提高整個(gè)系統(tǒng)的智能化體驗(yàn)。
1 系統(tǒng)結(jié)構(gòu)
圖1為系統(tǒng)硬件結(jié)構(gòu)框圖。圖中路由器作為監(jiān)控系統(tǒng)終端,其采用MIPS架構(gòu)的RT5350作為控制系統(tǒng)的控制器。存儲(chǔ)模塊由8 MB SPI FLASH和32 MB SDRAM組成,通過USB 2.0與攝像頭連接,攝像頭直接生成JPEG格式數(shù)據(jù)。
2 終端的開發(fā)應(yīng)用
基于RT5350的硬件終端平臺(tái),要為其安裝內(nèi)核以及文件系統(tǒng)。在虛擬機(jī)上搭載運(yùn)行Ubunt 9.10并對(duì)版本號(hào)為2.6.21.x的Linux系統(tǒng)進(jìn)行編譯安裝。其工作流程圖如圖2所示。
搭建好的平臺(tái)可以進(jìn)行內(nèi)核的配置和編譯,配置內(nèi)核的USB驅(qū)動(dòng)使其支持UVC攝像頭。
2.1 修改內(nèi)核中的USB攝像頭驅(qū)動(dòng)
攝像頭中的DSP處理CMOS攝像頭傳來的原始視頻數(shù)據(jù)后通過USB接口傳給單板,USB接口基本符合UVC協(xié)議規(guī)范,但是還是有些差別,所以修改內(nèi)核中攝像頭的驅(qū)動(dòng)程序[2]使其支持UVC攝像頭的使用。因?yàn)橐薷挠跋褓Y料,必須先宣告一個(gè)特別型態(tài)的指標(biāo)變數(shù),才能正確存取記憶中的資料。把UVC_driver.c與uvc_video.c拷貝到內(nèi)核中并替換原有的代碼,然后進(jìn)行編譯,生成新的UImage_new。
2.2 視頻服務(wù)器
視頻服務(wù)器軟件主要作用:一是控制攝像頭采集視頻信息;二是將攝像頭采集的數(shù)據(jù)通過路由器的WiFi信號(hào)發(fā)布出去。定義buffer指針來存儲(chǔ)數(shù)據(jù),創(chuàng)建pthread_cond_broadcast()發(fā)出一個(gè)更新信號(hào),通知發(fā)送通道來取數(shù)據(jù)。圖像數(shù)據(jù)輸入組件input_uvc獲取圖像并壓縮編碼主要包括三個(gè)接口函數(shù),圖像輸出組件output_hattp等待buffer中的數(shù)據(jù)更新,然后從buffer中取出數(shù)據(jù)。服務(wù)器的架構(gòu)如圖3、圖4所示。
在基于IP的網(wǎng)絡(luò)協(xié)議中,選擇HTTP通信方式,創(chuàng)建線程服務(wù)打開TCP Socket等待客戶端的連接。
2.3 視頻服務(wù)器軟件開機(jī)自啟動(dòng)
在實(shí)際的應(yīng)用中必須實(shí)現(xiàn)路由器開啟后相應(yīng)的視頻服務(wù)器軟件自動(dòng)啟動(dòng),跟蹤路由系統(tǒng)的啟動(dòng)步驟,在internet.sh添加編寫腳本[3]run.sh路徑來實(shí)現(xiàn)開機(jī)自啟動(dòng),run.sh的編程流程如圖5所示。
完成腳本后,將腳本run.sh拷貝到文件系統(tǒng)bin文件夾下,在腳本internet.sh中添加/bin/run.sh。
3 客戶端的開發(fā)
Android[4]客戶端的開發(fā)中使用Java[5]語言編寫APK進(jìn)行視頻數(shù)據(jù)的接收與顯示。MJPG?Streamer的傳輸是使用Socket編程模擬HTTP協(xié)議進(jìn)行數(shù)據(jù)的傳輸,則客戶端使用GET方法進(jìn)行HTTP[6]的請(qǐng)求連接。構(gòu)造ConnectTask函數(shù)繼承異步類AsynTask避免HTTP連接阻塞UI的運(yùn)行。其中WiFi熱點(diǎn)的連接可以是自動(dòng)或者手動(dòng),并將熱點(diǎn)IP地址存入本模塊的SharedPreference。下面對(duì)客戶端的開發(fā)分三個(gè)部分來介紹:客戶端總體框架結(jié)構(gòu)、視頻的接收顯示和視頻的拍照存儲(chǔ)。
3.1 客戶端總體框架結(jié)構(gòu)
在開發(fā)中使用DefaultHttpClient類創(chuàng)建客戶端,使用HttpGet方法向服務(wù)器發(fā)請(qǐng)求,根據(jù)服務(wù)器端的要求,發(fā)送的請(qǐng)求是“GET /?action=stream\n”,構(gòu)造MjpegInputStream類使其繼承DataInputStream,實(shí)現(xiàn)了Serializable接口,在這個(gè)類中根據(jù)數(shù)據(jù)幀的大小獲得類位圖,再構(gòu)造StreamerView類繼承SurfaceView實(shí)現(xiàn)SurfaceHolder.Callback接口,在StreamerView類中構(gòu)造方法根據(jù)類位圖繪制矩形,再繪制相應(yīng)的位圖。定義Generic類增強(qiáng)程序的擴(kuò)展性和可讀性,在這個(gè)類中構(gòu)建showMsg,getNowTime,getSdCartFile,getConnectedIP以及getShrinkedPic方法來顯示時(shí)間、獲取當(dāng)前系統(tǒng)時(shí)間、獲取SD卡路徑、獲取連接到WiFi熱點(diǎn)的所有手機(jī)IP地址以及得到照片的縮略圖。
客戶端實(shí)現(xiàn)層次如圖6所示。
3.2 視頻的接收與顯示
視頻服務(wù)器輸出端輸出的是一幀數(shù)據(jù),用UE打開發(fā)現(xiàn)每一個(gè)JPG格式的圖片開始2 B都是 0xFF,0xD8;整個(gè)數(shù)據(jù)流的形式是:HTTP頭信息,幀頭(0xFF 0xD8);幀數(shù)據(jù),幀尾(0xFF 0xD9)。首先通過0xFF,0xD8找到幀頭位置:幀頭位置前的數(shù)據(jù)就是HTTP頭,里面包含Content?Length,這個(gè)字段指示了整個(gè)幀數(shù)據(jù)的長(zhǎng)度,幀頭后面的數(shù)據(jù)就是幀圖像的開始位置。創(chuàng)建MjpegInputStream類來實(shí)例化流。
構(gòu)造readMjpegFrame方法,利用BitmapFactory.decodeStream()將輸入字節(jié)流轉(zhuǎn)換為類位圖。在surfaceView繼承類中將類位圖繪制出位圖,視頻數(shù)據(jù)接收顯示的流程圖如圖7所示。
surfaceview[7]的核心在于提供了兩個(gè)線程:UI線程和渲染線程,繪制位圖的整個(gè)過程的具體步驟是繼承SurfaceView并實(shí)現(xiàn)SurfaceHolder.Callback接口→SurfaceView.getHolder()通過此方法獲得SurfaceHolder對(duì)象→SurfaceHolder.addCallback(callback)添加回調(diào)函數(shù)→SurfaceHolder.lockCanvas()獲得Canvas對(duì)象并鎖定畫布→Canvas繪畫→SurfaceHolder.unlockCanvasAndPost(Canvas canvas)結(jié)束鎖定畫圖,并提交改變,將圖形顯示。
3.3 視頻的拍照存儲(chǔ)
創(chuàng)建MainActivity類繼承Activity實(shí)現(xiàn)OnCheckedChangeListener,監(jiān)聽RadioGroup,為RadioGroup設(shè)置4個(gè)RadioButton,當(dāng)RadioButton被按下或改變時(shí)觸發(fā)onCheckedChanged方法,在此方法中定義了不同控件的相對(duì)應(yīng)操作,實(shí)現(xiàn)流程圖如圖8所示。
在checkSdCard()方法中獲得SD卡路徑,創(chuàng)建存放圖片的picturePath目錄。在SD卡中根據(jù)picturePath以當(dāng)前系統(tǒng)時(shí)間為前綴新建圖片文件,調(diào)用StreamerView的getbitmap方法獲得位圖,如果位圖不為空,根據(jù)圖片文件獲得緩沖輸出流,調(diào)用位圖的壓縮方法將圖片壓縮為JPEG格式,刷新緩存,關(guān)閉流。
通過Java進(jìn)行安卓客戶端的開發(fā),成功實(shí)現(xiàn)了視頻數(shù)據(jù)的接收顯示以及拍照存儲(chǔ),其效果如圖9所示。
4 結(jié) 語
經(jīng)過測(cè)試本監(jiān)控系統(tǒng)可以實(shí)現(xiàn)55 m2的檢測(cè)距離,這在家庭的應(yīng)用中是足夠的。同時(shí)可以實(shí)現(xiàn)攝像頭的熱拔插以及服務(wù)器軟件的開機(jī)自啟動(dòng)。在手機(jī)上安裝APK靈活地實(shí)現(xiàn)視頻的實(shí)時(shí)監(jiān)控以及拍照存儲(chǔ)。視頻延遲時(shí)間在2 s左右,延遲時(shí)間是后面要重點(diǎn)解決的問題。
參考文獻(xiàn)
[1] 馬季.智能家居遠(yuǎn)程監(jiān)控系統(tǒng)的研究與實(shí)現(xiàn)[D].青島:中國海洋大學(xué),2009.
[2] 張輝.基于V4L2的嵌入式視頻驅(qū)動(dòng)程序開發(fā)與實(shí)現(xiàn)[D].合肥:安徽大學(xué),2010.
[3] 張根寶,胡杰.Linux集群環(huán)境下監(jiān)控Web服務(wù)器的Shell腳本設(shè)計(jì)[J].化工自動(dòng)化及儀表,2010(10):99?101.
[4] SATYA K,DAVE M,SAYED H.精通Android 3[M].北京:人民郵電出版社,2011.
[5] ECKEL B. Thinking in Java [M]. 3rd ed. USA: Prentice Hall PTR, 2002.
[6] 李濤.基于Android的智能家居APP的設(shè)計(jì)與實(shí)現(xiàn)[J].蘇州:蘇州大學(xué),2014.
[7] Summer.陽和移動(dòng)開發(fā)網(wǎng)站[EB/OL].[2015?09?04].http://www.mobile?open.com/?s=surfaceview&x=0&y=0.
[8] 于艷萍,朱曉智,王中訓(xùn).基于ARM9和USB攝像頭的網(wǎng)絡(luò)視頻采集系統(tǒng)設(shè)計(jì)[J].現(xiàn)代電子技術(shù),2011,34(24):49?51.