Linux上使用FFmpeg进行录音功能

 更新时间:2025年01月03日 08:36:58   作者:Postkarte不想说话  
这篇文章主要为大家详细介绍了Linux上如何使用FFmpeg进行录音功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下

使用的发行版

➜  ~ lsb_release -a
No LSB modules are available.
Distributor ID:	Linuxmint
Description:	Linux Mint 22
Release:	22
Codename:	wilma

创建一个Qt项目

创建名称为audio的Qt项目

下载FFmpeg

我们下载共享库版本的FFmpeg

下载链接

解压缩

FFmepg下载解压缩后放在和前面创建的Qt项目在一个同级别路径下

修改Qt项目文件

修改Qt项目文件CmakeLists.txt,引入头文件和库,添加内容如下

# 设置变量
set(ffmpeg444 "../ffmpeg444")

# 引入头文件目录
include_directories(${ffmpeg444}/include/)
# 引入库文件目录,注意link_directories要放在add_executable之前
link_directories(${ffmpeg444}/lib/)

# 链接库中添加avdevice avutil avformat
target_link_libraries(audio PRIVATE Qt${QT_VERSION_MAJOR}::Widgets avdevice avutil avformat)

添加一个开始录音的按钮

注册设备

设备只需要注册一次,因为我们在main.cpp文件中添加

#include "mainwindow.h"

