使用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 设置格式
最后成功运行:
在这里插入图片描述

posted @ 2023-02-09 10:28  一颗蘋果  阅读(142)  评论(0编辑  收藏  举报