HarmonyOS鸿蒙Next官方屏幕采集demo:AVScreenCaptureScreenRecord克隆下来真机中运行无法成功录屏

HarmonyOS鸿蒙Next官方屏幕采集demo:AVScreenCaptureScreenRecord克隆下来真机中运行无法成功录屏 官方demo地址:https://gitee.com/harmonyos_samples/avscreen-capture-screen-record

图片

我在原代码MyAVScreenCapture/startRecording方法中添加了异常的打印:

this.screenCapture?.on('error', (err) => {
  hilog.info(0xFF00, CommonConstants.LOG_TAG, 'Handle exception cases. %{public}d,  %{public}s,  %{public}s, %{public}s',
    err.code, err.name, err.message, err.stack);
})

点击进入基于ArkTS方法录屏到文件 页面后进行了录屏操作。

点击录屏图标后的日志打印:

InputKeyFlow                 I     [][OnPointerEvent:215] ac: down: 14735
InputKeyFlow                 I     [P:D:14735][OnPointerEvent:544] id:14735 recv
InputKeyFlow                 I     [] OnInputEvent(86): eid:26,InputId:14735,wid:211,ac:2
AceInputTracking             I     [(-1:100000:singleton)] pointdown windowId: 211
InputKeyFlow                 I     [] ConsumePointerEventInner(876): InputId:14735,wid:211,pointId:0,srcType:2,rect:[0,0,2800,1840],notify:1
InputKeyFlow                 I     [][OnPointerEvent:215] ac: move: 14736
InputKeyFlow                 I     [(100000:100000:scope)] InputTracking id:14735, fingerId:0, type=0, inject=0, isPrivacyMode=0
InputKeyFlow                 I     [(100000:100000:scope)] InputTracking id:14735, touch test hitted node info: fingerId: 0{ tag: page, depth: 6 };{ tag: Button, depth: 13 };
InputKeyFlow                 I     [(100000:100000:scope)] InputTracking id:14735, touch test hitted recognizer type info: recognizer type ClickRecognizer node info: { tag: Button };
InputKeyFlow                 I     [(100000:100000:scope)] Id:14735, click 0 down, ETF: 0, CTP: 0, state: 0
AceInputTracking             I     [(100000:100000:scope)] Consumed new event id=14735 in ace_container, lastEventInfo: id:14733
InputKeyFlow                 I     [][OnPointerEvent:215] ac: move, first: 14737-(2025-11-20 18:05:02.003ms), count: 1, last: ac: up: 14738
InputKeyFlow                 I     [P:U:14738][OnPointerEvent:544] id:14738 recv
InputKeyFlow                 I     [] OnInputEvent(86): eid:27,InputId:14738,wid:211,ac:4
InputKeyFlow                 I     [] ConsumePointerEventInner(876): InputId:14738,wid:211,pointId:0,srcType:2,rect:[0,0,2800,1840],notify:1
InputKeyFlow                 I     [(100000:100000:scope)] InputTracking id:14738, fingerId:0, type=1, inject=0, isPrivacyMode=0
InputKeyFlow                 I     [(100000:100000:scope)] Id:14738, click 0 up, state: 0
AceGesture                   I     [(100000:100000:scope)] Click try accept
InputKeyFlow                 I     [(100000:100000:scope)] Click accepted, tag: Button
AVScreenCaptureNapi          I     #172 JsCreateAVScreenRecorder success
InputKeyFlow                 I     [(100000:100000:scope)] id: 0, log: {types: Click, node: Button, prcd: Down, state: READY, prcd: Up, state: SUCCEED}
AceInputTracking             I     [(100000:100000:scope)] Consumed new event id=14738 in ace_container, lastEventInfo: id:14737
AVScreenCaptureNapi          I     #40 0x819A20Instances create
HiTraceC                     I     [a92ab4e7ce03446 0 0]HiTraceBegin name:AVScreenCapture flags:0x00.
TaskQueue                    I     [a92ab4e7ce03446 0 0]#45 0x6A02C0 Instance thread started [OS_AVScreenCaptureNapi], curTimeUs: [31492687889065]
AVScreenCaptureCallback      I     [a92ab4e7ce03446 0 0]#28 0x6D7CC8Instances create
AVScreenCaptureNapi          I     [a92ab4e7ce03446 0 0]#117 Constructor success
MY_TAG                       I     ScreenCapture has been created successfully.
AVScreenCaptureNapi          I     #463 JsSetEventCallback Start
AVScreenCaptureNapi          I     #586 argCount:2
AVScreenCaptureCallback      I     #73 Set callback type: stateChange
AVScreenCaptureNapi          I     #494 JsSetEventCallback set callback stateChange End
AVScreenCaptureNapi          I     #463 JsSetEventCallback Start
AVScreenCaptureNapi          I     #586 argCount:2
AVScreenCaptureCallback      I     #73 Set callback type: error
AVScreenCaptureNapi          I     #494 JsSetEventCallback set callback error End
MY_TAG                       I     startRecording captureConfig:
    2800
    1840
    76
    10000000
    48000
    2
    96000
    0

