多系统使用ffmpeg读取麦克风数据

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、命令行
    • 1.Ubuntu
      • 1.alsa
      • 2.pulseaudio
    • 2.Windows
      • 1.dshow
  • 二、代码
  • 总结


前言

最近在搞一个项目需要用到麦克风读取数据并分析,我的开发环境是Ubuntu-22.04,这个操作系统的声音架构是基于alsa+pulseaudio构建的,18.04和20.04一样。这里我会稍微向你展示下alsa和pulseaudio的些许差别,当然这只是这个系统的冰山一角,感兴趣的可以继续研究下去。


一、命令行

如果你只是想简单使用这个功能而不需要去开发代码,这个命令行很适合你。接下来分别基于UbuntuWindows来演示具体的方法,你可以感受其中的差别。

注意:alsa和pulseaudio只是其中一种多媒体架构,还有很多别的架构,只要是ffmpeg支持的都可以拿来用。

1.Ubuntu

这个操作系统上alsa和pulseaudio是有一定的差别的,看起来alsa更接近底层,更像是直接和硬件打交道;而pulseaudio是C/S架构,就是一个或多个Server(一般一个就够了,它只是支持多个)对一个或多个Client。

1.alsa

查看电脑上的声卡
cat /proc/asound/cards0 [PCH            ]: HDA-Intel - HDA Intel PCHHDA Intel PCH at 0xb42b0000 irq 138

我的电脑只有一个内置声卡,我的内置麦克风和内置扬声器乃至耳机插孔都是接在这个声卡上的。

使用也简单符合hw:CARD[,DEV[,SUBDEV]]这个格式就行了,除了hw必带以外,CARD是第几个声卡索引DEV是当前声卡下的设备索引SUBDEV是当前设备下的子设备索引

ffmpeg -f alsa -i hw:0,0,0 out1.wav
[alsa @ 0x617f08faf780] cannot open audio device hw:0,0,0 (Device or resource busy)
hw:0,0,0: Input/output error

为什么会有这个错呢,这就要讲到alsa和pulseaudio之间的差别了,如果麦克风被占用,alsa就会报错,pulseaudio则不会(可以创建多实例)。这个时候你需要找到占用的程序将它杀死,我这里是settings程序占用了,我关掉settings就行了。

在这里插入图片描述

到这里还没结束,alsa还有两个参数可以使用。一个是sample_rate(采样率),一个是channels(通道数)。如果你什么参数都不加它就是默认的选项。比如,我这个配置就是48000HZ采样率,双通道。

ffmpeg -f alsa -i hw:0,0,0 -sample_rate 16000 -channels 1 out1.wav

2.pulseaudio

获取方式和alsa略有差别,参数也比alsa丰富些,唯一的问题就是由于通过网络传输,有一定的延时,感受不强烈。

default就是你的默认麦克风,如果你只有一个内置麦克风那就填default就行了ffmpeg -f pulse -i default out1.wav

注意:和alsa不同,它可以多实例同时操作同一个麦克风而不会出现设备占用的问题。

在这里插入图片描述

再有就是pulseaudio的参数问题,支持的比alsa多。
server:从哪个server取数据,一般不填,使用默认即可
name:定义的程序名,默认是libavformat定义
stream_name:定义的流名字,默认是record
sample_rate:采样率,同alsa
channels:通道数,同alsa
frame_size:弃用,填了也不起效果
fragment_size:音频数据分段大小,这个参数影响延迟
wallclock:和PTS相关,默认是1

ffmpeg -f pulse -i default -sample_rate 16000 -channels 1 out1.wav

2.Windows

这里介绍一种基于dshow架构的多媒体系统,这个东西在Windows10Windows11中已经不被巨硬建议使用了,但是仍然属于可用状态。

1.dshow

