You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

公共虚拟显示器通过scrcpy访问显示黑屏问题求助

普通应用Public虚拟显示器被scrcpy捕获黑屏的解决办法

问题场景

基于官方ScreenCapture示例修改代码,给虚拟显示器加上DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC以便scrcpy访问,代码如下:

mVirtualDisplay = mMediaProjection.createVirtualDisplay("ScreenCapture",
                mSurfaceView.getWidth(), mSurfaceView.getHeight(), mScreenDensity,
                DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC,
                mSurface, null, null);

本地SurfaceView预览正常,但scrcpy连接该显示器时完全黑屏,同时scrcpy输出警告:

WARN: Display doesn't have FLAG_SUPPORTS_PROTECTED_BUFFERS flag, mirroring can be restricted

已知普通应用无法创建带FLAG_SUPPORTS_PROTECTED_BUFFERS的安全虚拟显示器,该权限仅系统应用持有。

可行解决方案

方案1:用MediaCodec中转帧数据

不要直接把同一个Surface同时给本地预览和虚拟显示器,而是通过MediaCodec做帧转发,同时支持本地预览和scrcpy的网络传输:

  • 初始化H.264编码的MediaCodec,配置对应分辨率和帧率参数。
  • 将MediaCodec生成的InputSurface作为虚拟显示器的输出Surface。
  • 启动MediaCodec的异步处理流程,从输出缓冲区中取出编码后的H.264帧。
  • 一方面把解码后的帧渲染到本地SurfaceView做预览,另一方面把编码帧通过Socket发送到电脑端,用scrcpy或自定义工具接收播放。

这种方式绕开了虚拟显示器的安全权限限制,不需要依赖Public虚拟显示器的系统捕获能力。

方案2:直接让scrcpy捕获主屏幕(放弃本地预览)

如果不需要本地预览功能,直接使用scrcpy默认的屏幕捕获方式即可,无需自己创建虚拟显示器。如果必须通过应用触发捕获,可以在应用申请到MediaProjection权限后,通过ADB命令将权限传递给scrcpy(需要修改scrcpy源码或使用自定义启动脚本)。

问题根源

普通应用创建的虚拟显示器缺少FLAG_SUPPORTS_PROTECTED_BUFFERS标志,系统会限制敏感内容输出;同时scrcpy作为外部工具,无法正确读取非安全虚拟显示器的帧缓冲区数据,即使加上VIRTUAL_DISPLAY_FLAG_PUBLIC也只能让系统识别该显示器,无法突破权限限制。

内容的提问来源于stack exchange,提问作者Kidades

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 16:25:55