AVScreenCaptureNapi          I     #277 Js Init Start
AVScreenCaptureNapi          I     #586 argCount:1
AVScreenCaptureNapi          I     #976 get audioSampleRate : 48000!
AVScreenCaptureNapi          I     #660 input audioSampleRate 48000
AVScreenCaptureNapi          I     #976 get audioChannelCount : 2!
AVScreenCaptureNapi          I     #670 input audioChannelCount 2
AVScreenCaptureNapi          I     #976 get audioBitrate : 96000!
AVScreenCaptureNapi          I     #679 input audioBitrate 96000
AVScreenCaptureNapi          I     #976 get displayId : 0!
AVScreenCaptureNapi          I     #701 input displayId 0
AVScreenCaptureNapi          I     #976 get videoBitrate : 10000000!
AVScreenCaptureNapi          I     #707 input videoBitrate 10000000
TaskQueue                    I     #153 Enter TaskProcessor [OS_AVScreenCaptureNapi], tid_: (13029)
AVScreenCaptureNapi          I     #956 can not find preset property
AVScreenCaptureNapi          I     #713 input videoCodec 2
AVScreenCaptureNapi          I     #976 get frameWidth : 2800!
AVScreenCaptureNapi          I     #976 get frameHeight : 1840!
AVScreenCaptureNapi          I     #720 input frameWidth 2800, frameHeight 1840
AVScreenCaptureNapi          I     #779 check video frame get displayInfo width:2800,height:1840,density:400
AVScreenCaptureNapi          I     #726 input formatted frameWidth 2800, frameHeight 1840
AVScreenCaptureNapi          I     #956 can not find fillMode property
AVScreenCaptureNapi          I     #826 AVScreenCaptureNapi::GetScreenCaptureFillMode in!
AVScreenCaptureNapi          I     #837 AVScreenCaptureNapi::GetScreenCaptureFillMode succeed, screenCaptureFillMode: 0
AVScreenCaptureNapi          I     #732 input screenCaptureFillMode 0
AVScreenCaptureNapi          I     #748 input url fd://76
AVScreenCaptureNapi          I     #317 Js Init End
AVScreenCaptureNapi          I     #534 Init Start
ScreenCaptureImpl            I     #275 ScreenCaptureImpl: 0x725E38InitCaptureFile start, url:<private>, videoEncInfo.audioBitrate:96000, videoEncInfo.audioCodecformat:3, innerCapInfo.audioSampleRate:48000, innerCapInfo.audioChannels::2, micCapInfo.audioSampleRate:48000, micCapInfo.audioChannels:2, videoCapInfo.displayId:0, videoCapInfo.taskIDs.size:0, videoCapInfo.videoSource:2.
AVScreenCaptureNapi          I     #542 Init End
AVScreenCaptureNapi          I     #312 The js thread of init finishes execution and returns
AVScreenCaptureNapi          I     #905 Js StartRecording Start
AVScreenCaptureNapi          I     #586 argCount:0
AVScreenCaptureNapi          I     #945 Js StartRecording End
AVScreenCaptureNapi          I     #887 StartRecording Start
ScreenCaptureImpl            I     #121 ScreenCaptureImpl:0x725E38 isPrivacyAuthorityEnabled:1
AVScreenCaptureNapi          I     #898 StartRecording End
AVScreenCaptureNapi          I     #940 The js thread of StartRecording finishes execution and returns
WMSFocus                     I     [] UpdateFocus(1073): Report update focus: 0, id: 211
Ace                          I     [(-1:100000:singleton)] [com.example.avscreencapturescreenrecord][entry][100000]: window unfocus
UIAbility                    E     [ui_ability_impl.cpp:414]null applicationContext or lifecycleCallback
Ace                          I     [(100000:100000:scope)] Update application state , state: ON_INACTIVE
AceFocus                     I     [(100000:100000:scope)] Window id: 211 lost focus.
WMSFocus                     I     [] NotifyHighlightChange(1654): windowId: 211, isHighlight: 0,
OHOS::RS                     I     RSUIDirector::ProcessMessages messageId:44, cmdCount:2, instanceId:100000
OHOS::RS                     I     RSUIDirector::PostTask messageId:44, cmdCount:2, instanceId:100000
thp_extra                    I     ThpExtraRunCommand[122]ver:5.0.8ThpExtraRunCommand, cmd:THP_UpdateViewsLocation, param:thp#Location#2383,117,2483,217#40,117,140,217
thp_extra                    I     InitTpInterfaces[33]InitTpInterfaces+
thp_extra                    E     InitTpInterfaces[35]inited +

