HarmonyOS鸿蒙Next中使用AVScreenCapture录屏横竖屏切换之后平板编码输出错误❌️

HarmonyOS鸿蒙Next中使用AVScreenCapture录屏横竖屏切换之后平板编码输出错误❌️ 因为要处理横竖屏切换不重新销毁AVScreenCapture和OH_VideoEncoder,所以设置编码参数宽高如下:

OH_AVFormat *format = OH_AVFormat_Create();
// 宽高都设置为1920这样可以兼容录屏横竖屏切换宽高分辨率倒置问题
OH_AVFormat_SetIntValue(format, OH_MD_KEY_WIDTH, 1920);
OH_AVFormat_SetIntValue(format, OH_MD_KEY_HEIGHT, 1920);
OH_AVFormat_SetIntValue(format, OH_MD_KEY_PIXEL_FORMAT, sampleInfo.pixelFormat);
int ret = OH_VideoEncoder_Configure(encoder_, format);
OH_AVFormat_Destroy(format);

参考的这个提问 在手机上都正常编码输出数据,但是在平板如:Matepad 11.5s灵动款 编码输出数据大小一直是34的错误帧,

修改为本身对应的宽高之后正常,这是怎么回事?


更多关于HarmonyOS鸿蒙Next中使用AVScreenCapture录屏横竖屏切换之后平板编码输出错误❌️的实战教程也可以访问 https://www.itying.com/category-93-b0.html

8 回复

开发者您好,其他设备(手机)默认使用硬编码器,而该设备(Matepad 11.5s灵动款平板)不支持硬编码,使用了软编码,而软编码如果实际大小与配置大小不符合需要reset后重新配置参数,具体流程为:调用OH_VideoEncoder_Reset重置编码器后,重新使用OH_VideoEncoder_Configure配置新的参数。具体可以参考:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/video-encoding#surface%E6%A8%A1%E5%BC%8F

更多关于HarmonyOS鸿蒙Next中使用AVScreenCapture录屏横竖屏切换之后平板编码输出错误❌️的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


使用官方的录屏码流c++教程demo就可以复现https://gitee.com/harmonyos_samples/avscreen-capture-screen-record,

修改demo里面的VideoEncoder.cpp

OH_AVFormat_SetIntValue(format, OH_MD_KEY_WIDTH, sampleInfo.videoWidth);
OH_AVFormat_SetIntValue(format, OH_MD_KEY_HEIGHT, sampleInfo.videoHeight);

改为:

int32_t max = std::max(sampleInfo.videoWidth, sampleInfo.videoHeight);
OH_AVFormat_SetIntValue(format, OH_MD_KEY_WIDTH, max);
OH_AVFormat_SetIntValue(format, OH_MD_KEY_HEIGHT, max);

使用 录屏转码流就可以复现这个bug,

这是有问题那台日志:
cke_351.png
cke_579.png

报错信息是什么,

并没有看到什么报错信息,我测试其他另外三台其他型号平板都是正常的,

在HarmonyOS Next中,使用AVScreenCapture进行录屏时,横竖屏切换可能导致编码输出错误。此问题通常与屏幕方向变化时,编码器未正确适配新的分辨率或宽高比有关。建议检查并重新配置AVScreenCapture的编码参数,确保在方向变化时更新输出设置。

这是一个典型的编码器配置与设备屏幕物理特性不匹配导致的问题。

核心原因分析:

您将编码器的宽高都固定设置为1920,意图是创建一个“正方形”的编码画布来兼容横竖屏切换。这个策略在手机上可能有效,是因为手机屏幕的宽高比相对接近(例如20:9),1920x1920的方形区域足以覆盖屏幕内容,编码器内部处理时可能进行了适配或裁剪。

然而,在平板设备上(如MatePad 11.5s),屏幕宽高比通常更“扁长”(例如MatePad 11.5s屏幕分辨率为2200x1440,宽高比约15:10)。当您强制设置一个正方形的编码目标(1920x1920)时:

  1. 源与目标不匹配AVScreenCapture捕获的是设备的物理屏幕帧缓冲区,其分辨率是固定的(例如2200x1440)。编码器被配置为输出1920x1920。
  2. 缩放与处理异常:编码器(或底层驱动)需要将捕获的长方形屏幕图像,适配到您指定的正方形编码区域。这个缩放/适配过程在您描述的平板上可能触发了特定的处理路径或限制,导致编码输出异常(持续输出大小为34的错误帧,这通常代表编码失败或空数据包)。
  3. 设备差异:不同设备(手机 vs. 平板)的图形栈、硬件编码器实现或驱动对非常规分辨率配置的容忍度和处理逻辑可能存在差异,这解释了为何手机正常而平板出错。

解决方案与正确实践:

您后续修改为“本身对应的宽高”后正常,这验证了上述分析。正确的做法不是固定一个正方形,而是动态地根据当前屏幕捕获的宽高来配置编码器

在横竖屏切换时,AVScreenCapture捕获的帧的宽高会自动对调(例如从2200x1440变为1440x2200)。您的编码器配置应同步更新:

  1. 获取当前捕获帧的尺寸:在收到AVScreenCaptureOnFrame回调时,从OH_AVMemory *或关联的OH_AVFormat *中获取当前帧的实际宽度和高度。
  2. 动态重配置编码器:当检测到屏幕方向切换(可通过OH_AVFormat中的尺寸变化或监听系统方向事件感知),使用新的实际宽高重新调用OH_VideoEncoder_Configure。虽然您希望不销毁编码器,但Configure方法可以在编码器运行时被再次调用以更新参数。
  3. 确保宽高值正确:确保传递给OH_VideoEncoder_ConfigureOH_MD_KEY_WIDTHOH_MD_KEY_HEIGHT与当前AVScreenCapture输出帧的宽高严格一致。无需也不应设置为固定值或正方形。

总结: 问题的根源在于编码器分辨率配置与视频源(屏幕捕获)的物理分辨率不匹配,这在宽高比差异大的平板设备上引发了兼容性问题。解决方案是使编码器配置动态跟随屏幕捕获的实际输出分辨率变化,而非采用一个固定的兼容值。

回到顶部