Android屏幕投影及反向控制原理

這一周過的是夠有意思的掌动,先停兩天電粗恢,然后感冒了眷射,然后項(xiàng)目出Bug了罚屋,然后發(fā)燒了脾猛,呵呵噠猛拴,趕緊只能過來寫點(diǎn)東西壓壓驚。鑒于最近正好在研究Android投屏及反像控制和Android雙開的技術(shù)原理跛溉,本周就先寫寫Android投影以及反向控制的原理了。

1 目標(biāo)

  • Android投影屏幕到電腦
  • 電腦端反向控制Android手機(jī)(如QQ刹勃,微信伍宦,淘寶...)

2 背景

最近在項(xiàng)目小組中遇到一件事,小組有時(shí)候需要演示demo供大家參考遇骑,當(dāng)演示Android手機(jī)投屏?xí)r势篡,就需要借助第三方軟件進(jìn)行投屏念祭,比如說360手機(jī)管家的演示功能還有一個(gè)神器Vysor(通過Google瀏覽器投屏并控制手機(jī))粱坤,但是隨之也會(huì)帶來問題,通過反編譯Vysor的Apk可以看到它是使用adb命令截屏然后通過Async網(wǎng)絡(luò)庫傳輸屏幕投影給后臺(tái)株旷,既然有網(wǎng)絡(luò)操作,如果是公司比較重要的東西齿尽,萬一第三方在后面偷偷保留了演示錄屏(我相信這些應(yīng)用應(yīng)該都不會(huì)循头,有職業(yè)操守),然后可能就會(huì)有自己去做投屏的需求。

3 預(yù)覽圖

今天寫的原理都是經(jīng)過本人實(shí)現(xiàn)過的,目前PC端已經(jīng)正常工作盒使,并且可以投屏多臺(tái)Android苞慢。Web端通過node.js websocket webrtc HTML實(shí)現(xiàn)的目前還在開發(fā)中挽放,鑒于之前沒怎么用過前端吗蚌,所以寫的比較慢。

目前測(cè)試實(shí)時(shí)投影在真實(shí)機(jī)上還可以。
PC端的動(dòng)態(tài)截圖如下陨收。

時(shí)間.gif
p2
地圖.gif

4 原理圖

原理.png

5 投屏

投影屏幕,可以去傳輸圖像也可以去傳輸視頻宏悦,具體使用哪一種就去看你的需求。而投影圖像又分為通過ADB命令去截取圖像以及通過Android的ImageReader獲取圖像然后通過網(wǎng)絡(luò)傳輸兩種方式诗越,所以投屏的實(shí)現(xiàn)是有很多種的块促,你想使用哪一種都是可以的。

圖像流

現(xiàn)在的產(chǎn)品看到他們都是借助手機(jī)連線到電腦端的,通過adb直接去截取圖片屎鳍,這樣的話就會(huì)很快,如果你只是在公司內(nèi)部用貌踏,使用公司的局域網(wǎng)進(jìn)行通信我覺得也已經(jīng)夠用了,因此也可以實(shí)現(xiàn)通過網(wǎng)絡(luò)Socket直接去傳輸圖像的字節(jié)碼眷昆。但是現(xiàn)在手機(jī)分辨率可高了攘滩,因此如果你不對(duì)圖像進(jìn)行處理直接通過Socket傳輸?shù)脑捘敲磿?huì)讓PC端投屏變得很卡赖瞒,因此AndroidClient可以先對(duì)圖像進(jìn)行壓縮裁剪之后再去傳輸。

Android端這塊我是開啟了一個(gè)Service,然后通過ImageReader獲取屏幕的圖像伺通,之后對(duì)圖片進(jìn)行裁剪壓縮之后再利用Socket傳輸圖像數(shù)據(jù)信息涮帘。其中的基本代碼流程如下:

virtualDisplay = mediaProjection.createVirtualDisplay("MainScreen",width,height,dpi
                ,DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC,imageReader.getSurface()
                ,null,screenHandler);
        imageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
            @Override
            public void onImageAvailable(ImageReader imageReader) {
                Log.i(TAG, "call onImageAvailable");
                try {
                    //如果有圖片那么就獲取
                    img = imageReader.acquireLatestImage();
                    if (img != null) {
                     //圖像處理
                     //send 數(shù)據(jù)
                    }
            }
  }

視頻流

起初我采用的就是圖片傳輸,后來想想其實(shí)還是有其他方案的妇多,其實(shí)可以通過獲取Android手機(jī)的屏幕視頻流通過H264進(jìn)行編碼進(jìn)行傳輸給后臺(tái)Server,這樣可以讓畫面顯示的更加流暢七问。Android Client里面有一個(gè)MediaCodec的類以及VirtualDisplay類可以去讀取Android的屏幕流饶氏,然后轉(zhuǎn)化為H264視頻流疹启。

Android端依然是開啟一個(gè)Service去獲取屏幕流籍琳,但是編碼H264時(shí)會(huì)有一個(gè)坑,就是需要你去手動(dòng)加入SPS和PPS呜达,之后才是視頻幀。此處的處理代碼如下

//1,get SPS and PPS
MediaFormat outputFormat = codec.getOutputFormat();
ByteBuffer sps = outputFormat.getByteBuffer("csd-0");    // SPS
ByteBuffer pps outputFormat.getByteBuffer("csd-1");    // PPS
//2, change ByteBuffer to byte[]
...
//3, send byte[] to server by socket
...

