当前位置: 代码网 > 服务器>服务器>Linux > Linux上使用FFmpeg进行录音功能

Linux上使用FFmpeg进行录音功能

2025年02月13日 Linux 我要评论
使用的发行版➜ ~ lsb_release -ano lsb modules are available.distributor id:linuxmintdescription:linux mint

使用的发行版

➜  ~ 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录音的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com