点击上方“Qt学视觉”,选择“星标”公众号重磅干货,第一时间送达
共同学习共同进步
音频输入可以使用QAudioRecorder或QAudioInput两个类实现。QAudioRecorder是高层次的 实现,输入的音频数据直接保存为文件,也可以通过QAudioProbe访问原始的音频数据。QAudioInput是低层次的实现,直接控制音频输入设备的参数,并将音频录制数据写入一个流设备。
1.使用 QAudioRecorder录制音频
QAudioRecorder是用于录制音频的类,它从QMediaRecorder类继承而来,只需要较少的代码, 就可以实现音频录制并存储到文件。
QAudioRecorder需要使用一个QAudioEncoderSettings类型的变量进行输入音频设置,主要是 编码格式、采样率、通道数、音频质量等高级设置,上图窗口左侧是音频输入设置。
设置一个输出保存文件后就可以使用QAudioRecorder录制文件,录制的数据会自动保存到文 件里。音频输入设备会根据音频设置自动确定底层的釆样参数,使用QAudioProbe类可以获取音 频输入缓冲区的参数和原始数据,上图窗口右侧显示了音频输入缓冲区的数据参数,包括缓冲区字节数、帧数、采样数、采样字长、釆样率等,通过这些参数就可以从缓冲区读取出原始的音频数据。
2. QAudioRecorder录音功能的实现
代码如下:
#pragma once#include #include #include "QMyVideoWidget.h"QT_CHARTS_USE_NAMESPACE#include "ui_QGuiMultimedia.h"#include #include #include #include #include #include #include #include #include "QMyDisplayDevice.h"#include #include #include #include #include class QGuiMultimedia : public QWidget{ Q_OBJECTpublic: QGuiMultimedia(QWidget *parent = Q_NULLPTR); ~QGuiMultimedia(); void onRecorderStateChanged(QMediaRecorder::State state);//recorder void onRecorderDurationChanged(qint64 duration);//recorder void probeProcessBuffer(const QAudioBuffer& buffer);//probe void btnStartRecord_clicked(); void btnPauseRecord_clicked(); void btnStopRecord_clicked(); void btnGetFile_clicked();private: QAudioRecorder* m_pRecorder;//音频录音 QAudioProbe* m_pProbe; //探测器}#include "QGuiMultimedia.h"#include #include #include #pragma execution_character_set("utf-8")QGuiMultimedia::QGuiMultimedia(QWidget* parent) : QWidget(parent){ ui.setupUi(this); m_pRecorder = new QAudioRecorder(this); m_pProbe = new QAudioProbe;//探测器 connect(m_pProbe, SIGNAL(audioBufferProbed(QAudioBuffer)), this, SLOT(probeProcessBuffer(QAudioBuffer))); m_pProbe->setSource(m_pRecorder); connect(m_pRecorder, SIGNAL(stateChanged(QMediaRecorder::State)), this, SLOT(onRecorderStateChanged(QMediaRecorder::State))); connect(m_pRecorder, SIGNAL(durationChanged(qint64)), this, SLOT(onRecorderDurationChanged(qint64))); if (m_pRecorder->defaultAudioInput().isEmpty()) return; //无音频录入设备 foreach(const QString & device, m_pRecorder->audioInputs()) ui.comboDevices->addItem(device); //音频录入设备列表 foreach(const QString & codecName, m_pRecorder->supportedAudioCodecs()) ui.comboCodec->addItem(codecName); //支持的音频编码 foreach(int sampleRate, m_pRecorder->supportedAudioSampleRates()) ui.comboSampleRate->addItem(QString::number(sampleRate)); //支持的采样率 //channels ui.comboChannels->addItem("1"); ui.comboChannels->addItem("2"); ui.comboChannels->addItem("4"); //quality ui.sliderQuality->setRange(0, int(QMultimedia::VeryHighQuality)); ui.sliderQuality->setValue(int(QMultimedia::NormalQuality)); //bitrates: ui.comboBitrate->addItem("32000"); ui.comboBitrate->addItem("64000"); ui.comboBitrate->addItem("96000"); ui.comboBitrate->addItem("128000"); connect(ui.btnStartRecord, SIGNAL(clicked()), this, SLOT(btnStartRecord_clicked())); connect(ui.btnPauseRecord, SIGNAL(clicked()), this, SLOT(btnPauseRecord_clicked())); connect(ui.btnStopRecord, SIGNAL(clicked()), this, SLOT(btnStopRecord_clicked())); connect(ui.btnGetFile, SIGNAL(clicked()), this, SLOT(btnGetFile_clicked()));}QGuiMultimedia::~QGuiMultimedia(){}void QGuiMultimedia::onRecorderStateChanged(QMediaRecorder::State state){ //录音状态变化 ui.btnStartRecord->setEnabled(state != QMediaRecorder::RecordingState); ui.btnPauseRecord->setEnabled(state == QMediaRecorder::RecordingState); ui.btnStopRecord->setEnabled(state == QMediaRecorder::RecordingState); ui.btnGetFile->setEnabled(state == QMediaRecorder::StoppedState); ui.editOutputFile->setEnabled(state == QMediaRecorder::StoppedState);}void QGuiMultimedia::onRecorderDurationChanged(qint64 duration){ //录音持续时间变化 ui.LabPassTime->setText(QString("已录制 %1 秒").arg(duration / 1000));}void QGuiMultimedia::probeProcessBuffer(const QAudioBuffer& buffer){ //处理探测到的缓冲区 ui.spin_byteCount->setValue(buffer.byteCount());//缓冲区字节数 ui.spin_duration->setValue(buffer.duration() / 1000);//缓冲区时长 ui.spin_frameCount->setValue(buffer.frameCount());//缓冲区帧数 ui.spin_sampleCount->setValue(buffer.sampleCount());//缓冲区采样数 QAudioFormat audioFormat = buffer.format();//缓冲区格式 ui.spin_channelCount->setValue(audioFormat.channelCount()); //通道数 ui.spin_sampleSize->setValue(audioFormat.sampleSize());//采样大小 ui.spin_sampleRate->setValue(audioFormat.sampleRate());//采样率 ui.spin_bytesPerFrame->setValue(audioFormat.bytesPerFrame());//每帧字节数 if (audioFormat.byteOrder() == QAudioFormat::LittleEndian) ui.edit_byteOrder->setText("LittleEndian");//字节序 else ui.edit_byteOrder->setText("BigEndian"); ui.edit_codec->setText(audioFormat.codec());//编码格式 if (audioFormat.sampleType() == QAudioFormat::SignedInt)//采样点类型 ui.edit_sampleType->setText("SignedInt"); else if (audioFormat.sampleType() == QAudioFormat::UnSignedInt) ui.edit_sampleType->setText("UnSignedInt"); else if (audioFormat.sampleType() == QAudioFormat::Float) ui.edit_sampleType->setText("Float"); else ui.edit_sampleType->setText("Unknown");}//开始录音void QGuiMultimedia::btnStartRecord_clicked(){ if (m_pRecorder->state() == QMediaRecorder::StoppedState) //已停止,重新设置 { QString selectedFile = ui.editOutputFile->text().trimmed(); if (selectedFile.isEmpty()) { QMessageBox::critical(this, "错误", "请先设置录音输出文件"); return; } if (QFile::exists(selectedFile)) if (!QFile::remove(selectedFile)) { QMessageBox::critical(this, "错误", "所设置录音输出文件被占用,无法删除"); return; } m_pRecorder->setOutputLocation(QUrl::fromLocalFile(selectedFile));//设置输出文件 m_pRecorder->setAudioInput(ui.comboDevices->currentText()); //设置录入设备 QAudioEncoderSettings settings; //音频编码设置 settings.setCodec(ui.comboCodec->currentText());//编码 settings.setSampleRate(ui.comboSampleRate->currentText().toInt());//采样率 settings.setBitRate(ui.comboBitrate->currentText().toInt());//比特率 settings.setChannelCount(ui.comboChannels->currentText().toInt()); //通道数 settings.setQuality(QMultimedia::EncodingQuality(ui.sliderQuality->value())); //品质 if (ui.radioQuality->isChecked())//编码模式为固定品质,自动决定采样率,采样点大小 settings.setEncodingMode(QMultimedia::ConstantQualityEncoding); else settings.setEncodingMode(QMultimedia::ConstantBitRateEncoding);//固定比特率 m_pRecorder->setAudioSettings(settings); //音频设置 } m_pRecorder->record();}//暂停void QGuiMultimedia::btnPauseRecord_clicked(){ m_pRecorder->pause();}//停止void QGuiMultimedia::btnStopRecord_clicked(){ m_pRecorder->stop();}//设置保存文件void QGuiMultimedia::btnGetFile_clicked(){ QString curPath = QDir::homePath();//获取系统当前目录 QString dlgTitle = "选择输出文件"; //对话框标题 QString filter = "wav文件(*.wav)"; //文件过滤器 QString selectedFile = QFileDialog::getSaveFileName(this, dlgTitle, curPath, filter); if (!selectedFile.isEmpty()) ui.editOutputFile->setText(selectedFile);}