6 反向控制

PC端去控制手機(jī)有如下兩大塊技術(shù):

  • Android通過USB數(shù)據(jù)線或者Wifi連接打開ADB,通過本地執(zhí)行ADB command
  • Android手機(jī)root掉,通過Android客戶端執(zhí)行ADB command

Adb連接方式有如下兩種:

  • Usb數(shù)據(jù)線
  • Wifi: adb tcpip 5555, adb connect android_ip_address

PC應(yīng)用程序:
Server端的代碼主題邏輯不復(fù)雜:通過Socket接收Android 客戶端傳過來的圖像數(shù)據(jù)信息解壓縮顯示到Ui上面扭倾,當(dāng)用戶點(diǎn)擊UI時(shí)獲取鼠標(biāo)點(diǎn)擊的坐標(biāo),通過比例換算轉(zhuǎn)化成實(shí)際Android真機(jī)的坐標(biāo),之后通過ADB執(zhí)行對(duì)應(yīng)的Command命令撬槽,然后Android圖像的變化再通過Socket實(shí)時(shí)傳輸給Server端記住坐標(biāo)系變化不要忘記了,一開始我忘記了轉(zhuǎn)化坐標(biāo)結(jié)果顯示就不對(duì)。

當(dāng)然PC端也可以讀取Android Client端的H264編碼視頻流薪者,然后PC端使用FFMPEG這個(gè)庫去解碼取试,關(guān)于FFMPEG庫的相關(guān)使用瞬浓,我推薦大家去看看雷霄驊的技術(shù)博客磅叛,此人在音視頻方面給予大家很大的幫助杖爽。

Web應(yīng)用程序:
首先通過在node.js上通過socket獲取Android Client端的H264視頻流,然后通過WebSocket實(shí)時(shí)將字節(jié)數(shù)組傳輸給WebRtc精置,通過WebRtc的video標(biāo)簽去顯示脂倦,題外話:WebRtc也是個(gè)好東西,你可以基于它去做很多有意思的東西比如網(wǎng)絡(luò)視屏以及現(xiàn)在挺熱的Android直播火欧,程序員去多折騰折騰還是很有意思的企锌。之后通過js獲取鼠標(biāo)點(diǎn)擊的坐標(biāo)事件,之后的操作和PC很相似了萍鲸,都是得到命令然后執(zhí)行捌肴,然后AndroidClient再投屏圖像状知,如此循環(huán)盲再。

這大概就是屏幕投影的原理了棠笑。并不復(fù)雜洪规。關(guān)鍵你要有一顆折騰的心。最近準(zhǔn)備把Web端的這塊實(shí)現(xiàn)完了就來寫一篇雙開的原理實(shí)現(xiàn)。歡迎其他程序員一起入坑一起交流,不管你是學(xué)習(xí)Android的還是后端的還是前端開發(fā)的,都?xì)g迎大家一起交流原理思想翻具,一起學(xué)習(xí)工禾,一起進(jìn)步。
還有本人寫博客并不多癣丧,所以語法表述之類的還尚待提高厢钧,而且今天寫的時(shí)候燒還沒退頭一直很懵霞扬,還請(qǐng)見諒,歡迎大家提出其他的實(shí)現(xiàn)想法以及意見。
也喜歡你可以加入QQ群大家一起交流交流:94839608

這是我一開始寫的最基本的Android屏幕投影以及反向控制代碼,里面很多代碼都是硬編碼進(jìn)去的,可能需要你們手動(dòng)改一些IP或者通過Socket去傳輸屏幕寬高之類的,畢竟只是基本測(cè)試使用的。這是鏈接
http://download.csdn.net/detail/zhangkai1992/9809903
最近換了工作方向,我還是很喜歡Android的,不過不是我最喜歡的,不過我還是有空會(huì)去研究研究Android的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門儒拂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蒜哀,“玉大人,你說我怎么就攤上這事。” “怎么了阔加?”我有些...
    開封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我逾条,道長(zhǎng),這世上最難降的妖魔是什么糕篇? 我笑而不...
    開封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任墩崩,我火速辦了婚禮,結(jié)果婚禮上奏纪,老公的妹妹穿的比我還像新娘。我一直安慰自己钟些,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著欲主,像睡著了一般单雾。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天辽幌,我揣著相機(jī)與錄音端辱,去河邊找鬼个盆。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的适揉。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼降铸!你這毒婦竟也來了推掸?” 一聲冷哼從身側(cè)響起谅畅,我...
    開封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤丹墨,失蹤者是張志新(化名)和其女友劉穎喉前,沒想到半個(gè)月后哎垦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡盾鳞,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年犬性,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片腾仅。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡乒裆,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出推励,到底是詐尸還是另有隱情鹤耍,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布验辞,位于F島的核電站稿黄,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏受神。R本人自食惡果不足惜抛猖,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一格侯、第九天 我趴在偏房一處隱蔽的房頂上張望鼻听。 院中可真熱鬧,春花似錦联四、人聲如沸撑碴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽醉拓。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間亿卤,已是汗流浹背愤兵。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留排吴,地道東北人秆乳。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像钻哩,于是被迫代替她去往敵國(guó)和親屹堰。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容