Skip to main content
HarmonyOS 的屏幕采集是同进程的 —— 不需要像 iOS 那样单独做一个扩展进程, 也就没有那 50MB 内存上限的约束。

最小流程

停止:

权限与授权窗

module.json5 里声明:
startCapture() 返回只代表采集已发起,不代表已经出帧。系统会弹窗让用户确认,用户点同意之后才真正出帧。UI 上不要在 await 返回后就 立刻显示”正在共享”,应该等到第一帧到达(渲染器回调)或用 onTrackBindRtcTrack 判断。
重启采集会再弹一次授权窗。鸿蒙的 AVScreenCapture 每次 getDisplayMedia / createVideoSource(isScreencast) 都要用户确认,拿不到”沿用上次授权”这种待遇。所以不要为了改参数而随手 restartCapture() —— 用户会看到弹窗反复出现。

三种采集模式

ScreenCaptureMode 决定采什么:
specifiedScreen / specifiedWindowtargetId 必须有值。这两个模式下 SDK 才会把对应的底层约束挂上去。如果模式选了但 targetIdundefined,底层约束解析会失败,抛出来的是一个既没有 message 也没有 code 的裸 Error —— 上层只看到”共享屏幕失败: “,而且系统的屏幕采集服务根本没被调到。这个报错很容易被误判成缺 ohos.permission.CAPTURE_SCREEN(实测补上权限也没用)。 遇到空错误信息时先回头检查 targetId

采集系统音频

传第二个预设参数即可,系统音频会作为独立的一条音频轨道产生:
ScreenAudioCaptureOptions 有个关键字段:
系统音频是独立轨道,所以可以单独控制 —— 比如”共享画面但不共享声音”就只发布视频轨。麦克风与系统音频也是两条独立轨道,鸿蒙上每条音频轨有自己的 AudioSource, 不存在 iOS 那种”必须先混成一路”的限制。

编码策略:屏幕与摄像头相反

屏幕内容变化慢、细节多(文字、表格),所以 SDK 内部对屏幕轨道启用 isScreencast=true,让编码器切到保清晰度优先的策略 —— 宁可掉帧也不糊字。 这与摄像头正相反(摄像头保帧率、宁可降分辨率)。默认帧率也不同: 如果共享的是视频播放画面,可以自己把 frameRate 提上去,但要相应提高 maxBitrate,否则会更糊。

横竖屏

SDK 内部开了 ohosScreenCaptureAutoRotation,旋转屏幕时采集会自动跟随 —— 否则横竖屏切换后对端画面是躺着的。这一点不需要业务侧处理。

排查清单

排障时先看日志里那条 请求屏幕采集 WxH@fps mode=... 系统声音=... —— 有这条说明参数已经组好、走到了系统调用;没有这条说明更早就失败了。

相关阅读