Android屏幕直播方案

项目需求是实时同步Android手机屏幕画面至浏览器。这里有两个挑战,一是Android如何在应用内获得屏幕实时视频流,另一个是如何在浏览器上做视频直播。经过一番折腾,确定了如下的实现方案。期间,我们也实现了手机摄像头的直播。

演示效果:

演示演示

Android获取实时屏幕画面

原理与基础设置

Android 5.0版本之后,支持使用MediaProjection的方式获取屏幕视频流。具体的使用方法和原理如下图所示:

MediaProjection原理MediaProjection原理

参考ScreenRecorder项目3的实现,我们了解到VirtualDisplay可以获取当前屏幕的视频流,创建VirtualDisplay只需通过MediaProjectionManager获取MediaProjection,然后通过MediaProjection创建VirtualDisplay即可。

那么视频数据的流向是怎样的呢?

  • 首先,Display 会将画面投影到 VirtualDisplay中;
  • 接着,VirtualDisplay 会将图像渲染到 Surface中,而这个Surface是由MediaCodec所创建的;
  • 最后,用户可以通过MediaCodec获取特定编码的视频流数据。

经过我们的尝试发现,在这个场景下,MediaCodec只允许使用video/avc编码类型,也就是RAW H.264的视频编码,使用其他的编码会出现应用Crash的现象(不知是否与硬件有关?)。由于这个视频编码,后面我们与它“搏斗”了好一段时间。

以下是关键部分的代码(来自ScreenRecorder项目3):

codec = MediaCodec.createEncoderByType(MIME_TYPE);
mSurface = codec.createInputSurface();
mVirtualDisplay = mMediaProjection.createVirtualDisplay(
        name,
        mWidth,
        mHeight,
        mDpi,
        DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC,
        mSurface,    // 图像会渲染到Surface中
        null,
        null);

在编码之前,我们还需要设置视频编码的一些格式信息,这里我们通过MediaFormat进行编码格式设置,代码如下(来自ScreenRecorder项目3)。

private static final String MIME_TYPE = "video/avc"; // H.264编码
private static final int FRAME_RATE = 30;            // 30 FPS
private static final int IFRAME_INTERVAL = 10;       // I-frames间隔时间
private static final int TIMEOUT_US = 10000;

private void prepareEncoder() throws IOException {
    
    MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE, mWidth, mHeight);
    format
  • 6
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值