允许录屏权限后的日志打印(开始录屏):

WMSFocus                     I     [] UpdateFocus(1073): Report update focus: 1, id: 211
UIAbility                    E     [ui_ability_impl.cpp:414]null applicationContext or lifecycleCallback
Ace                          I     [(-1:100000:singleton)] [com.example.avscreencapturescreenrecord][entry][100000]: window focus
Ace                          I     [(100000:100000:scope)] Update application state , state: ON_ACTIVE
accessibility_asacfwk        I     [(SubscribeStateObserver:463)]Observer has subscribed!
AceAccessibility             I     [(100000:100000:scope)]  the result of SubscribeStateObserver:4001
AceFocus                     I     [(100000:100000:scope)] Window id: 211 get focus.
AceFocus                     I     [(100000:100000:scope)] Request focus on current focus view: NavDestination/139
WMSFocus                     I     [] NotifyHighlightChange(1654): windowId: 211, isHighlight: 1,
AceFocus                     I     [(100000:100000:scope)] WinFocusMove end, NavDestination/secure_field onBlur, NavDestination/secure_field onFocus, start: 1, end: 1, update: 2
AceKeyboard                  I     [(100000:100000:scope)] current focus node info : (NavDestination/139).
AceKeyboard                  I     [(100000:100000:scope)] Normal Window focus first, set focus flag to window.
AceKeyboard                  I     [(100000:100000:scope)] Trigger Window Focus Callback
AceKeyboard                  I     [(100000:100000:scope)] need keyboard : 0.
WMSKeyboard                  I     [] operator()(3035): isNeedKeyboard: 0, keepKeyboardFlag: 0
WMSKeyboard                  I     [] RequestInputMethodCloseKeyboard(3003): Notify InputMethod framework close keyboard start.
WMSKeyboard                  I     [] RequestInputMethodCloseKeyboard(3006): Notify InputMethod framework close keyboard end.
OHOS::RS                     E     FlushImplicitTransaction return, [renderServiceClient_:1, transactionData empty:1]
AVScreenCaptureCallback      I     #95 OnError is called, name: 0, error message: 6
AVScreenCaptureCallback      I     #144 uv_queue_work_with_qos start, errorcode:6 , errormessage:Screen capture failed.:
MY_TAG                       I     Handle exception cases. 6,  BusinessError,  Screen capture failed., Cannot get SourceMap info, dump raw stack:
    ================Backtrace================
    #00 pc 0000000000742000 /system/lib64/platformsdk/libark_jsruntime.so
    #01 pc 0000000000742514 /system/lib64/platformsdk/libark_jsruntime.so
    #02 pc 0000000000334540 /system/lib64/platformsdk/libark_jsruntime.so
    #03 pc 00000000001b9498 /system/lib64/platformsdk/libark_jsruntime.so
    #04 pc 00000000001b8e24 /system/lib64/platformsdk/libark_jsruntime.so
    #05 pc 000000000024fd28 /system/lib64/platformsdk/libark_jsruntime.so
    #06 pc 00000000006156a0 /system/lib64/platformsdk/libark_jsruntime.so
    #07 pc 00000000005df11c /system/lib64/platformsdk/libark_jsruntime.so
    #08 pc 0000000000057220 /system/lib64/platformsdk/libace_napi.z.so
    #09 pc 00000000000c7898 /system/lib64/module/multimedia/libmedia.z.so
