// 格式名称、设备名称目前暂时使用宏定义固定死
#ifdef WIN64
#define FMT_NAME "dshow"
#define DEVICE_NAME "audio=麦克风阵列 (Realtek(R) Audio)"
#define FILENAME "D:/temp/out.pcm"
#endif
#include <QApplication>
#include <QPushButton>
#include "mainwindow.h"
#include <qdebug.h>
#include <QFile>
extern "C"
{
// 设备相关API
#include <libavdevice/avdevice.h>
// 格式相关API
#include <libavformat/avformat.h>
// 工具相关API(比如错误处理)
#include <libavutil/avutil.h>
// 编码相关API
#include <libavcodec/avcodec.h>
}
//音频录制
void auidoRecord(){
// 初始化libavdevice并注册所有 输入和输出设备 可能就是让程序知道有哪些设备吧 !
avdevice_register_all();//✔
//获取输入格式对象 根据名字获取对应的设备对象吧 然后就可以fmt 指针操作录音设备了,
//dshow,全名叫DirectShow,是Windows平台的多媒体系统库,可以使用dshow去操作多媒体输入设备
const AVInputFormat *fmt = av_find_input_format(FMT_NAME);//dshow ✔
//如果能获取失败
if(!fmt){ //感觉null 就是0
qDebug()<<"找不到输入对象"<<FMT_NAME;
return;
}
//这叫格式化上下文 用来操作设备的
AVFormatContext *ctx=nullptr;
//打开设备 给ctx 赋值 猜测通过ctx 可以操作DEVICE_NAME ,就是操作录音机地
int ret= avformat_open_input(&ctx,DEVICE_NAME,fmt,nullptr);//✔
if(ret<0){
char errbuff[1024]={0};
//根据ret 确认是什么错误
av_strerror(ret,errbuff,sizeof errbuff);
qDebug()<<"打开设备失败"<<errbuff;
return;
}
// 文件
QFile file(FILENAME);
// WriteOnly:只写模式。如果文件不存在,就创建文件;如果文件存在,就删除文件内容
if(!file.open(QFile::WriteOnly)){
qDebug() << "文件打开失败" << FILENAME;
// 关闭录音设备
avformat_close_input(&ctx);
return;
}
// 暂时假定只采集50个数据包 就是50 帧吧
int count=50;
//申请一个包包,来装音频数据 然后 再在这个包包里面拿数据 放到文件里面
AVPacket* pkt=av_packet_alloc();//数据包 给pkt 赋值
while(count-- > 0){
//采集数据 会自动一帧一帧 放入pkt
ret= av_read_frame(ctx,pkt);//ctx 操作数据 放进pkt 里面✔
if(ret==0){//读取成功
file.write((const char*)pkt->data,pkt->size);//把包里面的数据写进文件
//释放资源 数据包 当不再需要数据包时,必须使用 av_packet_unref ()释放它。
av_packet_unref(pkt);
}
else if(ret== AVERROR(EAGAIN)){
continue;
}
else{
char errbuff[1024];
av_strerror(ret,errbuff,sizeof errbuff);
qDebug()<<"av_read_frame error"<< errbuff << ret;
break;
}
}
// 关闭文件
file.close();
// 释放资源 pkt 就是包包 装东西的
av_packet_free(&pkt);
// 关闭设备
avformat_close_input(&ctx);//✔
}
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
MainWindow m;
m.show();
return QApplication::exec();
}
注意呢不能直接copy 代码 因为我代码里面文件路劲 在你的电脑可能没有,还有这是win 64位,并且,你要确保 ,你有依赖,其次你的配置没有啥问题,就是cmakelist文件没有啥问题