Linux上使用FFmpeg進行錄音功能
使用的發(fā)行版
? ~ lsb_release -a No LSB modules are available. Distributor ID: Linuxmint Description: Linux Mint 22 Release: 22 Codename: wilma
創(chuàng)建一個Qt項目
創(chuàng)建名稱為audio的Qt項目

下載FFmpeg
我們下載共享庫版本的FFmpeg
解壓縮
FFmepg下載解壓縮后放在和前面創(chuàng)建的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();
}
開始錄音
查看系統(tǒng)上的音頻輸入設備
查看下所有設備
? ~ 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 查看下系統(tǒng)上的音頻硬件設備
? 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: 只寫模式,如果文件不存在,則創(chuàng)建文件。如果文件存在,則清空文件內容
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
開始錄音
點擊開始錄音,稍等一會兒,發(fā)現(xiàn)二進制程序目錄下多了一個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錄音的資料請關注腳本之家其它相關文章!
相關文章
windows下寫的shell腳本在linux執(zhí)行出錯的解決辦法
這篇文章主要介紹了windows下寫的shell腳本在linux執(zhí)行出錯的解決辦法,需要的朋友可以參考下2014-03-03
用shell腳本實現(xiàn)自動切換內網和外網實現(xiàn)高可用
因為公司的服務器這段時間內網網卡老是出現(xiàn)問題,然后就導致了網站的各種問題,因為我們的數據庫鏈接,redis還有sphinx鏈接都是走的內網,,所以就寫了這個腳本,在線上也跑了一段時間了,,也沒出過什么問題2013-06-06

