Qt6 QAudioSource录 pcm 音频

71 篇文章 4 订阅
13 篇文章 2 订阅

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QAudioSource>
#include <QFile>
#include <QMediaFormat>
#include <QMediaRecorder>
#include <QUrl>
#include <QMediaCaptureSession>
#include <QTimer>


QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void stopRecording();
    void updateProgress(qint64 duration);
    void handleStateChanged(QAudio::State newState);

private:
    Ui::Widget *ui;

    QFile destinationFile;   // Class member
    QAudioSource* audio; // Class member
 
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QAudioSource>
#include <QAudioInput>
#include <QAudioFormat>
#include <QAudioDevice>
#include <QMediaDevices>
#include <QFile>
#include <QTimer>
#include <iostream>
#include <QDir>
#include <QFileDialog>
#include <QMediaRecorder>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    destinationFile.setFileName("test.pcm");
    destinationFile.open( QIODevice::WriteOnly | QIODevice::Truncate );

    QAudioFormat format;
    // Set up the desired format, for example:
    format.setSampleRate(44100);
    format.setChannelCount(2);
    format.setSampleFormat(QAudioFormat::Int16);
    format.setChannelConfig(QAudioFormat::ChannelConfigStereo);

    QAudioDevice info = QMediaDevices::defaultAudioInput();
    if (!info.isFormatSupported(format))
    {
        qWarning() << "Default format not supported, trying to use the nearest.";
    }

    audio = new QAudioSource(format, this);
    connect(audio, SIGNAL(stateChanged(QAudio::State)), this, SLOT(handleStateChanged(QAudio::State)));

    //QTimer::singleShot(3000, this, SLOT(stopRecording()));
    audio->start(&destinationFile);
    // Records audio for 3000ms
}

Widget::~Widget()
{
    delete ui;
}

void Widget::stopRecording()
{
    audio->stop();
    destinationFile.close();
    delete audio;
}

void Widget::handleStateChanged(QAudio::State newState)
{
    switch (newState)
    {
    case QAudio::StoppedState:
        if (audio->error() != QAudio::NoError)
        {
            std::cout << "Error handling" << std::endl;
        }
        else
        {
            std::cout << "Finished recording" << std::endl;
        }
        break;

    case QAudio::ActiveState:
        std::cout << "Started recording - read from IO device" << std::endl;
        break;

    default:
        // ... other cases as appropriate
        break;
    }
}

void Widget::updateProgress(qint64 duration)
{
    qDebug() << duration;
}

main.cpp

#include "widget.h"
#include <QApplication>
#include <iostream>
#include <QTimer>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    Widget win;
    win.show();
    return app.exec();
}

widget.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Widget</class>
 <widget class="QWidget" name="Widget">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>600</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Widget</string>
  </property>
  <widget class="QPushButton" name="pushButton">
   <property name="geometry">
    <rect>
     <x>280</x>
     <y>200</y>
     <width>89</width>
     <height>25</height>
    </rect>
   </property>
   <property name="text">
    <string>stop</string>
   </property>
  </widget>
 </widget>
 <resources/>
 <connections>
  <connection>
   <sender>pushButton</sender>
   <signal>clicked()</signal>
   <receiver>Widget</receiver>
   <slot>stopRecording()</slot>
   <hints>
    <hint type="sourcelabel">
     <x>339</x>
     <y>206</y>
    </hint>
    <hint type="destinationlabel">
     <x>547</x>
     <y>206</y>
    </hint>
   </hints>
  </connection>
 </connections>
 <slots>
  <slot>stopRecording()</slot>
 </slots>
</ui>
xz@xiaqiu:~/study/csdn/opencv/audio/2/build$ ls
xz@xiaqiu:~/study/csdn/opencv/audio/2/build$ qmake ..
xz@xiaqiu:~/study/csdn/opencv/audio/2/build$ make
xz@xiaqiu:~/study/csdn/opencv/audio/2/build$ ls
main.o    moc_predefs.h   moc_widget.o  testqt       widget.o
Makefile  moc_widget.cpp  test.pcm      ui_widget.h

输入ffplay -ar 44100 -ac 2 -f s16le test.pcm
播放音频

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Qt中播放PCM音频,你可以使用QAudio类及其相关的子类。以下是一个基本的步骤: 1. **设置音频设备和格式**: 首先,你需要创建一个`QAudioDeviceInfo`对象,它代表系统的音频输入或输出设备。然后选择一个合适的音频格式,如QAudioFormat::Format_PCM_16Bit。 ```cpp QAudioDeviceInfo deviceInfo(QAudioDeviceInfo::defaultInputDevice()); QAudioFormat format; format.setSampleRate(44100); format.setChannelCount(2); // 双声道 format.setCodec("audio/pcm"); format.setByteOrder(QAudioFormat::LittleEndian); format.setSampleSize(16); ``` 2. **创建音频输出流**: 使用`QAudioOutput`类创建一个音频输出流,并将设备信息和格式设置到流中。 ```cpp QAudioOutput audioOutput(deviceInfo, format); if (!audioOutput.open(QIODevice::ReadOnly)) { qWarning() << "Failed to open audio output: " << audioOutput.errorString(); } ``` 3. **读取和播放PCM数据**: PCM数据通常存储在一个文件或者内存缓冲区中。你可以读取PCM数据并逐帧发送给音频输出流。 ```cpp QByteArray pcmData; // 假设已经从文件读取到pcmData audioOutput.start(); while (pcmData.size()) { qint64 bytesPlayed = audioOutput.write(pcmData.data(), pcmData.size()); if (bytesPlayed < 0) { qWarning() << "Error playing audio: " << audioOutput.errorString(); break; } pcmData.remove(0, bytesPlayed); } audioOutput.stop(); ``` 4. **处理错误和结束**: 在整个播放过程中,记得检查错误并正确关闭资源。 ```cpp audioOutput.close(); ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值