共享屏幕问题

qq123456 13小时前 52

设备:华为 mate60,Android 12,屏幕分辨率 1260x2720

现象:调用 callSession.startScreenShare(Intent data) 后,HardwareVideoEncoder.initEncodeInternal 抛出 IllegalArgumentException,MediaCodec.configure 失败。

原因分析:设备分辨率 1260 不是 16 的倍数(1260/16=78.75),H264 编码器要求宽高对齐 16。ScreenCapturerAndroid 直接用了设备原始分辨率,没有做对齐处理。

日志:

E HardwareVideoEncoder: initEncodeInternal failed E HardwareVideoEncoder: java.lang.IllegalArgumentException at android.media.MediaCodec.native_configure(Native Method) at org.webrtc.HardwareVideoEncoder.initEncodeInternal(HardwareVideoEncoder.java:287) 请问:

ScreenCapturerAndroid 能否在 startCapture 时自动将分辨率对齐到 16 的倍数? 或者有没有接口可以设置屏幕共享的采集分辨率?

最新回复 (3)
  • wfclaw 12小时前
    引用 2
    你好,这个问题确实是 **H264 硬件编码器的限制** 导致的。

    **原因说明**

    大多数 Android 设备的 H264 硬件编码器(MediaCodec)要求输入分辨率宽和高必须是 **16 的倍数**。你的华为 Mate60 屏幕分辨率 1260×2720 中,1260 ÷ 16 = 78.75,不是整数,所以 `MediaCodec.configure` 直接抛异常。

    WebRTC 的 `ScreenCapturerAndroid` 默认使用设备原始分辨率采集屏幕,没有做对齐处理,因此遇到这种非 16 倍数宽度的屏幕就会报错。

    **目前的解决思路**

    野火 IM 的屏幕共享能力封装在 `AVEngineKit`(WebRTC 层)中,`ScreenCapturerAndroid` 的分辨率控制属于**底层 native/WebRTC 层实现**,SDK 层目前没有开放直接设置采集分辨率的接口。

    如果需要解决这个问题,通常需要在 WebRTC 源码层修改 `ScreenCapturerAndroid` 的采集逻辑,在 `startCapture` 时将分辨率对齐到 16 的倍数(例如把 1260 向下对齐到 1248 或向上对齐到 1280)。

    **建议**

    1. 这个问题涉及底层 WebRTC/native 修改,建议微信联系 **wfchat** 反馈,看官方是否能提供修复版本。
    2. 如果你们的团队能自行编译 WebRTC 层,可以在 `ScreenCapturerAndroid.startCapture` 中加入分辨率对齐逻辑。

    这是一个合理的兼容性需求,华为 Mate60 这类高分屏幕确实容易出现这个问题。
  • x86 12小时前
    引用 3
    你用我们发布的demo测试下,是否正常
  • wfclaw 48分钟前
    引用 4
    这个问题是 H.264 硬件编码器对分辨率有 16 像素对齐要求导致的。

    **问题原因:**

    华为 Mate60 的屏幕分辨率是 1260x2720,其中宽度 1260 不是 16 的倍数(1260/16 = 78.75)。H.264 MediaCodec 编码器在配置时要求宽高必须是 16 的整数倍,否则会抛出 IllegalArgumentException。

    **解决方向:**

    1. **修改屏幕采集分辨率**
       在启动屏幕共享前,将采集分辨率调整为 16 的倍数。例如:
       - 宽度调整为 1264(16×79)或 1248(16×78)
       - 保持宽高比进行等比缩放

    2. **WebRTC 层处理**
       如果你们用的是 WebRTC 的视频采集模块,可以在 `ScreenCapturerAndroid` 或 `HardwareVideoEncoder` 层增加分辨率对齐处理:
       ```java
       int alignedWidth = ((width + 15) / 16) * 16;
       int alignedHeight = ((height + 15) / 16) * 16;
       ```

    3. **野火源码修改建议**
       如果是野火 SDK 内部的屏幕共享实现,建议检查 `AVEngineKit` 中的屏幕共享启动逻辑,看是否有分辨率裁剪或缩放选项。

    4. **设备兼容性**
       这是部分华为/荣耀设备的共性问题,因为它们的屏幕宽度往往不是 16 的倍数(如 1220、1260 等)。

    **临时规避方案:**

    如果无法修改底层编码器,可以尝试:
    - 使用软件编码(虽然性能较差,但兼容性更好)
    - 先裁剪画面到 16 对齐的分辨率再送入编码器

    建议优先尝试在采集层面对齐分辨率,这是最标准的做法。
返回