使用Qt利用ffmpeg录音
首先需要使用ffmpeg获取到录音设备的设备名:
ffmpeg -f dshow -list_devices true -i dummy
期间出现报错:
该错误为QT中的常见错误,原因是函数调用中传进去的某一个指针变量没有被初始化
将AVFormatContext *ctx = nullptr;指向空后问题解决;
完整代码(代码更换环境需要修改格式对象(“dshow”为window上使用的)、设备名称和文件路径):
//获取输入格式对象
AVInputFormat *fmt = av_find_input_format("dshow");
if(!fmt)
{
qDebug()<<"获取输入格式失败"<<endl;
return;
}
//格式上下文(将来用于上下文操作设备,类似于句柄)
AVFormatContext *ctx = nullptr;
//设备名称
//cmd命令:ffmpeg -f dshow -list_devices true -i dummy 得到设备名称
const char *deviceName = "audio=插孔麦克风 (Realtek(R) Audio)";
//打开设备
int ret = avformat_open_input(&ctx, deviceName, fmt, nullptr);
if (ret < 0)
{
char errbuf[1024] = {0};
//根据函数返回的错误码获取错误信息
av_strerror(ret, errbuf, sizeof (errbuf));
qDebug()<<"打开设备失败:"<<errbuf;
return;
}
//文件名
const char* filename = "C:/Users/lzg/Desktop/qt_ffmpeg/haha/out.pcm";
QFile file(filename);
//如果文件不存在则创建文件,文件存在则清空文件
if(!file.open(QIODevice::WriteOnly)) //当只使用WriteOnly时,有Truncate功能
{
qDebug()<<"文件打开失败:"<<filename<<endl;
avformat_close_input(&ctx); //打开了必须关闭,不然存在内存泄漏
return;
}
//数据包
AVPacket pkt;
//采集50次数据
int count = 50;
while(count-- >0 && av_read_frame(ctx, &pkt)==0)
{
//将数据写入文件
file.write((const char*)pkt.data, pkt.size);
}
avformat_close_input(&ctx); //打开了必须关闭,不然存在内存泄漏
file.close();
qDebug()<<"采集结束"<<endl;
//ffmpeg -formats | findstr PCM
//ffplay -ar 44100 -ac 2 -f s16le out.pcm
采集到的pcm数据不能直接播放,因为里面只有音频数据,关于波特率,采样率等数据都没有,这是ffmpeg无法播放此音频;
在命令行窗口使用以下命令可以得到输出格式为s16le,有符号16位小端模式
ffmpeg -formats | findstr PCM
接下来使用命令将采集到的音频进行转换得到可播放的音频:
ffplay -ar 44100 -ac 2 -f s16le out.pcm
-ar rate set audio sampling rate (in Hz) 设置采样率
-ac channels set number of audio channels 设置双通道
-f fmt force format 设置格式
最后成功运行: