Qt由入门到放弃-音频采集与录制

QT音频采集与录制

QT       += multimedia #在Pro中添加使用qt多媒体模块
QAudioFormat音频格式类
QAudioFormat format;
format.setSampleRate(16000);
//设定声道数目,mono(平声道)的声道数目是1;stero(立体声)的声道数目是2
format.setChannelCount(2);   
format.setSampleSize(16);
format.setCodec("audio/pcm");   //编码器
//设定高低位,LittleEndian(低位优先),LargeEndian(高位优先)
format.setByteOrder(QAudioFormat::LittleEndian);   
format.setSampleType(QAudioFormat::SignedInt);
QAudioDeviceInfo 音频设备信息类

QAudioDeviceInfo类提供了一个查询音频设备及其功能的接口。QAudioDeviceInfo允许您查询系统中当前可用的音频设备(如声卡和USB耳机)。可用的音频设备取决于安装的平台或音频插件。

//返回支持模式的音频设备列表
//const QAudio::Mode mode =  QAudio::AudioInput; // QAudio::AudioOutput
QList<QAudioDeviceInfo> availableDevices(QAudio::Mode mode)
//返回默认输入音频设备的信息。所有平台和音频插件实现都提供了一个默认的音频设备来使用
QAudioDeviceInfo defaultInputDevice()
//返回默认输出音频设备的信息。所有平台和音频插件实现都提供了一个默认的音频设备来使用
QAudioDeviceInfo defaultOutputDevice()
//获取默认的音频输入设备,判断是否支持指定的格式,如果不支持则使用一个邻近的格式
QAudioDeviceInfo info = QAudioDeviceInfo::defaultInputDevice();
if (!info.isFormatSupported(format))
{
    format = info.nearestFormat(format);
}
QAudioInput 从音频输入设备接收音频数据类

直接获取音频采集设备的原始data,对data进行读写、存取等操作,实现音频的录制

//构造函数
//构造一个新的音频输入并将其附加到父级。默认音频输入设备与输出格式参数一起使用。
QAudioInput(const QAudioFormat &format = QAudioFormat(), QObject *parent = nullptr)
//构造一个新的音频输入并将其附加到父级。audioDevice引用的设备与输入格式参数一起使用
QAudioInput(const QAudioDeviceInfo &audioDevice, const QAudioFormat &format = QAudioFormat(), QObject *parent = nullptr)

//启动QAudioInput只需调用start(),并打开一个QIODevice进行写入
//开始将音频数据从系统的音频输入传输到设备。设备必须已在WriteOnly、Append或ReadWrite模式下打开。
//如果QAudioInput能够成功获取音频数据,state()将返回QAudio::ActiveState或QAudio::IdleState,error()返回QAudio::NoError,并发出stateChanged()信号。
//如果在此过程中出现问题,error()返回QAudio::OpenError,state()返回QAudio::StoppedState,并发出stateChanged()信号。
void QAudioInput::start(QIODevice *device) //向设备device中写入数据

//返回指向用于从系统音频输入传输数据的内部QIODevice的指针。设备已经打开,read()可以直接从中读取数据。注意:在流停止或启动另一个流后,指针将变为无效。
//如果QAudioInput能够访问系统的音频设备,state()返回QAudio::IdleState,error()返回QAudio::NoError,并发出stateChanged()信号。
//如果在此过程中出现问题,error()返回QAudio::OpenError,state()返回QAudio::StoppedState,并发出stateChanged()信号。
QIODevice *QAudioInput::start() //启动读取数据,并返回设备的指针,根据此指针获取音频数据流

//返回可供读取的音频数据量(字节)。注意:返回值只在QAudio::ActiveState或QAudio::IdleState状态时有效,否则返回零。
int QAudioInput::bytesReady() const

//停止音频输入,与系统资源分离
void QAudioInput::stop()
QScopedPointer<QAudioInput> m_audioInput;
QScopedPointer<AudioInfo> m_audioInfo;//class AudioInfo : public QIODevice
bool m_pullMode = true;

// Change bewteen pull and push modes
    if (m_pullMode) {
        m_audioInput->start(m_audioInfo.data());
    } else
    {
        auto io = m_audioInput->start();
        connect(io, &QIODevice::readyRead,
            [&, io]() {
                qint64 len = m_audioInput->bytesReady();
                const int BufferSize = 4096;
                if (len > BufferSize)
                    len = BufferSize;

                QByteArray buffer(len, 0);
                //从设备中读取数据到buffer中
                qint64 l = io->read(buffer.data(), len);
                if (l > 0)
                {
                    //写入到新的io设备中
                    m_audioInfo->write(buffer.constData(), l);
                }

            });
    }
QIODevice 输入输出设备类

QIODevice用于对输入输出设备进行管理。输入设备有两种类型,一种是随机访问设备(Random-accessdevices),如文件、缓冲区等;另一种是时序设备(Sequential device),如网络、进程等。可以通过isSequential()函数分辨设备是哪种类型的。

//纯虚函数,继承需要重写此函数,此函数由QIODevice调用
//从设备读取最多maxSize字节到data,并返回读取的字节数,如果发生错误,则返回-1
//QDataStream能够对类进行操作,但是QDataStream假定已读取所有请求的信息,因此如果出现问题,则不会重试读取
[pure virtual protected] qint64 QIODevice::readData(char *data, qint64 maxSize)

