Android投屏到PC初探

此文记录将Android屏幕投影到PC上的实现,大多实现参考网上框架实现。站在巨人的肩膀上,才能看的更远!

原理

1、Android上,主要用到了MediaCodec和DisplayManage类,前面一个类在API16上加上去,后者在API19上加上去的。调用系统的MediaProjectionManager类,开始录屏服务。(参照启动Android系统照相) 生成的virtualDiaplay可以贴到SurfaceView中展现。但这里,我们将它传输到PC上显示。所以用到MediaCodec将视频编码成H264,在手机端开启Server端,通过Socket将流传输到PC。

2、PC上,展现利用的Java媒体编解码框架Xuggle,对socket接收到的流进行解码播放。

重要的代码解释

Android端

 Intent intent = mediaProjectionManager.createScreenCaptureIntent();
startActivityForResult(intent, CAPATURE_REQUEST_CODE);

启动录屏服务,此时手机会弹框,要求用户点击确认。安全考虑,避免第三方侵犯用户隐私。

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  super.onActivityResult(requestCode, resultCode, data);
  if (resultCode == RESULT_OK) {
      switch (requestCode) {
          case CAPATURE_REQUEST_CODE:
              projection = mediaProjectionManager.getMediaProjection(resultCode, data);

              projection.registerCallback(mediaCallback,null);
                startService(new Intent(MainActivity.this,MyService.class));

              break;
      }
  }
}  

此时回调会返回MeidaProjection,后面的Service我们要调用它的createVirtualDisplay来创建前面所说的VirtualDisplay。 同时我用开启一个服务去开始执行编码视频和传输流操作。

这里都是初始化编码器的操作。

将编码器的surface传入MediaProjection。当然,这里也可以传surfaceView,让录屏在手机上显示。

之后MediaCodec编码生成的视频Frame数据会全部存到encodedData中,操作encodedData数据就行。这里我们将它转换成字节流通过Socket传输到PC。

PC端

利用AndroidDebugBridge监听手机连接状态,连接成功后执行如下操作:

将socket流交给Xuggler框架处理即可。

注意:

1、需要先将手机APP启动,点击按钮开启录屏。

2、手机连接成功后,还需要command执行“adb forward tcp:60001 tcp:60000” 将PC的60001端口数据转发到手机的60000端口。

3、之后再在PC端启动jar包即可。

4、稍等一会,你会看到手机的屏幕在电脑上

遗留问题

视频会有延迟,有时不流畅的问题。(猜测由于java解码框架的原因,如果换成web形式展现,估计会好很多)