文档管理中心

使用AVScreenCapture录屏取码流(C/C++)

屏幕录制主要为主屏幕录屏功能。

开发者可以调用录屏(AVScreenCapture)模块的C API接口,完成屏幕录制,采集设备内、麦克风等的音视频源数据。当开发直播、办公等应用时,可以调用录屏模块获取音视频原始码流,然后通过流的方式流转到其他模块处理,达成直播时共享桌面的场景。

录屏模块和窗口(Window)、图形(Graphic)等模块协同完成整个视频采集的流程。

当前在进行屏幕录制时默认使用主屏,图形默认根据主屏生产录屏帧数据到显示数据缓冲队列,录屏框架从显示数据缓冲队列获取数据进行相应处理。

使用AVScreenCapture录制屏幕涉及到AVScreenCapture实例的创建、音视频采集参数的配置、采集的开始与停止、资源的释放等。

开始屏幕录制时正在通话中或者屏幕录制过程中来电,录屏将自动停止。因通话中断的录屏会上报OH_SCREEN_CAPTURE_STATE_STOPPED_BY_CALL状态。

屏幕录制过程中发生系统用户切换事件时,录屏将自动停止。因系统用户切换中断的录屏会上报OH_SCREEN_CAPTURE_STATE_STOPPED_BY_USER_SWITCHES状态。

本开发指导将以完成一次屏幕数据录制的过程为例,向开发者讲解如何使用AVScreenCapture进行屏幕录制,详细的API声明请参考AVScreenCapture API参考

如果配置了采集麦克风音频数据,需对应配置麦克风权限ohos.permission.MICROPHONE和申请长时任务,配置方式请参见向用户申请权限申请长时任务

开发步骤及注意事项

使用AVScreenCapture时要明确其状态的变化,在创建实例后,调用对应的方法可以进入指定的状态实现对应的行为。

在确定的状态下执行不合适的方法会导致AVScreenCapture发生错误,开发者需要在调用状态转换的方法前进行状态检查,避免程序运行异常。

在 CMake 脚本中链接动态库

收起
自动换行
深色代码主题
复制
  1. target_link_libraries(entry PUBLIC libnative_avscreen_capture.so libnative_buffer.so libnative_media_core.so)
  1. 添加头文件。

    收起
    自动换行
    深色代码主题
    复制
    1. #include "napi/native_api.h"
    2. #include <multimedia/player_framework/native_avscreen_capture.h>
    3. #include <multimedia/player_framework/native_avscreen_capture_base.h>
    4. #include <multimedia/player_framework/native_avscreen_capture_errors.h>
    5. #include <native_buffer/native_buffer.h>
    6. #include <fcntl.h>
    7. #include "string"
    8. #include "unistd.h"
  2. 创建AVScreenCapture实例capture。

    收起
    自动换行
    深色代码主题
    复制
    1. OH_AVScreenCapture* capture = OH_AVScreenCapture_Create();
  3. 配置屏幕录制参数。

    创建AVScreenCapture实例capture后,可以设置屏幕录制所需要的参数。

    收起
    自动换行
    深色代码主题
    复制
    1. OH_AudioCaptureInfo miccapinfo = {
    2. .audioSampleRate = 16000,
    3. .audioChannels = 2,
    4. .audioSource = OH_MIC
    5. };
    6. OH_VideoCaptureInfo videocapinfo = {
    7. .videoFrameWidth = 768,
    8. .videoFrameHeight = 1280,
    9. .videoSource = OH_VIDEO_SOURCE_SURFACE_RGBA
    10. };
    11. OH_AudioInfo audioinfo = {
    12. .micCapInfo = miccapinfo,
    13. };
    14. OH_VideoInfo videoinfo = {
    15. .videoCapInfo = videocapinfo
    16. };
    17. OH_AVScreenCaptureConfig config = {
    18. .captureMode = OH_CAPTURE_HOME_SCREEN,
    19. .dataType = OH_ORIGINAL_STREAM,
    20. .audioInfo = audioinfo,
    21. .videoInfo = videoinfo
    22. };
    23. OH_AVScreenCapture_Init(capture, config);
  4. 设置麦克风开关。

    收起
    自动换行
    深色代码主题
    复制
    1. bool isMic = true;
    2. OH_AVScreenCapture_SetMicrophoneEnabled(capture, isMic);
  5. 回调函数的设置,主要监听录屏过程中的错误事件的发生,音频流和视频流数据的产生事件。

    收起
    自动换行
    深色代码主题
    复制
    1. OH_AVScreenCapture_SetErrorCallback(capture, OnError, userData);
    2. OH_AVScreenCapture_SetStateCallback(capture, OnStateChange, userData);
    3. OH_AVScreenCapture_SetDataCallback(capture, OnBufferAvailable, userData);
  6. 调用StartScreenCapture()方法开始进行屏幕录制。

    收起
    自动换行
    深色代码主题
    复制
    1. OH_AVScreenCapture_StartScreenCapture(capture);

    或调用StartScreenCaptureWithSurface方法以Surface模式进行屏幕录制。

    收起
    自动换行
    深色代码主题
    复制
    1. OH_AVScreenCapture_StartScreenCaptureWithSurface(capture, window);
  7. 调用StopScreenCapture()方法停止录制。

    收起
    自动换行
    深色代码主题
    复制
    1. OH_AVScreenCapture_StopScreenCapture(capture);
  8. 在回调OnBufferAvailable()中获取并处理音频视频原始码流数据。

    收起
    自动换行
    深色代码主题
    复制
    1. OnBufferAvailable(OH_AVScreenCapture *capture, OH_AVBuffer *buffer,
    2. OH_AVScreenCaptureBufferType bufferType, int64_t timestamp, void *userData)
  9. 调用Release()方法销毁实例,释放资源。

    收起
    自动换行
    深色代码主题
    复制
    1. OH_AVScreenCapture_Release(capture);

