C#如何實(shí)現(xiàn)監(jiān)控手機(jī)屏幕(附源碼下載)
最近做了一個(gè)項(xiàng)目,里面有涉及到監(jiān)控PC桌面和監(jiān)視手機(jī)屏幕的功能,客戶需要在PC電腦上和安卓手機(jī)上都能夠觀看對(duì)方的屏幕,而對(duì)方的設(shè)備既可以是PC電腦,也可以是安卓手機(jī)。
為了便于以后復(fù)習(xí),我把這個(gè)屏幕監(jiān)控的功能單獨(dú)提出來做了個(gè)Demo名為ScreenMonitor來記錄備忘,順便也分享給大家。
該Demo一個(gè)包括3個(gè)項(xiàng)目:服務(wù)端、PC客戶端、安卓客戶端。
文末除了將ScreenMonitor整個(gè)項(xiàng)目的源碼提供下載,也專門給出了可以直接部署的版本,供大家直接部署測(cè)試。
接下來,我將給大家介紹整個(gè)功能的實(shí)現(xiàn)原理和代碼邏輯,大家可以從文末下載源碼后,對(duì)照源碼再來看下面的介紹就會(huì)更清晰些。
一.服務(wù)端實(shí)現(xiàn)
服務(wù)端主要用來轉(zhuǎn)發(fā)數(shù)據(jù)(被監(jiān)控的屏幕圖像的編碼數(shù)據(jù)),并不涉及其它復(fù)雜的業(yè)務(wù)邏輯。
這個(gè)實(shí)現(xiàn)起來很簡(jiǎn)單,只需要幾句代碼就OK,它主要做的就是將客戶端的消息的處理與數(shù)據(jù)的轉(zhuǎn)發(fā)。這里不做過多的介紹,其關(guān)鍵核心代碼只有一句,就是創(chuàng)建OMCS多媒體服務(wù)器實(shí)例。
第一個(gè)參數(shù)是提供服務(wù)的TCP端口,第二個(gè)參數(shù)用于驗(yàn)證登錄的用戶帳號(hào)密碼。服務(wù)端運(yùn)行界面如下所示:
二.PC客戶端實(shí)現(xiàn)
客戶端中我們也分為了2種身份:控制端、被控端
我們?cè)诘卿洉r(shí),我們需要初始化多媒體管理器 來連接服務(wù)端進(jìn)行通信,其實(shí)也很簡(jiǎn)單,我們也只需要調(diào)用一句話就OK。
1.PC控制端:主要包括遠(yuǎn)程觀看對(duì)方的桌面、監(jiān)聽對(duì)方的麥克風(fēng) 2個(gè)功能
實(shí)現(xiàn)中主要是用到了DesktopConnector這個(gè)自定義控件,我們也只需簡(jiǎn)單的調(diào)用一個(gè)BeginConnect 方法就可以直接連接到對(duì)方桌面。將控件還提供了2個(gè)事件 ConnectEnded、Disconnected 來知道當(dāng)前連接的結(jié)果和狀態(tài)
public DesktopForm(string friendID,bool audioEnabled) { InitializeComponent(); this.ownerID = friendID; this.Text = string.Format("正在訪問{0}的桌面", this.ownerID); this.desktopConnector1.ConnectEnded += new CbGeneric<ConnectResult>(desktopConnector1_ConnectEnded); this.desktopConnector1.Disconnected += DesktopConnector1_Disconnected; this.desktopConnector1.BeginConnect(this.ownerID); if (audioEnabled) { this.microphoneConnector1.BeginConnect(this.ownerID); } } private void DesktopConnector1_Disconnected(ConnectorDisconnectedType type) { if (this.InvokeRequired) { this.BeginInvoke(new CbGeneric<ConnectorDisconnectedType>(this.DesktopConnector1_Disconnected), type); } else { if (type == ConnectorDisconnectedType.OwnerActiveDisconnect || type == ConnectorDisconnectedType.GuestActiveDisconnect) { return; } MessageBox.Show("斷開連接!原因:" + type); this.Close(); } } void desktopConnector1_ConnectEnded(ConnectResult result) { if (this.InvokeRequired) { this.BeginInvoke(new CbGeneric<ConnectResult>(this.desktopConnector1_ConnectEnded), result); } else { if (result != ConnectResult.Succeed) { MessageBox.Show("連接失敗!" + result.ToString()); } } }
以下為在PC端遠(yuǎn)程觀看手機(jī)屏幕的截圖:
2.PC被控端:顯示正在被哪些用戶觀看
三.安卓端實(shí)現(xiàn)
安卓客戶端就與PC客戶端的實(shí)現(xiàn)原理差不多了,只是其中一些細(xì)節(jié)不一樣而已
安卓端同樣也是分為2種身份:監(jiān)控端、被控端
同PC客戶端一樣我們也要初始化多媒體管理器 來連接服務(wù)端進(jìn)行通信
這里我們用到了一個(gè)自定義組件DesktopSurfaceView 用來顯示對(duì)方桌面的圖像 ,我們通過桌面連接器DesktopConnector 去連接對(duì)方的桌面將獲取的桌面圖像數(shù)據(jù)用于該組件來顯示
//顯示對(duì)方數(shù)據(jù)view DesktopSurfaceView otherView = (DesktopSurfaceView) findViewById(R.id.Desk_surface_remote); desktopConnector.setOtherVideoPlayerSurfaceView(otherView); desktopConnector.setConnectorEventListener(new IConnectorEventListener() { @Override public void connectEnded(ConnectResult connectResult) { if( connectResult!= ConnectResult.Succeed){ Message msg = Message.obtain(); // 實(shí)例化消息對(duì)象 msg.what = 1; // 消息標(biāo)識(shí) msg.obj = "遠(yuǎn)程桌面連接失?。? + connectResult.toString(); // 消息內(nèi)容存放 myHandler.sendMessage(msg); } } @Override public void disconnected(ConnectorDisconnectedType connectorDisconnectedType) { if(connectorDisconnectedType==ConnectorDisconnectedType.OwnerActiveDisconnect||connectorDisconnectedType==ConnectorDisconnectedType.GuestActiveDisconnect) { return; } Message msg = Message.obtain(); // 實(shí)例化消息對(duì)象 msg.what = 2; // 消息標(biāo)識(shí) msg.obj = "遠(yuǎn)程桌面連接斷開:" + connectorDisconnectedType.toString();// 消息內(nèi)容存放 myHandler.sendMessage(msg); } }); desktopConnector.beginConnect(targetUid);
下圖為手機(jī)監(jiān)控PC桌面
2.安卓被控端:需要采集本手機(jī)的桌面圖像、麥克風(fēng)聲音發(fā)送給控制方
核心點(diǎn)在采集本手機(jī)的整個(gè)桌面的圖像,這一點(diǎn)在OMCS框架中已經(jīng)為我們處理好了,我們只是需要設(shè)置一下相關(guān)權(quán)限來允許錄制屏幕即可,剩下的事情都可以交給omcs內(nèi)部去處理了。
MultimediaManagerFactory.GetSingleton().setDesktopRecordActivity(this);//this 為當(dāng)前Activity @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); MultimediaManagerFactory.GetSingleton().setDesktopRecordActivityResult(requestCode, resultCode, data);//設(shè)置授權(quán)結(jié)果給多媒體管理器 }
當(dāng)控制方請(qǐng)求觀看安卓的桌面時(shí),被控端會(huì)彈出如下權(quán)限申請(qǐng)?zhí)崾?,點(diǎn)擊“立即開始”對(duì)方就可以開始采集屏幕并將數(shù)據(jù)發(fā)送給 控制方用于顯示。(若勾選了始終允許分享屏幕 的選項(xiàng),之后控制端請(qǐng)求訪問該被控端時(shí)就不會(huì)再次彈出權(quán)限的對(duì)話框了,可直接看得到該屏幕)
四、ScreenMonitor 源碼下載
1. 項(xiàng)目源碼下載 網(wǎng)盤下載(提取碼:w3mi)
2. 可直接部署版本下載 網(wǎng)盤下載(提取碼:w493)
到此這篇關(guān)于C#如何實(shí)現(xiàn)監(jiān)控手機(jī)屏幕(附源碼下載)的文章就介紹到這了,更多相關(guān)C# 監(jiān)控手機(jī)屏幕內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 關(guān)于.NET/C#/WCF/WPF 打造IP網(wǎng)絡(luò)智能視頻監(jiān)控系統(tǒng)的介紹
- C# FileSystemWatcher 在監(jiān)控文件夾和文件時(shí)的使用方法
- C# 監(jiān)控 Windows 文件夾的方法
- C#使用FileSystemWatcher控件實(shí)現(xiàn)的文件監(jiān)控功能示例
- C#利用性能計(jì)數(shù)器監(jiān)控網(wǎng)絡(luò)狀態(tài)
- C#獲取串口列表實(shí)現(xiàn)實(shí)時(shí)監(jiān)控串口
- C#實(shí)現(xiàn)讀取注冊(cè)表監(jiān)控當(dāng)前操作系統(tǒng)已安裝軟件變化的方法
- C#進(jìn)程監(jiān)控方法實(shí)例分析
- C#實(shí)現(xiàn)軟件監(jiān)控外部程序運(yùn)行狀態(tài)的方法
- c#使用filesystemwatcher實(shí)時(shí)監(jiān)控文件目錄的添加和刪除
- C# 實(shí)現(xiàn)視頻監(jiān)控系統(tǒng)(附源碼)
相關(guān)文章
C#中圖片旋轉(zhuǎn)和翻轉(zhuǎn)(RotateFlipType)用法分析
這篇文章主要介紹了C#中圖片旋轉(zhuǎn)和翻轉(zhuǎn)(RotateFlipType)用法,實(shí)例分析了C#圖片旋轉(zhuǎn)及翻轉(zhuǎn)Image.RotateFlip方法屬性的常用設(shè)置技巧,需要的朋友可以參考下2015-06-06C#用表達(dá)式樹構(gòu)建動(dòng)態(tài)查詢的方法
這篇文章主要介紹了C#用表達(dá)式樹構(gòu)建動(dòng)態(tài)查詢的方法,幫助大家更好的理解和學(xué)習(xí)c#,感興趣的朋友可以了解下2020-12-12深入DropDownList用法的一些學(xué)習(xí)總結(jié)分析
本篇文章是對(duì)DropDownList的用法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06