https://www.gyan.dev/ffmpeg/builds/ 选择相应的版本 xxx-full_build-shared.7z配置
在xx.pro文件中配置
# 设置FFmpeg头文件的位置
INCLUDEPATH += XXX/ffmpeg-4.3.2-2021-02-27-full_build-shared/include
# 设置FFmpeg静态库
LIBS += -L XXX/ffmpeg-4.3.2-2021-02-27-full_build-shared/lib
-lavcodec
-lavdevice
-lavfilter
-lavformat
-lavutil
-lpostproc
-lswresample
-lswscale
配置环境变量
在系统的Path中配置
XXXffmpeg-4.3.2-2021-02-27-full_build-sharedbin
QApplication a(argc, argv);
qDebug() << "FFMPEG version -> " << av_version_info();
// 1.注册设备 - 一个应用只注册一次
avdevice_register_all();
...
创建按钮实现事件
void MainWindow::on_recordButton_clicked()
{
// 按钮事件实现
if(thread == nullptr){
ui->recordButton->setText("结束录音");
thread = new record_thread(this);
// 对突发异常的处理
connect(thread,&QThread::finished,
[this]{
ui->recordButton->setText("开始录音");
thread = nullptr;
});
thread->start();
}else{
ui->recordButton->setText("开始录音");
thread->requestInterruption();
thread = nullptr;
}
}
实现子线程录音
// record_thread.h #ifndef RECORD_THREAD_H #define RECORD_THREAD_H #include#include #include #include extern "C" { #include #include #include #include } #define FILE_NAME "./out.pcm" // 多系统配置 #ifdef Q_OS_WIN // windows // 格式 #define FOMART_NAME "dshow" // 设备名称 #define DEVICE_NAME "audio=麦克风阵列 (2- Conexant SmartAudio HD)" #else #define FOMART_NAME "avfoundation" #define DEVICE_NAME ":0" #endif class record_thread : public QThread { Q_OBJECT public: explicit record_thread(QObject *parent = nullptr); ~record_thread(); private: void run() override; signals: }; #endif // RECORD_THREAD_H // record_thread.cpp #include "record_thread.h" record_thread::record_thread(QObject *parent) : QThread(parent) { qDebug() << "创建线程"; // 线程销毁的监听 connect(this,&QThread::finished,this,&QThread::deleteLater); } record_thread::~record_thread(){ qDebug() << "销毁线程"; // 断开所有连接 disconnect(); // 线程销毁的资源回收 --> while requestInterruption(); exit(); wait(); } void record_thread::run() { qDebug() << "开始录音"; // 2.获取输入格式 AVInputFormat * fmt = av_find_input_format(FOMART_NAME); if(!fmt){ qDebug() << "获取输入格式失败 -> " << FOMART_NAME; return; } // 3.打开设备 // 格式上下文 AVFormatContext * ctx = nullptr; // 选项 // AVDictionary * options; int ret = avformat_open_input(&ctx,DEVICE_NAME,fmt,nullptr); if(ret < 0){ char error_buff[1024] = {0}; av_strerror(ret,error_buff,sizeof(error_buff)); qDebug() << "打开设备失败 -> " << error_buff; return; } // 4.采集数据 // 数据包 AVPacket pkt; // 文件名 QFile file(FILE_NAME); // 文件只写 - 文件不存在就创建,存在就清空,再开始写入 if(!file.open(QIODevice::WriteOnly)){ qDebug() << "文件打开失败 -> " << FILE_NAME; avformat_close_input(&ctx); return; } // 保存数据 while(!isInterruptionRequested() && av_read_frame(ctx,&pkt) == 0){ file.write((const char *)pkt.data,pkt.size); } // 5.释放资源 file.close(); avformat_close_input(&ctx); qDebug() << "录音结束"; // 6.测试out.pcm文件 // ffplay -ar 44100 -ac 2 -f s16le out.pcm }



