HarmonyOS鸿蒙Next中基于C/C++方法录屏转码流无法录制到系统声音

HarmonyOS鸿蒙Next中基于C/C++方法录屏转码流无法录制到系统声音 官方demo:https://gitee.com/harmonyos_samples/avscreen-capture-screen-record.git
文档说明:https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-avscreencapture-for-screen-recording#section88234491599

官方demo无法录制系统内的声音,调整其他参数也不行,请问有没有大佬知道的?


更多关于HarmonyOS鸿蒙Next中基于C/C++方法录屏转码流无法录制到系统声音的实战教程也可以访问 https://www.itying.com/category-93-b0.html

10 回复

提供一下音频的相关配置,OH_AudioInfo里的参数

更多关于HarmonyOS鸿蒙Next中基于C/C++方法录屏转码流无法录制到系统声音的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


void CAVScreenCaptureToStream::SetConfigToStream(OH_AVScreenCaptureConfig &config, int32_t videoWidth,
                                                 int32_t videoHeight) {
    OH_AudioCaptureInfo micCapInfo = {.audioSampleRate = 48000, .audioChannels = 2, .audioSource = OH_SOURCE_DEFAULT};
    OH_AudioCaptureInfo innerCapInfo = {.audioSampleRate = 48000, .audioChannels = 2, .audioSource = OH_ALL_PLAYBACK};
    OH_AudioEncInfo audioEncInfo = {.audioBitrate = 96000, .audioCodecformat = OH_AudioCodecFormat::OH_AAC_LC};
    OH_AudioInfo audioInfo = {.micCapInfo = micCapInfo, .innerCapInfo = innerCapInfo, .audioEncInfo = audioEncInfo};

    OH_VideoCaptureInfo videoCapInfo = {
        .videoFrameWidth = videoWidth, .videoFrameHeight = videoHeight, .videoSource = OH_VIDEO_SOURCE_SURFACE_RGBA};

    OH_VideoEncInfo videoEncInfo = {
        .videoCodec = OH_VideoCodecFormat::OH_H264, .videoBitrate = 10000000, .videoFrameRate = 30};

    OH_VideoInfo videoInfo = {.videoCapInfo = videoCapInfo, .videoEncInfo = videoEncInfo};

    config = {
        .captureMode = OH_CAPTURE_HOME_SCREEN,
        .dataType = OH_ORIGINAL_STREAM,
        .audioInfo = audioInfo,
        .videoInfo = videoInfo,
    };
}

void CAVScreenCaptureToStream::StartScreenCapture(int32_t outputFd, int32_t videoWidth, int32_t videoHeight) {
    InitConfig(outputFd, videoWidth, videoHeight);

    if (g_avCapture != nullptr) {
        StopScreenCaptureRecording(g_avCapture);
    }

    g_avCapture = OH_AVScreenCapture_Create();
    if (g_avCapture == nullptr) {
        OH_LOG_ERROR(LOG_APP, "create screen capture failed");
    }
    OH_LOG_INFO(LOG_APP, "ScreenCapture after create sc");

    // Set callback
    OH_AVScreenCapture_SetErrorCallback(g_avCapture, OnErrorToStream, nullptr);
    OH_AVScreenCapture_SetStateCallback(g_avCapture, OnSurfaceStateChangeToStream, nullptr);

    OH_AVScreenCapture_SetMicrophoneEnabled(g_avCapture, true);
    OH_AVScreenCapture_SetCanvasRotation(g_avCapture, true);

    // Initialize configuration information
    OH_AVScreenCaptureConfig config_;
    SetConfigToStream(config_, videoWidth, videoHeight);
    int result = OH_AVScreenCapture_Init(g_avCapture, config_);
    if (result != AV_SCREEN_CAPTURE_ERR_OK) {
        OH_LOG_INFO(LOG_APP, "ScreenCapture OH_AVScreenCapture_Init failed %{public}d", result);
    }
    OH_LOG_INFO(LOG_APP, "ScreenCapture OH_AVScreenCapture_Init %{public}d", result);

    result = OH_AVScreenCapture_StartScreenCaptureWithSurface(g_avCapture, sampleInfo_.window);
    OH_LOG_INFO(LOG_APP, "OH_VideoEncoder_Start Started 2 %{public}d", result);
    if (result != AV_SCREEN_CAPTURE_ERR_OK) {
        OH_LOG_INFO(LOG_APP, "ScreenCapture Started failed %{public}d", result);
        OH_AVScreenCapture_Release(g_avCapture);
    }
    m_IsRunning = true;

    // Start muxer
    int32_t ret = muxer_->Start();
    // Start video Encoder
    ret = videoEncoder_->Start();

    isStarted_ = true;
    // Start the video output threads
    encOutputThread_ = std::make_unique<std::thread>(&CAVScreenCaptureToStream::EncOutputThread, this);
    if (encOutputThread_ == nullptr) {
        StartRelease();
        return;
    }

    if (audioEncContext_) {
        // Start AudioCapturer
        audioCapturer_->AudioCapturerStart();

        // Start audio Encoder
        audioEncoder_->Start();
        isStarted_ = true;
        // Start the audio input and output threads
        audioEncInputThread_ = std::make_unique<std::thread>(&CAVScreenCaptureToStream::AudioEncInputThread, this);
        audioEncOutputThread_ = std::make_unique<std::thread>(&CAVScreenCaptureToStream::AudioEncOutputThread, this);
        if (audioEncInputThread_ == nullptr || audioEncOutputThread_ == nullptr) {
            StartRelease();
            return;
        }

        // Empty the playback cache queue
        if (audioEncContext_ != nullptr) {
            audioEncContext_->ClearCache();
        }
    }
}