ffrt                         W     215:~WorkerThread:72 to exit, qos[2]
ffrt                         W     216:~WorkerThread:72 to exit, qos[2]
ffrt                         W     217:~WorkerThread:72 to exit, qos[3]
ffrt                         W     218:~WorkerThread:72 to exit, qos[2]
ffrt                         W     219:~WorkerThread:72 to exit, qos[3]

点击录屏图标结束后的日志:

InputKeyFlow                 I     [][OnPointerEvent:215] ac: down: 14746
InputKeyFlow                 I     [P:D:14746][OnPointerEvent:544] id:14746 recv
InputKeyFlow                 I     [] OnInputEvent(86): eid:28,InputId:14746,wid:211,ac:2
AceInputTracking             I     [(-1:100000:singleton)] pointdown windowId: 211
InputKeyFlow                 I     [(100000:100000:scope)] InputTracking id:14746, fingerId:0, type=0, inject=0, isPrivacyMode=0
InputKeyFlow                 I     [] ConsumePointerEventInner(876): InputId:14746,wid:211,pointId:0,srcType:2,rect:[0,0,2800,1840],notify:1
InputKeyFlow                 I     [][OnPointerEvent:215] ac: move: 14747
TunnelClient                 I     in Connect, enter
TunnelClient                 I     in Connect, leave
TunnelClient                 I     in Connect, enter
TunnelClient                 I     in Connect, leave
InputKeyFlow                 I     [(100000:100000:scope)] InputTracking id:14746, touch test hitted node info: fingerId: 0{ tag: page, depth: 6 };{ tag: Button, depth: 13 };{ tag: Image, depth: 15 };
InputKeyFlow                 I     [(100000:100000:scope)] InputTracking id:14746, touch test hitted recognizer type info: recognizer type ClickRecognizer node info: { tag: Button };recognizer type LongPressRecognizer node info: { tag: Image }; { tag: Image };recognizer type PanRecognizer node info: { tag: Image };
InputKeyFlow                 I     [(100000:100000:scope)] Id:14746, exclusive 0 type: 0
InputKeyFlow                 I     [(100000:100000:scope)] Id:14746, parallel 0 type: 0
InputKeyFlow                 I     [(100000:100000:scope)] Id:14746, sequenced 0 type: 0
InputKeyFlow                 I     [(100000:100000:scope)] Id:14746, LongPress 0 down, state: 0
InputKeyFlow                 I     [(100000:100000:scope)] Id:14746, LongPress 0 down, state: 0
InputKeyFlow                 I     [(100000:100000:scope)] Id:14746, click 0 down, ETF: 0, CTP: 0, state: 0
AceInputTracking             I     [(100000:100000:scope)] Consumed

更多关于HarmonyOS鸿蒙Next官方屏幕采集demo:AVScreenCaptureScreenRecord克隆下来真机中运行无法成功录屏的实战教程也可以访问 https://www.itying.com/category-93-b0.html

4 回复

从你给的日志关键信息可锁定问题本质:

权限已授予:日志显示 isPrivacyAuthorityEnabled:1,说明录屏隐私权限通过校验;

初始化成功:JsCreateAVScreenRecorder success 和 Constructor success 证明录屏实例创建正常;

