Ubuntu下使用Qt和ffmpeg,打开音频采集设备并读取数据

Ubuntu下使用Qt和ffmpeg,打开音频采集设备并读取数据

  1. 引入编译好的ffmpeg库文件和头文件。
    (1)在.pro文件中加入:
unix:!macx: LIBS += -L$$PWD/../../../usr/local/ffmpeg/lib/ 
-lavcodec -lavdevice -lavfilter -lavformat -lavutil -lswresample -lswscale

INCLUDEPATH += $$PWD/../../../usr/local/ffmpeg/include
DEPENDPATH += $$PWD/../../../usr/local/ffmpeg/include

即可引入库文件,库文件路径根据自己的编译路径修改,我的路径是/usr/local/ffmpeg。
(2)也可通过在Qt Creator中引入外部库文件的方式引入ffmpeg。

2.引入所需头文件

extern "C"
{
#include "libavdevice/avdevice.h"
#include "libavutil/avutil.h"
#include  "libavformat/avformat.h"
}

注意:ffmpeg是C语言编写的,C++环境下需要加上extern “C”,否则程序编译会报错。

  1. 打开设备
void MainWindow::openDevice()
{
    // 注册设备
    avdevice_register_all();

    // 获取采集格式
    AVInputFormat *inputFmt = av_find_input_format("alsa");

    int ret = 0;
    AVFormatContext *fmt_ctx = nullptr;
    char *deviceName = "hw:0,0";
    AVDictionary *options = nullptr;
    // 打开设备
    ret = avformat_open_input(&fmt_ctx, deviceName, inputFmt, &options);

    char errors[1024];
    if (ret < 0)
    {
        av_strerror(ret, errors, 1024);
        printf("Failed to open audio device, [%d]%s\n", ret, errors);
    }
}
  1. 从设备读取音频数据
  2. 增加头文件
#include "libavcodec/avcodec.h"

读取代码:

void MainWindow::openDeviceAndReadData()
{
    // 设置日志级别
    av_log_set_level(AV_LOG_DEBUG);
    // 注册设备
    avdevice_register_all();

    // 获取采集格式
    AVInputFormat *inputFmt = av_find_input_format("alsa");

    int ret = 0;
    AVFormatContext *fmt_ctx = nullptr;
    char *deviceName = "hw:0,0";
    AVDictionary *options = nullptr;
    // 打开设备
    ret = avformat_open_input(&fmt_ctx, deviceName, inputFmt, &options);

    char errors[1024] = {0};
    if (ret < 0)
    {
        av_strerror(ret, errors, 1024);
        printf("Failed to open audio device, [%d]%s\n", ret, errors);
        return;
    }

    int count = 0;
    AVPacket packet;

    av_init_packet(&packet);

    // 从设备读取数据
    while ((ret = av_read_frame(fmt_ctx, &packet) == 0) && count++ < 500)
    {
        av_log(NULL, AV_LOG_INFO, "Packet size: %d(%p), count = %d\n",
               packet.size, packet.data, count);

        // 释放packet空间
        av_packet_unref(&packet);
    }

    // 关闭设备,释放上下文空间
    avformat_close_input(&fmt_ctx);

    av_log(NULL, AV_LOG_DEBUG, "Finish!\n");

}

使用完上下文AVFormatContext 和AVPacket以后要注意释放空间,避免内存泄漏。

注:1. C语言和C++中手动分配的空间使用完以后要记得释放,避免内存泄漏,否则服务端程序不断申请内存空间而不释放,最终会导致程序崩溃。
2. 指针变量释放以后,要置为NULL,避免野指针。在多线程中,如果在线程1中的指针释放了其指向的内存地址,没有置为NULL,之后这块空间被线程2使用,而此时线程1中的指针依然可以访问并修改这块内存空间,如果线程1中的指针修改了内存内容,则会对线程2造成影响,产生不可估计的后果。

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

VectorAL

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值