查看所有可用的声音设备ffmpeg -list_devices true -f dshow -i dymmylibpostproc    55.  9.100 / 55.  9.100
[dshow @ 00000260fad9b880] DirectShow video devices (some may be both video and audio devices)
[dshow @ 00000260fad9b880]  "Integrated Webcam"
[dshow @ 00000260fad9b880]     Alternative name "@device_pnp_\\?\usb#vid_0c45&pid_671f&mi_00#6&205508db&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global"
[dshow @ 00000260fad9b880] DirectShow audio devices
[dshow @ 00000260fad9b880]  "麦克风阵列 (英特尔® 智音技术)"
[dshow @ 00000260fad9b880]     Alternative name "@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{B6D36105-4B01-4CF8-A2A8-9AF88D902594}"
[dshow @ 00000260fad9b880]  "立体声混音 (2- Realtek(R) Audio)"
[dshow @ 00000260fad9b880]     Alternative name "@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{6FA30750-4E01-41B2-BAD1-FFC68DAFE0E3}"

从上面可以看出来我有两个设备,一个叫立体声混音,还有一个是英特尔智音技术。这里多说一句英特尔智音技术里面有些降噪算法,效果还可以;立体声混音效果就不如这个英特尔智音技术了,噪音比较明显。

ffmpeg -f dshow -i audio="@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{B6D36105-4B01-4CF8-A2A8-9AF88D902594}" out1.wav

注意:用法和Ubuntu差别较大!

同样的,也不知道是不是Windows天然自带buff,参数比Linux多很多,这里列举一部分。
sample_rate:采样率,同Linux
sample_size:采样位数
channels:通道数,同Linux
list_devices:显示可用设备,上面有,Linux该命令无效
list_options:显示设备配置,Linux该命令无效
audio_buffer_size:以毫秒计的缓存大小,和Linux的意思差不多,影响延迟因素

二、代码

main.cpp

