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录音的资料请关注脚本之家其它相关文章!
最新评论