最近做了一個專案,裡面有涉及到監控PC桌面和監視手機螢幕的功能,客戶需要在PC電腦上和安卓手機上都能夠觀看對方的螢幕,而對方的裝置既可以是PC電腦,也可以是安卓手機。
為了便於以後複習,我把這個螢幕監控的功能單獨提出來做了個Demo名為ScreenMonitor來記錄備忘,順便也分享給大家。
該Demo一個包括3個專案:服務端、PC客戶端、安卓客戶端。
文末除了將ScreenMonitor整個專案的原始碼提供下載,也專門給出了可以直接部署的版本,供大家直接部署測試。
接下來,我將給大家介紹整個功能的實現原理和程式碼邏輯,大家可以從文末下載原始碼後,對照原始碼再來看下面的介紹就會更清晰些。
一.服務端實現
服務端主要用來轉發資料(被監控的螢幕影像的編碼資料),並不涉及其它複雜的業務邏輯。
這個實現起來很簡單,只需要幾句程式碼就OK,它主要做的就是將客戶端的訊息的處理與資料的轉發。這裡不做過多的介紹,其關鍵核心程式碼只有一句,就是建立OMCS多媒體伺服器例項。
Program.MultimediaServer = MultimediaServerFactory.CreateMultimediaServer(9900, userVerifier, config, bool.Parse(ConfigurationManager.AppSettings["SecurityLogEnabled"]));
第一個引數是提供服務的TCP埠,第二個引數用於驗證登入的使用者帳號密碼。服務端執行介面如下所示:
二.PC客戶端實現
客戶端中我們也分為了2種身份:控制端、被控端
我們在登入時,我們需要初始化多媒體管理器 來連線服務端進行通訊,其實也很簡單,我們也只需要呼叫一句話就OK。
multimediaManager.Initialize(loginForm.CurrentUserID, "", ConfigurationManager.AppSettings["ServerIP"], int.Parse(ConfigurationManager.AppSettings["ServerPort"]));
1.PC控制端:主要包括遠端觀看對方的桌面、監聽對方的麥克風 2個功能
實現中主要是用到了DesktopConnector這個自定義控制元件,我們也只需簡單的呼叫一個BeginConnect 方法就可以直接連線到對方桌面。將控制元件還提供了2個事件 ConnectEnded、Disconnected 來知道當前連線的結果和狀態
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端遠端觀看手機螢幕的截圖:
2.PC被控端:顯示正在被哪些使用者觀看
三.安卓端實現
安卓客戶端就與PC客戶端的實現原理差不多了,只是其中一些細節不一樣而已
安卓端同樣也是分為2種身份:監控端、被控端
同PC客戶端一樣我們也要初始化多媒體管理器 來連線服務端進行通訊
LogonResponse omcsResp = MultimediaManagerFactory.GetSingleton().initialize(id, password, ipaddStr, 9900, getApplication());//登入OMCS伺服器
1.安卓控制端:功能同PC一樣,可觀看目標使用者的螢幕和監聽麥克風
這裡我們用到了一個自定義元件 DesktopSurfaceView 用來顯示對方桌面的影像 ,我們通過桌面聯結器 DesktopConnector 去連線對方的桌面將獲取的桌面影像資料用於該元件來顯示
//顯示對方資料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(); // 例項化訊息物件 msg.what = 1; // 訊息標識 msg.obj = "遠端桌面連線失敗:" + connectResult.toString(); // 訊息內容存放 myHandler.sendMessage(msg); } } @Override public void disconnected(ConnectorDisconnectedType connectorDisconnectedType) { if(connectorDisconnectedType==ConnectorDisconnectedType.OwnerActiveDisconnect||connectorDisconnectedType==ConnectorDisconnectedType.GuestActiveDisconnect) { return; } Message msg = Message.obtain(); // 例項化訊息物件 msg.what = 2; // 訊息標識 msg.obj = "遠端桌面連線斷開:" + connectorDisconnectedType.toString();// 訊息內容存放 myHandler.sendMessage(msg); } }); desktopConnector.beginConnect(targetUid);
下圖為手機監控PC桌面
2.安卓被控端:需要採集本手機的桌面影像、麥克風聲音傳送給控制方
核心點在採集本手機的整個桌面的影像,這一點在OMCS框架中已經為我們處理好了,我們只是需要設定一下相關許可權來允許錄製螢幕即可,剩下的事情都可以交給omcs內部去處理了。
MultimediaManagerFactory.GetSingleton().setDesktopRecordActivity(this);//this 為當前Activity @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); MultimediaManagerFactory.GetSingleton().setDesktopRecordActivityResult(requestCode, resultCode, data);//設定授權結果給多媒體管理器 }
當控制方請求觀看安卓的桌面時,被控端會彈出如下許可權申請提示,點選“立即開始”對方就可以開始採集螢幕並將資料傳送給 控制方用於顯示。(若勾選了始終允許分享螢幕 的選項,之後控制端請求訪問該被控端時就不會再次彈出許可權的對話方塊了,可直接看得到該螢幕)
四、ScreenMonitor 原始碼下載
1. 專案原始碼下載 網盤下載 (提取碼: 1234)
2. 可直接部署版本下載 網盤下載 (提取碼: 1234)
另外:GGTalk V7.0 已於2020.09.30釋出,全新的 服務端+PC端+Android端 原始碼,快來下載吧!