#include <iostream>
#include <cstdio>
#include <fstream>extern "C" {
#include <libavformat/avformat.h>
#include <libavdevice/avdevice.h>
}int main() {av_register_all();//ffmpeg 3.x versionavdevice_register_all();AVFormatContext *fmt_ctx = nullptr;AVInputFormat *input_fmt = av_find_input_format("pulse"); // 音频设备的输入格式,如alsa、pulse等const char *dev_name = "default"; // microphone device nameAVDictionary *format_opts = nullptr;//set stream format optionsav_dict_set(&format_opts, "sample_rate", "16000", 0);//set audio sampleav_dict_set(&format_opts, "channels", "1", 0);//set audio channelav_dict_set(&format_opts, "fragment_size", "25600", 0);//set audio fragment size// open audio deviceif (avformat_open_input(&fmt_ctx, dev_name, input_fmt, &format_opts) != 0) {printf("can't open input device!\n");if (format_opts)av_dict_free(&format_opts);return -1;}if (format_opts)av_dict_free(&format_opts);//Output Info---printf("---------------- File Information ---------------\n");av_dump_format(fmt_ctx, 0, dev_name, 0);printf("-------------------------------------------------\n");// find audio stream infoif (avformat_find_stream_info(fmt_ctx, nullptr) < 0) {printf("can't get audio stream info!\n");return -1;}int audio_stream_idx = -1;// find audio stream indexfor (int i = 0; i < fmt_ctx->nb_streams; i++) {if (fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {audio_stream_idx = i;break;}}if (audio_stream_idx == -1) {printf("can't find audio stream index!\n");return -1;}//write pcm datastd::ofstream ofs("../audio/test.pcm");AVPacket packet;while (av_read_frame(fmt_ctx, &packet) >= 0) {if (packet.stream_index == audio_stream_idx) {std::cout << "packet size: " << packet.size << std::endl;std::cout << "packet duration: " << packet.duration << std::endl;ofs.write((char *) packet.data, packet.size);ofs.flush();}av_packet_unref(&packet);}avformat_close_input(&fmt_ctx);ofs.close();return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(read_microphone)set(CMAKE_CXX_STANDARD 11)find_package(PkgConfig REQUIRED)pkg_check_modules(ffmpeg REQUIRED IMPORTED_TARGET  libavformat libavutil libavdevice libavcodec)add_executable(${PROJECT_NAME} main.cpp)target_link_libraries(${PROJECT_NAME} PkgConfig::ffmpeg)

简单源代码


总结

1、方法不止这些,还需要继续研究。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/783241.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android 12系统源码_多窗口模式(一)和多窗口模式相关方法的调用顺序

前言 从 Android 7.0 开始&#xff0c;Google 推出了一个名为“多窗口模式”的新功能&#xff0c;允许在设备屏幕上同时显示多个应用&#xff0c;多窗口模式允许多个应用同时共享同一屏幕&#xff0c;多窗口模式&#xff08;Multi Window Supports&#xff09;目前支持以下三种…

我的C++奇迹之旅相遇:支持函数重载的原理

文章目录 &#x1f4dd;前言&#x1f320; C支持函数重载的原理&#xff1a;名字修饰(name Mangling)&#x1f309;不同编译器不同函数名修饰规则 &#x1f320;Windows下名字修饰规则&#x1f6a9;总结 &#x1f4dd;前言 函数重载概念 函数重载&#xff1a;是函数的一种特殊…

大模型面试准备(九):简单透彻理解MoE

节前&#xff0c;我们组织了一场算法岗技术&面试讨论会&#xff0c;邀请了一些互联网大厂朋友、参加社招和校招面试的同学&#xff0c;针对大模型技术趋势、大模型落地项目经验分享、新手如何入门算法岗、该如何备战、面试常考点分享等热门话题进行了深入的讨论。 合集在这…

Linux(CentOS7)安装 MySQL8

目录 下载 上传 解压 创建配置文件 初始化 MySQL 服务 启动 MySQL 服务 连接 MySQL 创建软链接 下载 官方地址&#xff1a; MySQL :: Download MySQL Community Serverhttps://dev.mysql.com/downloads/mysql/选择版本前需先看一下服务器的 glibc 版本 ldd --versio…

js录制本地摄像头下载mp4和转file文件流

前端获取本地摄像头和麦克风并录制为mp4导出其实很简单&#xff0c;只是可能你不太了解相关的知识点&#xff0c;我已经在项目中实战过。 前端获取本地摄像头麦克风&#xff0c;并录制视频 export class VideoRecording { // 录视频mediaRecorder: MediaRecorder | null;strea…

浏览器工作原理与实践--垃圾回收:垃圾数据是如何自动回收的

在上一篇文章中&#xff0c;我们提到了JavaScript中的数据是如何存储的&#xff0c;并通过例子分析了原始数据类型是存储在栈空间中的&#xff0c;引用类型的数据是存储在堆空间中的。通过这种分配方式&#xff0c;我们解决了数据的内存分配的问题。 不过有些数据被使用之后&am…

【PCB专题】案例:Allegro怎么1:1在纸上打印出PCB板

首先我们要知道为什么我们需要1:1打印出PCB板? 为什么需要1:1打印 一般我们要1:1打印出来这个功能是在新画的器件封装验证、首板结构配合检查、多个板卡互连验证等情况下使用: 在新画了一个器件封装时,如果我们手上有实物,那么通过1:1打印出来后可以与实物器件交叉对比…

Web框架开发-Django-Form组件归类

一、Form类 创建Form类时,注意涉及到【字段】和【插件】,字段用于对用户请求数据的验证,插件用于生成HTML; 1、Django内置字段如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 …

CVE-2023-38408漏洞修复 - 升级openssl和openssh

CVE-2023-38408 OpenSSH 代码问题漏洞修复 - 升级openssl和openssh ※ 重要说明&#xff1a; 1、升级后会导致无法用ssh远程登录&#xff0c;提示“Permission denied, please try again.” 2、解决方案请查看本章节【三、解决升级后无法用ssh远程登录】 目录 CVE-2023-38408 O…

使用Docker搭建NZBGet

NZBGet是一款高效的NZB下载客户端&#xff0c;它支持使用NZB文件来自动下载网络上的文件&#xff0c;特别是BT种子文件。NZBGet能够与多个索引器和下载管理器&#xff08;如Sonarr、Radarr、SABnzbd等&#xff09;集成&#xff0c;提供稳定、快速且易于管理的下载体验。 使用D…

代码随想录算法训练营第39天| 738.单调递增的数字、968.监控二叉树

738.单调递增的数字 题目链接&#xff1a;单调递增的数字 题目描述&#xff1a;当且仅当每个相邻位数上的数字 x 和 y 满足 x < y 时&#xff0c;我们称这个整数是单调递增的。 给定一个整数 n &#xff0c;返回 小于或等于 n 的最大数字&#xff0c;且数字呈 单调递增 。 解…

WebScraper网页数据爬取可视化工具使用(无需编码)

前言 Web Scraper 是一个浏览器扩展&#xff0c;可以实现无需编码即可爬取网页上的数据。只需按照规则进行配置&#xff0c;即可实现一键爬取导出数据。 安装 进入Google应用商店安装此插件&#xff0c;安装步骤如下&#xff1a; 进入Google应用商店需要外网VPN才能访问&…

C#基础复习

【namespace】 命名空间 。net有众多类&#xff0c;全放一起&#xff0c;无法快速检索到需要的类。 所以用【点】来区分&#xff0c;注意【点】不是包含关系。 解决类重名问题时&#xff0c;要用完全限定名来区分。【完整命名空间路径】 配合引用&#xff1a; 【字段】 类内部…

Android 中 调试和减少内存错误

Android 中 调试和减少内存错误 ASan 概述 官网连接&#xff1a; https://developer.android.com/ndk/guides/asan?hlzh-cn ASan API 27开始HWASan&#xff08;替换AScan&#xff09; 从 NDK r21 和 Android 10&#xff08;API 级别 29&#xff09;开始适用于 64 位 Arm 设…

微服务demo(三)nacosfeign

一、feign使用 1、集成方法 1.1、pom consumer添加依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId><version>2.2.6.RELEASE</version></dependency&…

WEB APIS知识点案例总结

随机点名案例 业务分析: 点击开始按钮随机抽取数组中的一个数据,放到页面中点击结束按钮删除数组当前抽取的一个数据当抽取到最后一个数据的时候,两个按钮同时禁用(只剩最后一个数据不用抽了) 核心:利用定时器快速展示,停止定时器结束展示 <!DOCTYPE html> <html…

智慧公厕产品的特点、应用场景

随着城市化进程的加速和智能科技的不断发展&#xff0c;智慧公厕作为城市管理的重要组成部分&#xff0c;逐渐成为了现代城市的一道靓丽风景线。它的特点和应用场景备受人们关注和喜爱。 智慧公厕的特点有哪些呢&#xff1f;首先&#xff0c;它智能化的设备和感应技术为其特点…

华为昇腾认证考试内容有哪些

华为昇腾认证考试的内容主要包括理论知识和实践操作两部分。 在理论知识部分&#xff0c;考生需要掌握昇腾计算的基础知识&#xff0c;包括昇腾计算平台的架构、性能特点、应用场景等。此外&#xff0c;还需要深入理解昇腾AI框架、算子开发、模型优化等相关技术原理和应用方法…

《操作系统导论》第14章读书笔记:插叙:内存操作API

《操作系统导论》第14章读书笔记&#xff1a;插叙&#xff1a;内存操作API —— 杭州 2024-03-30 夜 文章目录 《操作系统导论》第14章读书笔记&#xff1a;插叙&#xff1a;内存操作API1.内存类型1.1.栈内存&#xff1a;它的申请和释放操作是编译器来隐式管理的&#xff0c;所…

Xcode删除原本的Git,再添加新的git

本文参考&#xff1a;Xcode怎么删除原本git,在重新设置新的git地址_ios xcode 删除原本git-CSDN博客 开发中会有一个问题。Xcode项目A 提交到Git服务器server1&#xff0c;此时项目A内部已经存在一个Git文件&#xff0c;与server1相关联。 此时你想将项目A提交到 另一个Git…