#include <QApplication>
extern "C" {
// 设备相关
#include <libavdevice/avdevice.h>

}
int main(int argc, char *argv[])
{
    // 注册设备,程序整个运行过程只需要注册一次
    avdevice_register_all();
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

开始录音

查看系统上的音频输入设备

查看下所有设备

➜  ~ ffmpeg -hide_banner -devices
Devices:
 D. = Demuxing supported
 .E = Muxing supported
 --
 DE fbdev           Linux framebuffer
 D  kmsgrab         KMS screen capture
 D  lavfi           Libavfilter virtual input device
 DE oss             OSS (Open Sound System) playback
 DE pulse           Pulse audio output
  E sdl,sdl2        SDL2 output device
 DE video4linux2,v4l2 Video4Linux2 output device
 D  x11grab         X11 screen capture, using XCB

我们可以使用arecord -l 查看下系统上的音频硬件设备

➜  arecord -l
**** List of CAPTURE Hardware Devices ****
card 0: K66 [K66], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: Device [USB Audio Device], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 2: PCH [HDA Intel PCH], device 0: ALC897 Analog [ALC897 Analog]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 2: PCH [HDA Intel PCH], device 2: ALC897 Alt Analog [ALC897 Alt Analog]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 4: Camera [USB 2.0 Camera], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

录音按钮点击相关代码, 修改mainwindow.cpp文件

内容如下

#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include <QDebug>
#include <QFile>

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

#define BUF_SIZE 1024

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::on_audioButton_clicked()
{
    const char* fmtName = "pulse"; //设置输入设备格式名称
    // 获取输入格式对象
    AVInputFormat *fmt = av_find_input_format(fmtName);

    if (!fmt) {
        qDebug() << "获取输入格式对象失败" << fmtName;
        return;
    }

    AVFormatContext *ctx = nullptr;  // 打开的设备上下文对象,可以利用这个上下文对象来操作设备

    // 设备名称,可以使用 arecord -l查看设备
    const char* deviceName = "hw:0";  // 使用card 0, arecord -l命令列出的第一个设备

    AVDictionary* options = nullptr;  // 选项

    // 利用输入格式对象打开设备
    int ret = avformat_open_input(&ctx, deviceName, fmt, &options);

    if (ret < 0) {
        char errbuf[BUF_SIZE] = {0};
        // av_strerror获取错误原因
        av_strerror(ret, errbuf, BUF_SIZE);
        qDebug() << "打开设备失败:" << errbuf;
        return;

    }


    // 录音保存的文件
    const char* fileName = "out.pcm";  // 采集的数据是原始pcm数据
    QFile file(fileName);

    // 打开文件
    // WriteOnly: 只写模式,如果文件不存在,则创建文件。如果文件存在,则清空文件内容
    if (!file.open(QIODevice::WriteOnly)) {
        qDebug() << "文件打开失败" << fileName;
        avformat_close_input(&ctx);  // 关闭设备
        return;
    }

    // 开始采集数据
    int count = 50; // 采集数据的次数
    AVPacket pkt;  // 数据包
    while(count-- > 0 && av_read_frame(ctx, &pkt) == 0) {  // 一直采集数据,当为0时说明数据采集成功了
        // 将数据写入文件
        file.write((const char *)pkt.data, pkt.size);
    }

    // 释放资源
    file.close();  // 关闭文件
    avformat_close_input(&ctx); // 关闭设备

}

关于设备部分,我们可以使用条件编译

#ifdef Q_OS_LINUX
    const char* fmtName = "pulse"; //设置输入设备格式名称
#elif Q_OS_WIN
    const char* fmtName = "dshow"; //设置输入设备格式名称
#endif



#ifdef Q_OS_LINUX
    // 设备名称,可以使用 arecord -l查看设备
    const char* deviceName = "hw:0";
#elif Q_OS_WIN
    const char* deviceName = "audio=麦克风 (K66)";
#endif

开始录音

点击开始录音,稍等一会儿,发现二进制程序目录下多了一个out.pcm我们录制的音频文件

播放

我们可以使用ffplay播放我们刚才录制的pcm音频数据

查看PCM的格式

使用ffmpeg -hide_banner -formats 我们可以输出所有的格式

➜  ~ ffmpeg -hide_banner -formats | grep PCM
 DE alaw            PCM A-law
 DE f32be           PCM 32-bit floating-point big-endian
 DE f32le           PCM 32-bit floating-point little-endian
 DE f64be           PCM 64-bit floating-point big-endian
 DE f64le           PCM 64-bit floating-point little-endian
 DE mulaw           PCM mu-law
 DE s16be           PCM signed 16-bit big-endian
 DE s16le           PCM signed 16-bit little-endian
 DE s24be           PCM signed 24-bit big-endian
 DE s24le           PCM signed 24-bit little-endian
 DE s32be           PCM signed 32-bit big-endian
 DE s32le           PCM signed 32-bit little-endian
 DE s8              PCM signed 8-bit
 DE u16be           PCM unsigned 16-bit big-endian
 DE u16le           PCM unsigned 16-bit little-endian
 DE u24be           PCM unsigned 24-bit big-endian
 DE u24le           PCM unsigned 24-bit little-endian
 DE u32be           PCM unsigned 32-bit big-endian
 DE u32le           PCM unsigned 32-bit little-endian
 DE u8              PCM unsigned 8-bit
 DE vidc            PCM Archimedes VIDC

播放

  • -ar 指定采样率
  • -ac 指定声道数
  • -f 指定音频格式, s16le表示有符号的16位小端模式
ffplay -ar 44100 -ac 2 -f s16le out.pcm

以上就是Linux上使用FFmpeg进行录音功能的详细内容,更多关于Linux FFmpeg录音的资料请关注脚本之家其它相关文章!

相关文章

  • 详解Linux常用的四种压缩命令

    详解Linux常用的四种压缩命令

    这篇文章主要详细介绍了Linux常用的四种压缩命令,tar命令,gzip命令,rar命令和zip命令,并通过代码示例给大家讲解的非常详细,具有一定的参考价值,需要的朋友可以参考下
    2024-03-03
  • 详解Shell 脚本中 “$” 符号的多种用法

    详解Shell 脚本中 “$” 符号的多种用法

    这篇文章主要介绍了详解Shell 脚本中 '$' 符号的多种用法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-05-05
  • 使用Bash Shell检查文件是否存在的方法

    使用Bash Shell检查文件是否存在的方法

    大多数情况下,可以使用测试命令来对条件进行测试。比如可以比较字符串、判断文件是否存在及是否可读等等。下面这篇文章就主要介绍了使用Bash Shell检查文件是否存在的方法,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-01-01
  • Linux Shell 脚本编程入门教程

    Linux Shell 脚本编程入门教程

    Linux的Shell种类众多,常见的有:Bourne Shell(/usr/bin/sh或/bin/sh)、Bourne Again Shell(/bin/bash)、C Shell(/usr/bin/csh)、K Shell(/usr/bin/ksh)、Shell for Root(/sbin/sh),Shell是用户与Linux操作系统沟通的桥梁,对本文感兴趣的朋友一起看看吧
    2015-11-11
  • Linux systemd 定时任务原理解析

    Linux systemd 定时任务原理解析

    说到 Linux 定时任务,大家用得最多的就是 crond 服务,但其实 systemd 也有类似的功能,我们不但可以通过 systemd 来管理服务,还能设置定时任务,那就是 systemd timer,接下来通过本文介绍Linux systemd 定时任务的相关知识,需要的朋友可以参考下
    2024-04-04
  • awk统计文件中某关键词出现次数的命令

    awk统计文件中某关键词出现次数的命令

    awk统计文件中某关键词出现的次数,供朋友们学习参考
    2013-02-02
  • Shell实现系统时间和BIOS时间同步校准脚本分享

    Shell实现系统时间和BIOS时间同步校准脚本分享

    这篇文章主要介绍了Shell实现系统时间和BIOS时间同步校准脚本分享,本文给出了多个时间同步服务器,然后用ntpdate轮询同步,需要的朋友可以参考下
    2014-10-10
  • linux shell中的比较符号与特殊符号介绍

    linux shell中的比较符号与特殊符号介绍

    本文为大家介绍linux shell中的特殊符号,包括字符串比较、数字比较与计算、特殊字符等,学习shell的朋友可以看下
    2013-06-06
  • linux ls命令教程及ls命令使用方法

    linux ls命令教程及ls命令使用方法

    学习linux这么久了,最常用的命令莫属 ls命令了,今天就总结下ls命令的用法与经验技巧。感兴趣的朋友一起看看吧
    2017-08-08
  • shell脚本之判断输入参数是否为整数值的实例

    shell脚本之判断输入参数是否为整数值的实例

    今天小编就为大家分享一篇shell脚本之判断输入参数是否为整数值的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-07-07

最新评论