失败触发点:在 StartRecording 执行后触发 OnError,错误码 6 无明确官方文档定义,但结合场景可判定为 录屏配置不兼容设备 或 API 版本适配问题(设备 API 为 5.0.5 (17),属于鸿蒙 5.0 系列)。

解决:

日志中录屏配置参数存在超设备能力的风险,需按以下标准修改(鸿蒙 5.0 设备对分辨率、码率有严格限制):

问题配置(日志提取):

  • 分辨率:2800×1840(设备屏幕原生分辨率,录屏编码可能不支持)
  • 视频码率:10000000 bps(10Mbps,过高导致编码失败)
  • 音频码率:96000 bps(部分设备仅支持 64kbps)
// 修改录屏配置 CaptureConfig,适配鸿蒙5.0设备
const captureConfig: AVScreenCaptureConfig = {
  displayId: 0, // 保持默认
  frameWidth: 1920, // 降低分辨率(设备支持的主流编码分辨率)
  frameHeight: 1080, // 1080P 兼容所有鸿蒙5.0+设备
  videoBitrate: 5000000, // 视频码率降至5Mbps(平衡画质与兼容性)
  videoCodec: VideoCodec.H264, // 明确指定 H264 编码(避免默认编码不兼容)
  audioSampleRate: 48000, // 保持不变(设备支持)
  audioChannelCount: 2, // 保持不变
  audioBitrate: 64000, // 音频码率降至64kbps(鸿蒙5.0设备推荐值)
  url: "fd://76" // 保持原文件描述符
};

更多关于HarmonyOS鸿蒙Next官方屏幕采集demo:AVScreenCaptureScreenRecord克隆下来真机中运行无法成功录屏的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


系统架构设计

概述

本文档描述了系统的整体架构设计,包括组件交互、数据流和部署结构。

核心组件

前端服务

  • 用户界面层
  • API网关
  • 负载均衡器

后端服务

  • 业务逻辑处理
  • 数据访问层
  • 缓存服务

数据存储

  • 关系型数据库
  • NoSQL数据库
  • 文件存储系统

架构特点

  1. 微服务架构
  2. 水平可扩展
  3. 高可用性设计
  4. 安全防护机制

部署方案

  • 容器化部署
  • 自动化运维
  • 监控告警系统

技术栈

  • 前端:React, Vue.js
  • 后端:Java, Spring Boot
  • 数据库:MySQL, Redis
  • 中间件:Kafka, RabbitMQ

鸿蒙Next的AVScreenCaptureScreenRecord功能需要用户手动授权屏幕录制权限。请在"设置-应用-权限管理"中为您的应用开启"屏幕录制"权限。若权限已开启但仍无法录屏,请检查设备系统版本是否支持AVScreenCapture接口,部分鸿蒙Next Beta版本可能存在兼容性问题。录屏功能还需确保应用已配置正确的权限声明,并在manifest文件中声明ohos.permission.CAPTURE_SCREEN权限。

根据日志分析,录屏失败的主要原因是错误码6:“Screen capture failed”。这个错误通常与屏幕采集的底层权限或配置相关。

从日志可以看到:

  1. AVScreenCapture初始化成功
  2. 权限检查通过(isPrivacyAuthorityEnabled:1)
  3. 开始录制后立即触发了错误回调

问题可能出现在以下几个方面:

分辨率配置问题: 当前配置的分辨率2800x1840可能超出了设备支持的范围。建议尝试使用标准分辨率如1920x1080或1280x720。

文件路径权限: 虽然您提到文件写入正常,但录屏需要特定的文件描述符权限。确保使用应用沙箱内的有效路径。

API版本兼容性: API 5.0.5(17)可能存在已知的屏幕采集问题。建议检查是否有更新的API版本可用。

建议修改: 在captureConfig中降低分辨率和码率:

  • 将2800x1840改为1920x1080
  • 视频码率从10000000降低到5000000
  • 音频码率从96000降低到64000

同时确认设备系统版本与HarmonyOS Next SDK的兼容性,某些设备可能需要特定的系统更新才能正常使用屏幕采集功能。

回到顶部