最近作了一个项目,里面有涉及到监控PC桌面和监视手机屏幕的功能,客户须要在PC电脑上和安卓手机上都可以观看对方的屏幕,而对方的设备既能够是PC电脑,也能够是安卓手机。服务器
为了便于之后复习,我把这个屏幕监控的功能单独提出来作了个Demo名为ScreenMonitor来记录备忘,顺便也分享给你们。框架
该Demo一个包括3个项目:服务端、PC客户端、安卓客户端。ide
文末除了将ScreenMonitor整个项目的源码提供下载,也专门给出了能够直接部署的版本,供你们直接部署测试。测试
接下来,我将给你们介绍整个功能的实现原理和代码逻辑,你们能够从文末下载源码后,对照源码再来看下面的介绍就会更清晰些。 ui
一.服务端实现
服务端主要用来转发数据(被监控的屏幕图像的编码数据),并不涉及其它复杂的业务逻辑。this
这个实现起来很简单,只须要几句代码就OK,它主要作的就是将客户端的消息的处理与数据的转发。这里不作过多的介绍,其关键核心代码只有一句,就是建立OMCS多媒体服务器实例。 编码
Program.MultimediaServer = MultimediaServerFactory.CreateMultimediaServer(9900, userVerifier, config, bool.Parse(ConfigurationManager.AppSettings["SecurityLogEnabled"]));
第一个参数是提供服务的TCP端口,第二个参数用于验证登陆的用户账号密码。服务端运行界面以下所示:spa
二.PC客户端实现
客户端中咱们也分为了2种身份:控制端、被控端3d
咱们在登陆时,咱们须要初始化多媒体管理器 来链接服务端进行通讯,其实也很简单,咱们也只须要调用一句话就OK。 orm
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 去链接对方的桌面将获取的桌面图像数据用于该组件来显示 郑州哪里割包皮好http://www.zztongji120.com/
//显示对方数据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桌面
郑州作包皮手术多少钱http://www.zztjxb.com/
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);//设置受权结果给多媒体管理器 }
当控制方请求观看安卓的桌面时,被控端会弹出以下权限申请提示,点击“当即开始”对方就能够开始采集屏幕并将数据发送给 控制方用于显示。(若勾选了始终容许分享屏幕 的选项,以后控制端请求访问该被控端时就不会再次弹出权限的对话框了,可直接看获得该屏幕)