//纯虚函数,继承需要重写此函数,此函数由QIODevice调用
//从data中向设备写入最多maxSize字节。返回写入的字节数,如果发生错误,返回-1
[pure virtual protected] qint64 QIODevice::writeData(const char *data, qint64 maxSize)

//从设备读取最多maxSize字节到data,并返回读取的字节数。
//如果发生错误,例如尝试从以WriteOnly模式打开的设备进行读取时,此函数将返回-1
qint64 QIODevice::read(char *data, qint64 maxSize)

//从data中向设备写入最多maxSize字节的数据。返回实际写入的字节数,如果发生错误,返回-1
qint64 QIODevice::write(const char *data, qint64 maxSize)
QAudioProbe 监视正在播放或录制的音频l类

QAudioProbe类一旦接收到,则执行槽函数,处理对应的缓冲数据,通过获取当前的QAudioBuffer进行显示操作

//在媒体服务中音频缓冲区被处理此信号发出
[signal] void QAudioProbe::audioBufferProbed(const QAudioBuffer &buffer)
  QAudioRecorder *recorder = new QAudioRecorder();
  QAudioProbe *probe = new QAudioProbe;
  // ... configure the audio recorder (skipped)
  connect(probe, SIGNAL(audioBufferProbed(QAudioBuffer)), this, SLOT(processBuffer(QAudioBuffer)));
  probe->setSource(recorder); // 设置监视的源,Returns true, hopefully.
  recorder->record(); // Now we can do things like calculating levels or performing an FFT
QAudioBuffer 具有特定格式和采样率的音频样本集合类

和QAudioProbe结合使用,解析采样的音频数据

QAudioRecorder 录制音频类,父类为QMediaRecorder

此类和QAudioInput从设备读取数据类不同在于,直接调用record()即可向指定文件录制音频文件,不需要自己操作QIODevide设备的读写。

enum QMediaRecorder::State

ConstantValueDescription
QMediaRecorder::StoppedState0The recorder is not active.
QMediaRecorder::RecordingState1The recording is requested.
QMediaRecorder::PausedState2The recorder is paused.

enum QMediaRecorder::Status

ConstantValueDescription
QMediaRecorder::UnavailableStatus0The recorder is not available or not supported by connected media object.
QMediaRecorder::UnloadedStatus1The recorder is avilable but not loaded.
QMediaRecorder::LoadingStatus2The recorder is initializing.
QMediaRecorder::LoadedStatus3The recorder is initialized and ready to record media.
QMediaRecorder::StartingStatus4Recording is requested but not active yet.
QMediaRecorder::RecordingStatus5Recording is active.
QMediaRecorder::PausedStatus6Recording is paused.
QMediaRecorder::FinalizingStatus7Recording is stopped with media being finalized.
//开始录制。当recorder state更改为QMediaRecorder::RecordingState时,录制可能会异步启动
//录制开始时会发出statusChanged(QMediaRecorder::RecordingStatus)信号。
//如果录制失败,则发出error()信号,并将记录器状态重置回QMediaRecorder::StoppedState。
[slot] void QMediaRecorder::record()

//Returns a list of supported audio codecs.音频编解码器的列表
QStringList QMediaRecorder::supportedAudioCodecs() const

//Returns a list of supported container formats.文件格式
QStringList QMediaRecorder::supportedContainers() const

//state  during record(), pause() or stop() calls
[signal] void QMediaRecorder::stateChanged(QMediaRecorder::State state)

//时长改变发送信号
[signal] void QMediaRecorder::durationChanged(qint64 duration)

//状态改变发送信号
[signal] void statusChanged(QMediaRecorder::Status status)

//表示录制媒体的实际位置已更改。这个信号通常在录音开始时发出
[signal] void QMediaRecorder::actualLocationChanged(const QUrl &location)

//设置文件输出路径,不设置则选择默认的路径进行存储
bool QMediaRecorder::setOutputLocation(const QUrl &location)

//设置音频和视频编码器设置和容器格式。
//如果未指定某些参数,或传递了空设置,编码器将根据媒体源属性选择默认编码参数。
//只有当编码器处于QMediaEncoder::StoppedState状态时才能更改设置。
void QMediaRecorder::setEncodingSettings(const QAudioEncoderSettings &audio,
const QVideoEncoderSettings &video = QVideoEncoderSettings(), const QString &container = QString())
//返回可用音频输入的列表
QStringList QAudioRecorder::audioInputs() const
QAudioEncoderSettings 编码设置类
QAudioEncoderSettings settings;
settings.setCodec(boxValue(ui->audioCodecBox).toString());
settings.setSampleRate(boxValue(ui->sampleRateBox).toInt());
settings.setBitRate(boxValue(ui->bitrateBox).toInt());
settings.setChannelCount(boxValue(ui->channelsBox).toInt());
settings.setQuality(QMultimedia::EncodingQuality(ui->qualitySlider->value()));
settings.setEncodingMode(ui->constantQualityRadioButton->isChecked() ?
                         QMultimedia::ConstantQualityEncoding :
                         QMultimedia::ConstantBitRateEncoding);

QString container = boxValue(ui->containerBox).toString();

m_audioRecorder->setEncodingSettings(settings, QVideoEncoderSettings(), container);
m_audioRecorder->record(); //开始录制
参考文献

QT5.12帮助文档及示例

  • 2
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值