栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

QT实现FFMPEG录音功能(WIN)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

QT实现FFMPEG录音功能(WIN)

FFMPEG录音功能 QT 配置FFMPEG(WINDOWS) 下载资源文件
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
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/934295.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号