1# 使用AVScreenCapture录屏写文件(C/C++) 2 3屏幕录制主要为主屏幕录屏功能。 4 5开发者可以调用录屏([AVScreenCapture](media-kit-intro.md#avscreencapture))模块的C API接口,完成屏幕录制,采集设备内、麦克风等的音视频源数据。可以调用录屏模块获取音视频文件,然后通过文件的形式流转到其他模块进行播放或处理,达成文件形式分享屏幕内容的场景。 6 7录屏模块和窗口(Window)、图形(Graphic)等模块协同完成整个视频采集的流程。 8 9使用AVScreenCapture录制屏幕涉及到AVScreenCapture实例的创建、音视频采集参数的配置、采集的开始与停止、资源的释放等。 10 11开始屏幕录制时正在通话中或者屏幕录制过程中来电,录屏将自动停止。因通话中断的录屏会上报OH_SCREEN_CAPTURE_STATE_STOPPED_BY_CALL状态。 12 13屏幕录制过程中发生系统用户切换事件时,录屏将自动停止。因系统用户切换中断的录屏会上报OH_SCREEN_CAPTURE_STATE_STOPPED_BY_USER_SWITCHES状态。 14 15本开发指导将以完成一次屏幕数据录制的过程为例,向开发者讲解如何使用AVScreenCapture进行屏幕录制,详细的API声明请参考[AVScreenCapture API参考](../../reference/apis-media-kit/_a_v_screen_capture.md)。 16 17如果配置了采集麦克风音频数据,需对应配置麦克风权限ohos.permission.MICROPHONE和申请长时任务,配置方式请参见[向用户申请权限](../../security/AccessToken/request-user-authorization.md)、[申请长时任务](../../task-management/continuous-task.md)。 18 19## 开发步骤及注意事项 20 21使用AVScreenCapture时要明确其状态的变化,在创建实例后,调用对应的方法可以进入指定的状态实现对应的行为。 22在确定的状态下执行不合适的方法会导致AVScreenCapture发生错误,开发者需要在调用状态转换的方法前进行状态检查,避免程序运行异常。 23 24**在 CMake 脚本中链接动态库** 25 26```c++ 27target_link_libraries(entry PUBLIC libnative_avscreen_capture.so) 28``` 29 301. 添加头文件。 31 32 ```c++ 33 #include "napi/native_api.h" 34 #include <multimedia/player_framework/native_avscreen_capture.h> 35 #include <multimedia/player_framework/native_avscreen_capture_base.h> 36 #include <multimedia/player_framework/native_avscreen_capture_errors.h> 37 #include <fcntl.h> 38 #include "string" 39 #include "unistd.h" 40 ``` 41 422. 创建AVScreenCapture实例capture。 43 44 ```c++ 45 OH_AVScreenCapture* capture = OH_AVScreenCapture_Create(); 46 ``` 47 483. 配置屏幕录制参数。 49 50 创建AVScreenCapture实例capture后,可以设置屏幕录制所需要的参数。 51 52 其中,录屏存文件时默认录制内录,麦克风可以动态开关,可以同时内外录制。 53 54 同时,录屏存文件需要设置状态回调,感知录制状态。 55 56 ```c++ 57 //录屏时获取麦克风或者内录,内录参数必填,如果都设置了,内录和麦克风的参数设置需要一致 58 OH_AudioCaptureInfo micCapInfo = { 59 .audioSampleRate = 48000, 60 .audioChannels = 2, 61 .audioSource = OH_MIC 62 }; 63 64 OH_AudioCaptureInfo innerCapInfo = { 65 .audioSampleRate = 48000, 66 .audioChannels = 2, 67 .audioSource = OH_ALL_PLAYBACK 68 }; 69 70 OH_AudioEncInfo audioEncInfo = { 71 .audioBitrate = 48000, 72 .audioCodecformat = OH_AAC_LC 73 }; 74 75 OH_VideoCaptureInfo videoCapInfo = { 76 .videoFrameWidth = 768, 77 .videoFrameHeight = 1280, 78 .videoSource = OH_VIDEO_SOURCE_SURFACE_RGBA 79 }; 80 81 OH_VideoEncInfo videoEncInfo = { 82 .videoCodec = OH_H264, 83 .videoBitrate = 2000000, 84 .videoFrameRate = 30 85 }; 86 87 OH_AudioInfo audioInfo = { 88 .innerCapInfo = innerCapInfo, 89 .audioEncInfo = audioEncInfo 90 }; 91 92 OH_VideoInfo videoInfo = { 93 .videoCapInfo = videoCapInfo, 94 .videoEncInfo = videoEncInfo 95 }; 96 97 config = { 98 .captureMode = OH_CAPTURE_HOME_SCREEN, 99 .dataType = OH_CAPTURE_FILE, 100 .audioInfo = audioInfo, 101 .videoInfo = videoInfo, 102 }; 103 104 OH_AVScreenCapture_Init(capture, config); 105 ``` 106 1074. 调用StartScreenRecording()方法开始进行屏幕录制。 108 109 ```c++ 110 OH_AVScreenCapture_StartScreenRecording(capture); 111 ``` 112 1135. 调用StopScreenRecording()方法停止录制。 114 115 ```c++ 116 OH_AVScreenCapture_StopScreenRecording(capture); 117 ``` 118 1196. 调用Release()方法销毁实例,释放资源。 120 121 ```c++ 122 OH_AVScreenCapture_Release(capture); 123 ``` 124 125## 完整示例 126 127下面展示了使用AVScreenCapture屏幕录制存文件的完整示例代码。 128 129```c++ 130 131#include "napi/native_api.h" 132#include <multimedia/player_framework/native_avscreen_capture.h> 133#include <multimedia/player_framework/native_avscreen_capture_base.h> 134#include <multimedia/player_framework/native_avscreen_capture_errors.h> 135#include <fcntl.h> 136#include "string" 137#include "unistd.h" 138 139void OnStateChange(struct OH_AVScreenCapture *capture, OH_AVScreenCaptureStateCode stateCode, void *userData) { 140 (void)capture; 141 142 if (stateCode == OH_SCREEN_CAPTURE_STATE_STARTED) { 143 // 处理状态变更 144 } 145 if (stateCode == OH_SCREEN_CAPTURE_STATE_STOPPED_BY_CALL || 146 stateCode == OH_SCREEN_CAPTURE_STATE_STOPPED_BY_USER_SWITCHES) { 147 // 录屏中断状态处理 148 } 149 if (stateCode == OH_SCREEN_CAPTURE_STATE_INTERRUPTED_BY_OTHER) { 150 // 处理状态变更 151 } 152 (void)userData; 153} 154 155static napi_value Screencapture(napi_env env, napi_callback_info info) { 156 OH_AVScreenCaptureConfig config; 157 OH_AudioCaptureInfo micCapInfo = { 158 .audioSampleRate = 48000, 159 .audioChannels = 2, 160 .audioSource = OH_MIC 161 }; 162 163 OH_AudioCaptureInfo innerCapInfo = { 164 .audioSampleRate = 48000, 165 .audioChannels = 2, 166 .audioSource = OH_ALL_PLAYBACK 167 }; 168 169 OH_AudioEncInfo audioEncInfo = { 170 .audioBitrate = 48000, 171 .audioCodecformat = OH_AudioCodecFormat::OH_AAC_LC 172 }; 173 174 OH_VideoCaptureInfo videoCapInfo = { 175 .videoFrameWidth = 768, 176 .videoFrameHeight = 1280, 177 .videoSource = OH_VIDEO_SOURCE_SURFACE_RGBA 178 }; 179 180 OH_VideoEncInfo videoEncInfo = { 181 .videoCodec = OH_VideoCodecFormat::OH_H264, 182 .videoBitrate = 2000000, 183 .videoFrameRate = 30 184 }; 185 186 OH_AudioInfo audioInfo = { 187 .micCapInfo = micCapInfo, 188 .innerCapInfo = innerCapInfo, 189 .audioEncInfo = audioEncInfo 190 }; 191 192 OH_VideoInfo videoInfo = { 193 .videoCapInfo = videoCapInfo, 194 .videoEncInfo = videoEncInfo 195 }; 196 197 config = { 198 .captureMode = OH_CAPTURE_HOME_SCREEN, 199 .dataType = OH_CAPTURE_FILE, 200 .audioInfo = audioInfo, 201 .videoInfo = videoInfo, 202 }; 203 204 struct OH_AVScreenCapture *capture = OH_AVScreenCapture_Create(); 205 206 // 初始化录屏参数,传入配置信息OH_AVScreenRecorderConfig 207 OH_RecorderInfo recorderInfo; 208 const std::string SCREEN_CAPTURE_ROOT = "/data/storage/el2/base/files/"; 209 int32_t outputFd = open((SCREEN_CAPTURE_ROOT + "screen01.mp4").c_str(), O_RDWR | O_CREAT, 0777); 210 std::string fileUrl = "fd://" + std::to_string(outputFd); 211 recorderInfo.url = const_cast<char *>(fileUrl.c_str()); 212 recorderInfo.fileFormat = OH_ContainerFormatType::CFT_MPEG_4; 213 config.recorderInfo = recorderInfo; 214 215 //设置状态回调 216 OH_AVScreenCapture_SetStateCallback(capture, OnStateChange, nullptr); 217 218 // 进行初始化操作 219 int32_t retInit = OH_AVScreenCapture_Init(capture, config); 220 221 // 开始录屏 222 int32_t retStart = OH_AVScreenCapture_StartScreenRecording(capture); 223 224 // 录制10s 225 sleep(10); 226 227 // 结束录屏 228 int32_t retStop = OH_AVScreenCapture_StopScreenRecording(capture); 229 230 // 释放ScreenCapture 231 int32_t retRelease = OH_AVScreenCapture_Release(capture); 232 233 // 返回调用结果,示例仅返回随意值 234 napi_value sum; 235 napi_create_double(env, 5, &sum); 236 237 return sum; 238} 239 240EXTERN_C_START 241static napi_value Init(napi_env env, napi_value exports) { 242 napi_property_descriptor desc[] = { 243 {"screencapture", nullptr, Screencapture, nullptr, nullptr, nullptr, napi_default, nullptr}}; 244 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); 245 return exports; 246} 247EXTERN_C_END 248 249static napi_module demoModule = { 250 .nm_version = 1, 251 .nm_flags = 0, 252 .nm_filename = nullptr, 253 .nm_register_func = Init, 254 .nm_modname = "entry", 255 .nm_priv = ((void *)0), 256 .reserved = {0}, 257}; 258 259extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&demoModule); } 260``` 261