官网demo里面码流方式的录屏实现中没有实现内录的逻辑,如果需要实现支持内录的码流方式的录屏,可以参考官方文档,https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/using-avscreencapture-for-buffer

系统声音录制需要额外权限声明,在module.json5文件中需补充:

{
  "requestPermissions": [
    {
      "name": "ohos.permission.MEDIA_AUDIO_CAPTURE",
      "reason": "$string:reason"
    }
  ]
}

在初始化录屏参数时,需显式指定音频采集源为系统混音流。正确配置应包含:

OH_AVScreenCapture_SetAudioSource(capture, AV_AUDIO_SOURCE_MIX);

没有这个权限:MEDIA_AUDIO_CAPTURE 也没有这个函数:OH_AVScreenCapture_SetAudioSource,

找HarmonyOS工作还需要会Flutter的哦,有需要Flutter教程的可以学学大地老师的教程,很不错,B站免费学的哦:https://www.bilibili.com/video/BV1S4411E7LY/?p=17

升级下ffmpeg

跟ffmpeg没有关系,

HarmonyOS Next中C/C++录屏API仅能采集视频流,系统音频采集需使用鸿蒙专用音频接口。当前鸿蒙多媒体框架将音频路由与视频采集分离,系统声音需通过AudioCapturer单独获取音频轨道,再与视频流同步封装。该设计出于系统安全架构考虑,应用层无法直接访问全局音频混流。若需同时录制系统音视频,必须通过鸿蒙媒体会话服务申请组合权限。

在HarmonyOS Next中,使用C/C++方法进行录屏转码流时,系统声音录制可能受限于当前API的权限或配置。官方demo基于AVScreenCapture框架,默认可能仅捕获视频流,不包含系统音频。需要检查以下方面:

  1. 音频源配置:确保在初始化AVScreenCapture时,通过SetAudioSource方法明确指定音频源类型(如AUDIO_SOURCE_TYPE_SYSTEM),但当前HarmonyOS Next的公开API可能未开放系统音频捕获权限。

  2. 权限声明:在module.json5中检查是否已申请必要权限,例如ohos.permission.CAPTURE_SCREEN(涵盖录屏),但系统音频捕获可能需要额外权限(如ohos.permission.RECORD_AUDIO),且系统级音频权限可能对普通应用受限。

  3. 编码器兼容性:确认音频编码格式(如AAC)与容器格式(如MP4)匹配,但问题更可能源于框架未开放系统音频流接入。

目前,HarmonyOS Next对系统音频捕获的支持可能仍在完善中,建议关注官方文档更新或社区动态,以获取后续API扩展信息。可尝试替代方案(如应用内音频捕获),但系统级声音录制需依赖底层能力开放。

回到顶部