1# Using AVScreenCapture to Capture Screens and Obtain Streams (C/C++) 2 3Screen capture is mainly used to record the main screen. 4 5You can call the C APIs of the [AVScreenCapture](media-kit-intro.md#avscreencapture) module to record the screen and collect audio and video source data output by the device and microphone. When developing a live streaming or an office application, you can call the APIs to obtain original audio and video streams and transfer the streams to other modules for processing. In this way, the home screen can be shared during live streaming. 6 7The AVScreenCapture, Window, and Graphics modules together implement the entire video capture process. 8 9By default, the main screen is captured, and the Graphics module generates the screen capture frame data based on the main screen and places the data to the display data buffer. The player framework obtains the data from the buffer for processing. 10 11The full screen capture process involves creating an AVScreenCapture instance, configuring audio and video capture parameters, starting and stopping screen capture, and releasing resources. 12 13If you are in a call when screen capture starts or a call is coming during screen capture, screen capture automatically stops, and the **OH_SCREEN_CAPTURE_STATE_STOPPED_BY_CALL** status is reported. 14 15Screen capture automatically stops upon system user switching, and **OH_SCREEN_CAPTURE_STATE_STOPPED_BY_USER_SWITCHES** is reported. 16 17This topic describes how to use the AVScreenCapture APIs to carry out one-time screen capture. For details about the API reference, see [AVScreenCapture](../../reference/apis-media-kit/_a_v_screen_capture.md). 18 19If microphone data collection is configured, configure the permission ohos.permission.MICROPHONE and request a continuous task. For details, see [Requesting User Authorization](../../security/AccessToken/request-user-authorization.md) and [Continuous Task](../../task-management/continuous-task.md). 20 21## How to Develop 22 23After an AVScreenCapture instance is created, different APIs can be called to switch the AVScreenCapture to different states and trigger the required behavior. 24 25If an API is called when the AVScreenCapture is not in the given state, the system may throw an exception or generate other undefined behavior. Therefore, you are advised to check the AVScreenCapture state before triggering state transition. 26 27**Linking the Dynamic Library in the CMake Script** 28 29```c++ 30target_link_libraries(entry PUBLIC libnative_avscreen_capture.so libnative_buffer.so libnative_media_core.so) 31``` 32 331. Add the header files. 34 35 ```c++ 36 #include "napi/native_api.h" 37 #include <multimedia/player_framework/native_avscreen_capture.h> 38 #include <multimedia/player_framework/native_avscreen_capture_base.h> 39 #include <multimedia/player_framework/native_avscreen_capture_errors.h> 40 #include <native_buffer/native_buffer.h> 41 #include <fcntl.h> 42 #include "string" 43 #include "unistd.h" 44 ``` 45 462. Check whether there is a running screen capture service instance. If yes, wait until the instance is stopped and the resources are released. 47 483. Create an AVScreenCapture instance, named **capture** in this example. 49 50 ```c++ 51 OH_AVScreenCapture* capture = OH_AVScreenCapture_Create(); 52 ``` 53 544. Set screen capture parameters. 55 56 After the **capture** instance is created, you can set the parameters required for screen capture. For details about how to set the audio and video parameters, see [Detailed Description](#detailed-description). 57 58 ```c++ 59 OH_AVScreenCaptureConfig config; 60 61 OH_AudioInfo audioinfo = { 62 .micCapInfo = miccapinfo, 63 .innerCapInfo = innerCapInfo, 64 .audioEncInfo = audioEncInfo 65 }; 66 67 OH_VideoInfo videoinfo = { 68 .videoCapInfo = videocapinfo, 69 .videoEncInfo = videoEncInfo 70 }; 71 72 OH_AVScreenCaptureConfig config = { 73 .captureMode = OH_CAPTURE_HOME_SCREEN, 74 .dataType = OH_ORIGINAL_STREAM, 75 .audioInfo = audioinfo, 76 .videoInfo = videoinfo 77 }; 78 79 OH_AVScreenCapture_Init(capture, config); 80 ``` 81 825. (Optional) Enable the microphone. 83 84 ```c++ 85 bool isMic = true; 86 OH_AVScreenCapture_SetMicrophoneEnabled(capture, isMic); 87 ``` 88 896. Set callback functions, which are used to listen for errors that may occur during screen capture and the generation of audio and video stream data. See [Detailed Description](#detailed-description) for more information. 90 91 ```c++ 92 OH_AVScreenCapture_SetErrorCallback(capture, OnError, userData); 93 OH_AVScreenCapture_SetStateCallback(capture, OnStateChange, userData); 94 OH_AVScreenCapture_SetDataCallback(capture, OnBufferAvailable, userData); 95 ``` 96 977. Call **StartScreenCapture()** to start screen capture. 98 99 ```c++ 100 bool IsCaptureStreamRunning = true; 101 OH_AVScreenCapture_StartScreenCapture(capture); 102 ``` 103 104 Alternatively, call **StartScreenCaptureWithSurface()** to start screen capture in surface mode. 105 106 ```c++ 107 OH_AVScreenCapture_StartScreenCaptureWithSurface(capture, window); 108 ``` 109 1108. Call **StopScreenCapture()** to stop screen capture. See [Detailed Description](#detailed-description) for more information. 111 112 ```c++ 113 OH_AVScreenCapture_StopScreenCapture(capture); 114 ``` 115 1169. Call **Release()** to release the instance. 117 118 ```c++ 119 OH_AVScreenCapture_Release(capture); 120 ``` 121 122## Specifications for Selecting the Window to Capture on 2-in-1 Devices 123For 2-in-1 devices, a selection page is offered to users for capturing a specific window. To maintain compatibility with the existing interface design, when third-party applications set the screen capture mode to **OH_CAPTURE_SPECIFIED_SCREEN** or **OH_CAPTURE_SPECIFIED_WINDOW**, a picker dialog appears with the designated window ID pre-selected. The content that gets captured ultimately depends on the user's choice within the picker. 124 125It is recommended that the selection page be used in **OH_CAPTURE_SPECIFIED_WINDOW** mode. You need to configure the screen capture height and width based on the 2-in-1 device's resolution and pass the display ID (and a window ID if you want to capture a specific window). 126 127```c++ 128// Configure the screen capture width and height in config_ based on the 2-in-1 device's resolution. 129config_.videoInfo.videoCapInfo.videoFrameWidth = 2880; 130config_.videoInfo.videoCapInfo.videoFrameHeight = 1920; 131 132// Set the screen capture mode to OH_CAPTURE_SPECIFIED_WINDOW and pass a display ID. 133config_.captureMode = OH_CAPTURE_SPECIFIED_WINDOW; 134config_.videoInfo.videoCapInfo.displayId = 0; 135 136// (Optional) Pass a window ID if you want to capture a specific window. 137vector<int32_t> missionIds = {61}; // Window 61 is pre-selected in the picker. 138config_.videoInfo.videoCapInfo.missionIDs = &missionIds[0]; 139config_.videoInfo.videoCapInfo.missionIDsLen = static_cast<int32_t>(missionIds.size()); 140``` 141 142The selection page is also compatible with the following screen capture modes: 143 1441. OH_CAPTURE_SPECIFIED_WINDOW mode, with multiple window IDs passed. 145 146 The 2-in-1 device does not display a picker dialog box. Instead, it displays a privacy dialog box to ask for user approval. Multiple windows can be captured at the same time. 147 148 ```c++ 149 // Configure the screen capture width and height in config_ based on the 2-in-1 device's resolution. 150 config_.videoInfo.videoCapInfo.videoFrameWidth = 2880; 151 config_.videoInfo.videoCapInfo.videoFrameHeight = 1920; 152 153 // Set the screen capture mode to OH_CAPTURE_SPECIFIED_WINDOW and pass a display ID. 154 config_.captureMode = OH_CAPTURE_SPECIFIED_WINDOW; 155 config_.videoInfo.videoCapInfo.displayId = 0; 156 157 // Pass multiple window IDs. 158 vector<int32_t> missionIds = {60, 61}; // Windows 60 and 61 are to be captured at the same time. 159 config_.videoInfo.videoCapInfo.missionIDs = &missionIds[0]; 160 config_.videoInfo.videoCapInfo.missionIDsLen = static_cast<int32_t>(missionIds.size()); 161 ``` 162 1632. OH_CAPTURE_SPECIFIED_SCREEN mode. 164 165 The 2-in-1 device displays a picker dialog box, with the display (specified by the passed display ID) pre-selected. 166 167 ```c++ 168 // Configure the screen capture width and height in config_ based on the 2-in-1 device's resolution. 169 config_.videoInfo.videoCapInfo.videoFrameWidth = 2880; 170 config_.videoInfo.videoCapInfo.videoFrameHeight = 1920; 171 172 // Set the screen capture mode to OH_CAPTURE_SPECIFIED_SCREEN and pass a display ID. 173 config_.captureMode = OH_CAPTURE_SPECIFIED_SCREEN; 174 config_.videoInfo.videoCapInfo.displayId = 0; 175 ``` 176 1773. OH_CAPTURE_HOME_SCREEN mode. 178 179 The 2-in-1 device does not display a picker dialog box. Instead, it displays a privacy dialog box to ask for user approval. 180 181 ```c++ 182 // Configure the screen capture width and height in config_ based on the 2-in-1 device's resolution. 183 config_.videoInfo.videoCapInfo.videoFrameWidth = 2880; 184 config_.videoInfo.videoCapInfo.videoFrameHeight = 1920; 185 186 // Set the screen capture mode to OH_CAPTURE_HOME_SCREEN and pass a display ID. 187 config_.captureMode = OH_CAPTURE_HOME_SCREEN; 188 config_.videoInfo.videoCapInfo.displayId = 0; 189 ``` 190 191## Detailed Description 192This section describes how to set screen capture parameters, set callback functions, and stop the screen capture service instance involved in [How to Develop](#how-to-develop). 193 1941. Set screen capture parameters. 195 ```c++ 196 // Configure audio information in audioinfo. 197 OH_AudioCaptureInfo micCapinfo = { 198 .audioSampleRate = 48000, 199 .audioChannels = 2, 200 .audioSource = OH_SOURCE_DEFAULT 201 }; 202 OH_AudioCaptureInfo innerCapInfo = { 203 .audioSampleRate = 48000, 204 .audioChannels = 2, 205 .audioSource = OH_ALL_PLAYBACK 206 }; 207 OH_AudioEncInfo audioEncInfo = { 208 .audioSampleRate = 48000, 209 .audioCodecformat = OH_AudioCodecFormat::OH_AAC_LC 210 }; 211 212 // Configure video information in videoinfo. 213 OH_VideoCaptureInfo videoCapInfo = { 214 .videoFrameWidth = 768, 215 .videoFrameHeight = 1280, 216 .videoSource = OH_VIDEO_SOURCE_SURFACE_RGBA 217 }; 218 OH_VideoEncInfo videoEncInfo = { 219 .videoCodec = OH_VideoCodecFormat::OH_H264, 220 .videoBitrate = 2000000, 221 .videoFrameRate = 30 222 }; 223 ``` 224 2252. Set callback functions. 226 227 Listeners are provided for error events, state changes, and data obtained involved in screen capture. 228 229 ```c++ 230 // OnError(), a callback function invoked when an error occurs. 231 void OnError(OH_AVScreenCapture *capture, int32_t errorCode, void *userData) { 232 (void)capture; 233 (void)errorCode; 234 (void)userData; 235 } 236 237 // OnStageChange(), a callback function invoked when the state changes. 238 void OnStageChange(struct OH_AVScreenCapture *capture, OH_AVScreenCaptureStateCode stateCode, void *userData) { 239 (void)capture; 240 if (stateCode == OH_SCREEN_CAPTURE_STATE_STARTED) { 241 // Process the screen capture start event. 242 } 243 if (stateCode == OH_SCREEN_CAPTURE_STATE_CANCELED) { 244 // Process the screen capture cancellation event. 245 } 246 if (stateCode == OH_SCREEN_CAPTURE_STATE_STOPPED_BY_CALL) { 247 // Process the event indicating that screen capture is interrupted by a call. 248 } 249 if (stateCode == OH_SCREEN_CAPTURE_STATE_MIC_UNAVAILABLE) { 250 // Process the event indicating that the microphone is unavailable during screen capture. 251 } 252 if (stateCode == OH_SCREEN_CAPTURE_STATE_INTERRUPTED_BY_OTHER) { 253 // Process the event indicating that screen capture is interrupted by others. 254 } 255 ... 256 if (stateCode == OH_SCREEN_CAPTURE_STATE_EXIT_PRIVATE_SCENE) { 257 // Process the event indicating that the application exits the privacy mode during screen capture. 258 } 259 (void)userData; 260 } 261 262 // Obtain and process the OnBufferAvailable() callback function of the original audio and video stream data. 263 void OnBufferAvailable(OH_AVScreenCapture *capture, OH_AVBuffer *buffer, OH_AVScreenCaptureBufferType bufferType, int64_t timestamp, void *userData) { 264 // Screen capture is in progress. 265 if (IsCaptureStreamRunning) { 266 if (bufferType == OH_SCREEN_CAPTURE_BUFFERTYPE_VIDEO) { 267 // Video buffer. 268 OH_NativeBuffer *nativeBuffer = OH_AVBuffer_GetNativeBuffer(buffer); 269 if (nativeBuffer != nullptr && capture != nullptr) { 270 // Obtain the buffer capacity. 271 int bufferLen = OH_AVBuffer_GetCapacity(buffer); 272 273 // Obtain the buffer attribute. 274 OH_AVCodecBufferAttr info; 275 OH_AVBuffer_GetBufferAttr(buffer, &info); 276 277 // Obtain the native buffer configuration. 278 OH_NativeBuffer_Config config; 279 OH_NativeBuffer_GetConfig(nativeBuffer, &config); 280 281 // Obtain the buffer address. 282 uint8_t *buf = OH_AVBuffer_GetAddr(buffer); 283 if (buf != nullptr) { 284 return; 285 } 286 // Use the buffer data. 287 288 // The reference count of the native buffer is decremented by 1. When the reference count reaches 0, the buffer is released. 289 OH_NativeBuffer_Unreference(nativeBuffer); 290 } 291 } else if (bufferType == OH_SCREEN_CAPTURE_BUFFERTYPE_AUDIO_INNER) { 292 // Buffer for internal recording. 293 // Obtain the buffer attribute. 294 OH_AVCodecBufferAttr info; 295 OH_AVBuffer_GetBufferAttr(buffer, &info); 296 297 // Obtain the buffer capacity. 298 int bufferLen = OH_AVBuffer_GetCapacity(buffer); 299 300 // Obtain the buffer address. 301 uint8_t *buf = OH_AVBuffer_GetAddr(buffer); 302 if (buf != nullptr) { 303 return; 304 } 305 // Use the buffer data. 306 } else if (bufferType == OH_SCREEN_CAPTURE_BUFFERTYPE_AUDIO_MIC) { 307 // Microphone buffer. 308 // Obtain the buffer capacity. 309 int bufferLen = OH_AVBuffer_GetCapacity(buffer); 310 311 // Obtain the buffer address. 312 uint8_t *buf = OH_AVBuffer_GetAddr(buffer); 313 if (buf != nullptr) { 314 return; 315 } 316 // Use the buffer data. 317 } 318 } 319 } 320 ``` 321 3223. Stops the screen capture service and releases resources. 323 ```c++ 324 void StopScreenCapture() { 325 // Screen capture is in progress and a screen capture service instance exists. 326 if (IsCaptureStreamRunning && capture != nullptr) { 327 // Stop screen capture. 328 OH_AVScreenCapture_StopScreenCapture(capture); 329 330 // Release screen capture resources. 331 OH_AVScreenCapture_Release(capture); 332 333 // Clear other resources, such as closing the file. 334 335 // Set IsCaptureStreamRunning to false and the screen capture service instance to a null pointer. 336 IsCaptureStreamRunning = false; 337 capture = nullptr; 338 } 339 } 340 ``` 341 342## Sample Code 343 344Refer to the sample code below to implement screen capture using AVScreenCapture. 345 346For details about how to create an OH_AVBuffer instance, see [Buffer Output](../avcodec/video-decoding.md#buffer-output). 347 348For details about screen capture in surface mode, see [Surface Input](../avcodec/video-encoding.md#surface-input). 349 350Currently, the buffer holds original streams, which can be encoded and saved in MP4 format for playback. 351 352> **NOTE** 353> 354> The encoding format is reserved and will be implemented in later versions. 355 356```c++ 357 358#include "napi/native_api.h" 359#include <multimedia/player_framework/native_avscreen_capture.h> 360#include <multimedia/player_framework/native_avscreen_capture_base.h> 361#include <multimedia/player_framework/native_avscreen_capture_errors.h> 362#include <multimedia/player_framework/native_avbuffer.h> 363#include <native_buffer/native_buffer.h> 364#include <fcntl.h> 365#include "string" 366#include "unistd.h" 367 368struct OH_AVScreenCapture *capture; 369static napi_value Screencapture(napi_env env, napi_callback_info info) { 370 // Obtain the window ID number[] from the JS side. 371 std::vector<int> windowIdsExclude = {}; 372 size_t argc = 1; 373 napi_value args[1] = {nullptr}; 374 // Obtain parameters. 375 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); 376 // Obtain the length of the array. 377 uint32_t array_length; 378 napi_get_array_length(env, args[0], &array_length); 379 // Read the initial window ID. 380 for (int32_t i = 0; i < array_length; i++) { 381 napi_value temp; 382 napi_get_element(env, args[0], i, &temp); 383 uint32_t tempValue; 384 napi_get_value_uint32(env, temp, &tempValue); 385 windowIdsExclude.push_back(tempValue); 386 } 387 // Instantiate AVScreenCapture. 388 capture = OH_AVScreenCapture_Create(); 389 390 // Set the callbacks. 391 OH_AVScreenCapture_SetErrorCallback(capture, OnError, nullptr); 392 OH_AVScreenCapture_SetStateCallback(capture, OnStateChange, nullptr); 393 OH_AVScreenCapture_SetDataCallback(capture, OnBufferAvailable, nullptr); 394 395 // (Optional) Configure screen capture rotation. This API should be called when the device screen rotation is detected. If the device screen does not rotate, the API call is invalid. 396 OH_AVScreenCapture_SetCanvasRotation(capture, true); 397 // Optional. Filter audio. 398 OH_AVScreenCapture_ContentFilter *contentFilter= OH_AVScreenCapture_CreateContentFilter(); 399 // Add a filter announcement. 400 OH_AVScreenCapture_ContentFilter_AddAudioContent(contentFilter, OH_SCREEN_CAPTURE_NOTIFICATION_AUDIO); 401 // Exclude the specified window ID. 402 OH_AVScreenCapture_ContentFilter_AddWindowContent(contentFilter, &windowIdsExclude[0], 403 static_cast<int32_t>(windowIdsExclude.size())); 404 405 OH_AVScreenCapture_ExcludeContent(capture, contentFilter); 406 407 // Initialize the screen capture parameters and pass in an OH_AVScreenRecorderConfig struct. 408 OH_AudioCaptureInfo miccapinfo = {.audioSampleRate = 16000, .audioChannels = 2, .audioSource = OH_MIC}; 409 OH_VideoCaptureInfo videocapinfo = { 410 .videoFrameWidth = 768, .videoFrameHeight = 1280, .videoSource = OH_VIDEO_SOURCE_SURFACE_RGBA}; 411 OH_AudioInfo audioinfo = { 412 .micCapInfo = miccapinfo, 413 }; 414 OH_VideoInfo videoinfo = {.videoCapInfo = videocapinfo}; 415 OH_AVScreenCaptureConfig config = {.captureMode = OH_CAPTURE_HOME_SCREEN, 416 .dataType = OH_ORIGINAL_STREAM, 417 .audioInfo = audioinfo, 418 .videoInfo = videoinfo}; 419 OH_AVScreenCapture_Init(capture, config); 420 421 // Optional. Use the surface mode. 422 // To create an encoder by MIME type, call OH_VideoEncoder_CreateByMime. The system creates the most appropriate encoder based on the MIME type. 423 // OH_AVCodec *codec = OH_VideoEncoder_CreateByMime(OH_AVCODEC_MIMETYPE_VIDEO_AVC); 424 // Obtain the input surface from a video encoder. 425 // OH_AVErrCode OH_VideoEncoder_GetSurface(codec, window); 426 // Start the encoder. 427 // int32_t retEnc = OH_VideoEncoder_Start(codec); 428 // Specify a surface to start screen capture. 429 // int32_t retStart = OH_AVScreenCapture_StartScreenCaptureWithSurface(capture, window); 430 431 // Start screen capture. 432 OH_AVScreenCapture_StartScreenCapture(capture); 433 434 // Enable the microphone. 435 OH_AVScreenCapture_SetMicrophoneEnabled(capture, true); 436 437 // (Optional) Transfer the IDs of the subwindows and main windows to skip from screen capture. Transfer an empty array to cancel the windows that has been configured for exemption. 438 // std::vector<int> windowIdsSkipPrivacy = {}; 439 // OH_AVScreenCapture_SkipPrivacyMode(capture, &windowIdsSkipPrivacy[0], 440 // static_cast<int32_t>(windowIdsSkipPrivacy.size())); 441 442 // (Optional) Adjust the screen capture resolution after the capture starts. For details about the resolution range, see the AVCodec encoding and decoding capabilities. 443 // OH_AVScreenCapture_ResizeCanvas(capture, 768, 1280); 444 445 // (Optional) Set the maximum frame rate for screen capture. Call the function after screen capture starts. 446 // OH_AVScreenCapture_SetMaxVideoFrameRate(capture, 20); 447 448 sleep(10); // Capture the screen for 10s. 449 // Stop screen capture. 450 OH_AVScreenCapture_StopScreenCapture(capture); 451 // Release the AVScreenCapture instance. 452 OH_AVScreenCapture_Release(capture); 453 // Return the call result. In the example, only a random number is returned. 454 napi_value sum; 455 napi_create_double(env, 5, &sum); 456 457 return sum; 458} 459``` 460