完整示例

下面展示了使用AVScreenCapture屏幕录制的完整示例代码。

创建OH_AVBuffer,可参考视频解码Buffer模式

使用Surface模式录屏,可参考视频编码Surface模式

目前阶段流程结束后返回的buffer为原始码流,针对原始码流可以进行编码并以mp4等文件格式保存以供播放。

说明

编码格式当前阶段仅作预留,待后续版本实现。

收起
自动换行
深色代码主题
复制
  1. #include "napi/native_api.h"
  2. #include <multimedia/player_framework/native_avscreen_capture.h>
  3. #include <multimedia/player_framework/native_avscreen_capture_base.h>
  4. #include <multimedia/player_framework/native_avscreen_capture_errors.h>
  5. #include <multimedia/player_framework/native_avbuffer.h>
  6. #include <native_buffer/native_buffer.h>
  7. #include <fcntl.h>
  8. #include "string"
  9. #include "unistd.h"
  10. void OnError(OH_AVScreenCapture *capture, int32_t errorCode, void *userData) {
  11. (void)capture;
  12. (void)errorCode;
  13. (void)userData;
  14. }
  15. void OnStateChange(struct OH_AVScreenCapture *capture, OH_AVScreenCaptureStateCode stateCode, void *userData) {
  16. (void)capture;
  17. if (stateCode == OH_SCREEN_CAPTURE_STATE_STARTED) {
  18. // 处理状态变更
  19. }
  20. if (stateCode == OH_SCREEN_CAPTURE_STATE_STOPPED_BY_CALL ||
  21. stateCode == OH_SCREEN_CAPTURE_STATE_STOPPED_BY_USER_SWITCHES) {
  22. // 录屏中断状态处理
  23. }
  24. if (stateCode == OH_SCREEN_CAPTURE_STATE_INTERRUPTED_BY_OTHER) {
  25. // 处理状态变更
  26. }
  27. (void)userData;
  28. }
  29. void OnBufferAvailable(OH_AVScreenCapture *capture, OH_AVBuffer *buffer,
  30. OH_AVScreenCaptureBufferType bufferType, int64_t timestamp, void *userData) {
  31. // 获取解码后信息 可以参考编解码接口
  32. int bufferLen = OH_AVBuffer_GetCapacity(buffer);
  33. OH_NativeBuffer *nativeBuffer = OH_AVBuffer_GetNativeBuffer(buffer);
  34. OH_NativeBuffer_Config config;
  35. OH_NativeBuffer_GetConfig(nativeBuffer, &config);
  36. int32_t videoSize= config.height * config.width * 4;
  37. uint8_t *buf = OH_AVBuffer_GetAddr(buffer);
  38. if (bufferType == OH_SCREEN_CAPTURE_BUFFERTYPE_VIDEO) {
  39. // 处理视频buffer
  40. } else if (bufferType == OH_SCREEN_CAPTURE_BUFFERTYPE_AUDIO_INNER) {
  41. // 处理内录buffer
  42. } else if (bufferType == OH_SCREEN_CAPTURE_BUFFERTYPE_AUDIO_MIC) {
  43. // 处理麦克风buffer
  44. }
  45. }
  46. struct OH_AVScreenCapture *capture;
  47. static napi_value Screencapture(napi_env env, napi_callback_info info) {
  48. // 从js端获取窗口id number[]
  49. std::vector<int> windowIdsExclude = {};
  50. size_t argc = 1;
  51. napi_value args[1] = {nullptr};
  52. // 获取参数
  53. napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
  54. // 获取数组长度
  55. uint32_t array_length;
  56. napi_get_array_length(env, args[0], &array_length);
  57. // 读初窗口id
  58. for (int32_t i = 0; i < array_length; i++) {
  59. napi_value temp;
  60. napi_get_element(env, args[0], i, &temp);
  61. uint32_t tempValue;
  62. napi_get_value_uint32(env, temp, &tempValue);
  63. windowIdsExclude.push_back(tempValue);
  64. }
  65. // 实例化ScreenCapture
  66. capture = OH_AVScreenCapture_Create();
  67. // 设置回调
  68. OH_AVScreenCapture_SetErrorCallback(capture, OnError, nullptr);
  69. OH_AVScreenCapture_SetStateCallback(capture, OnStateChange, nullptr);
  70. OH_AVScreenCapture_SetDataCallback(capture, OnBufferAvailable, nullptr);
  71. // 可选 配置录屏旋转,此接口在感知到手机屏幕旋转时调用,如果手机的屏幕实际上没有发生旋转,调用接口是无效的。
  72. OH_AVScreenCapture_SetCanvasRotation(capture, true);
  73. // 可选 [过滤音频]
  74. OH_AVScreenCapture_ContentFilter *contentFilter= OH_AVScreenCapture_CreateContentFilter();
  75. // 添加过滤通知音
  76. OH_AVScreenCapture_ContentFilter_AddAudioContent(contentFilter, OH_SCREEN_CAPTURE_NOTIFICATION_AUDIO);
  77. // 排除指定窗口id
  78. OH_AVScreenCapture_ContentFilter_AddWindowContent(contentFilter, &windowIdsExclude[0],
  79. static_cast<int32_t>(windowIdsExclude.size()));
  80. OH_AVScreenCapture_ExcludeContent(capture, contentFilter);
  81. // 初始化录屏,传入配置信息OH_AVScreenRecorderConfig
  82. OH_AudioCaptureInfo miccapinfo = {.audioSampleRate = 16000, .audioChannels = 2, .audioSource = OH_MIC};
  83. OH_VideoCaptureInfo videocapinfo = {
  84. .videoFrameWidth = 768, .videoFrameHeight = 1280, .videoSource = OH_VIDEO_SOURCE_SURFACE_RGBA};
  85. OH_AudioInfo audioinfo = {
  86. .micCapInfo = miccapinfo,
  87. };
  88. OH_VideoInfo videoinfo = {.videoCapInfo = videocapinfo};
  89. OH_AVScreenCaptureConfig config = {.captureMode = OH_CAPTURE_HOME_SCREEN,
  90. .dataType = OH_ORIGINAL_STREAM,
  91. .audioInfo = audioinfo,
  92. .videoInfo = videoinfo};
  93. OH_AVScreenCapture_Init(capture, config);
  94. // 可选 [Surface模式]
  95. // 通过 MIME TYPE 创建编码器,系统会根据MIME创建最合适的编码器。
  96. // OH_AVCodec *codec = OH_VideoEncoder_CreateByMime(OH_AVCODEC_MIMETYPE_VIDEO_AVC);
  97. // 从视频编码器获取输入Surface
  98. // OH_AVErrCode OH_VideoEncoder_GetSurface(codec, window);
  99. // 启动编码器
  100. // int32_t retEnc = OH_VideoEncoder_Start(codec);
  101. // 指定surface开始录屏
  102. // int32_t retStart = OH_AVScreenCapture_StartScreenCaptureWithSurface(capture, window);
  103. // 开始录屏
  104. OH_AVScreenCapture_StartScreenCapture(capture);
  105. // mic开关设置
  106. OH_AVScreenCapture_SetMicrophoneEnabled(capture, true);
  107. // 可选 豁免隐私窗口 需传递应用豁免子窗口和主窗口ID,传空数组取消豁免隐私窗口
  108. // std::vector<int> windowIdsSkipPrivacy = {};
  109. // OH_AVScreenCapture_SkipPrivacyMode(capture, &windowIdsSkipPrivacy[0],
  110. // static_cast<int32_t>(windowIdsSkipPrivacy.size()));
  111. // 可选 调整录屏分辨率 需在启动后调用,分辨率有范围限制 可参考avcodec编解码能力
  112. // OH_AVScreenCapture_ResizeCanvas(capture, 768, 1280);
  113. sleep(10); // 录制10s
  114. // 结束录屏
  115. OH_AVScreenCapture_StopScreenCapture(capture);
  116. // 释放ScreenCapture
  117. OH_AVScreenCapture_Release(capture);
  118. // 返回调用结果,示例仅返回随意值
  119. napi_value sum;
  120. napi_create_double(env, 5, &sum);
  121. return sum;
  122. }
在 指南 中进行搜索
请输入您想要搜索的关键词