You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Qt AudioSource录制无数据:buffer.size()与processedUSecs()均为0

问题排查与解决方法

核心问题:缺少Qt事件循环

QAudioSource 依赖 Qt 的事件循环处理音频数据的采集和写入操作,控制台应用默认不会启动事件循环,导致音频数据无法写入 QBuffer,因此 buffer.size() 和 processedUSecs() 都为0。

具体修复步骤

  • 启动Qt事件循环:在控制台应用中手动创建 QCoreApplication 对象并调用 exec(),确保事件循环正常运行,这是音频数据能被写入的前提。
  • 修复格式检查逻辑:如果指定格式不被设备支持,直接回退到设备的首选格式,避免使用无效格式导致录制失败。
  • 替换阻塞式sleep:用Qt的 QTimer 实现定时读取,避免阻塞事件循环影响音频采集。
  • 优化Buffer使用:不要频繁启停录制,定时读取数据后重置Buffer,保持录制的连续性。

修复后的示例代码

#include <QCoreApplication>
#include <QAudioSource>
#include <QAudioDevice>
#include <QMediaDevices>
#include <QBuffer>
#include <QTimer>
#include <iostream>
#include <cassert>

bool hasInitialisedAudio = false;
QAudioSource* source = nullptr;
QBuffer* buffer = nullptr;

double calculateRMS(const char* data, qint64 size) {
    // 实现你的RMS计算逻辑
    return 0.0;
}

void readAudioData() {
    if (!source || !buffer) return;

    source->stop();
    buffer->seek(0);
    std::cout << "Recorded a buffer of size " << buffer->size() 
              << " during " << source->processedUSecs() / 1000000.0 << " seconds." << std::endl;
    double RMS = calculateRMS(buffer->data().constData(), buffer->size());

    // 重置Buffer并重启录制
    buffer->buffer().clear();
    buffer->seek(0);
    source->start(buffer);
}

int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);

    buffer = new QBuffer();
    buffer->open(QBuffer::ReadWrite);

    QAudioFormat format;
    format.setSampleRate(8000);
    format.setChannelCount(1);
    format.setSampleFormat(QAudioFormat::UInt8);

    QAudioDevice info = QMediaDevices::defaultAudioInput();
    if (!info.isFormatSupported(format)) {
        std::cout << "Default format not supported, using preferred format" << std::endl;
        format = info.preferredFormat();
    }

    source = new QAudioSource(format);
    assert(source->state() == QAudio::StoppedState);

    source->setVolume(1);
    source->start(buffer);

    if (source->error() != QAudio::NoError || source->state() != QAudio::ActiveState) {
        std::cout << "An error has occurred while recording audio" << std::endl;
        return 1;
    }

    hasInitialisedAudio = true;

    // 每10秒触发一次数据读取
    QTimer* timer = new QTimer();
    QObject::connect(timer, &QTimer::timeout, readAudioData);
    timer->start(10000);

    return a.exec(); // 启动事件循环
}

额外注意事项

  • 项目的 .pro 文件需添加多媒体模块:QT += multimedia
  • 长时间录制时,建议将数据写入文件而非内存Buffer,避免内存溢出
  • 程序退出时记得释放 QAudioSource、QBuffer、QTimer 等动态分配的对象

内容的提问来源于stack exchange,提问作者user22925547

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 01:36:05