ffmpeg音频采集

Posted 一二三o-0-O

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ffmpeg音频采集相关的知识,希望对你有一定的参考价值。

【ffmpeg】音频采集

个人简介

📦个人主页:一二三o-0-O的博客
🏆技术方向:C/C++客户端资深工程师(直播+音视频剪辑)
👨‍💻作者简介:数据结构算法与音视频领域创作者
📒 系列专栏:ffmpeg入门
📣专栏目标:务实的掌握FFmpeg相关专业知识
🧡如果对您有帮助的话,欢迎点赞👍收藏📂,关注不迷路

前言

如果是刚刚开始学习音视频的伙伴,可以先看看音视频基 础专栏系列的内容,掌握音视频相关的一些基础理论

音视频基础专栏系列

(一)【音视频基础】音频基础理论
(二)【音视频基础】视频基础理论
(三)【音视频基础】封装格式与编码数据

如果觉得理论学习枯燥的伙伴,可以先通过以下四篇文章使用ffmpeg实现一个播放器,可以获得些许成就感,为持续在音视频领域扎根打好兴趣基础。

ffmpeg专栏系列

(一)【ffmpeg】ffmpeg命令工具的使用
(二)【ffmpeg】视频解码器
(三)【ffmpeg】SDL视频显示
(四)【ffmpeg】ffmpeg+SDL实现播放器

下面正式开始使用ffmpeg采集音频数据

通过命令采集音频数据

采集音频的方式

  • android
    • AudioRecorder
    • MediaRecoder
  • ios
    • AudioUnit
    • AVFoundation
  • Windows
    • DirectShow
    • OpenAL
    • AudioCore

windows下采集音频

  • 首先要获取windows设备的信息,使用下面的命令

./ffmpeg -list_devices true -f dshow -i dummy

运行后会得到所有的设备信息如下图所示:

  • 然后选择使用音频采集设备采集音频,使用下列命令行:

./ffmpeg -f dshow -i audio=“麦克风 (6- Logitech USB Headset H340)” out.wav

采集过程如下图,会默认使用16位、44.1K采样率以及双声道的采样数据进行采集:

  • 然后在同级目录生成wav的音频文件,可以使用ffmplay进行播放,确认与自己刚刚录制的音频是否一致,如下图所示:

通过API采集音频数据

API与命令行的流程是一致的:

  • 首先打开音频设备
  • 然后从音频设备中读取PCM数据
  • 最后将PCM数据录制下来

打开音频设备

使用ffmpeg4.2.2版本+Qt GUI框架

//音频设备
QString sDeviceName = "audio=" +
                      QString("麦克风 (6- Logitech USB Headset H340)");//vecDeviceName[0];

//ffmpeg
int ret = 0;
char errors[1024];
// 声明上下文
AVFormatContext *fmt_ctx = nullptr;

//注册音频设备
avdevice_register_all();

//设置windows下的音频采集format
const AVInputFormat *iformat = av_find_input_format("dshow");
// 打开音频设备
if ((ret = avformat_open_input(&fmt_ctx, sDeviceName.toUtf8().data(),
                               iformat, &options)) < 0) 
    av_strerror(ret, errors, 1024);
    qDebug() << QString("Failed to open audio device, [%1]%2\\n").arg(ret).arg(
                 errors);

从音频设备中读取音频数据

API,数据封装简析

  • av_read_frame
    • 读取音视频数据(本节只读取音频数据)
    • AVformatContext:上下文,判断是从音视频设备还是从媒体文件中读取数据
    • AVPacket:数据包(本节只是音频包)
    • 返回0表示成功
  • AVPacket
    • data:存具体的数据
    • size:缓冲区的大小
  • 与AVPacket相关的API
    • av_init_packet:初始化
    • av_packet_unref:释放初始化的资源,与av_init_packet成对使用
    • av_packet_alloc:申请资源、并调用av_init_packet初始化
    • av_packet_free:释放资源,与av_packet_alloc成对使用

代码

int count;
// 声明数据包
AVPacket pkt;
// 初始化数据包
av_init_packet(&pkt);

// 从设备中读取数据包
while ((ret = av_read_frame(fmt_ctx, &pkt)) == 0 &&
       count <= 500) 
    qDebug() << "pkt size is:" << pkt.size;

// 释放数据包
av_packet_unref(&pkt);

录制音频数据

// 声明文件
QFile file("D:\\\\msys64\\\\home\\\\Administrator\\\\ffmpegDemon\\\\bin\\\\debug\\\\exercise\\\\record.pcm");
// 打开文件
if (!file.open(QIODevice::Truncate | QIODevice::WriteOnly)) 
    qDebug() << "open failed";
    return;


// 从设备中读取数据包
while ((ret = av_read_frame(fmt_ctx, &pkt)) == 0 &&
       count <= 500) 
    qDebug() << "pkt size is:" << pkt.size;
	// 写文件
    file.write((const char *)pkt.data, pkt.size);

av_packet_unref(&pkt);
// 关闭文件
file.close();

参考资料

【1】雷神博客
【2】ffmpeg官方文档
【3】李超:音视频基础+ffmpeg原理

以上是关于ffmpeg音频采集的主要内容,如果未能解决你的问题,请参考以下文章

JavaCV音视频开发宝典:使用JavaCV采集windows系统声音并录制成mp3音频文件(FFmpeg采集windows系统声音)

JavaCV音视频开发宝典:使用JavaCV采集windows系统声音并录制成mp3音频文件(FFmpeg采集windows系统声音)

ffmpeg:无法识别音频输入设备

在 ffmpeg 中使用蓝牙耳机设备作为音频源

开源FFMpeg——使用SDL进行音频播放下(使用篇)

是否可以使用 ffmpeg 从 ASIO 设备捕获音频?