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

news2024/11/26 18:40:27

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

文章目录

  • 前言
  • 一、命令行
    • 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/cards
 0 [PCH            ]: HDA-Intel - HDA Intel PCH
                      HDA 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 dymmy

  libpostproc    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 version
    avdevice_register_all();
    AVFormatContext *fmt_ctx = nullptr;
    AVInputFormat *input_fmt = av_find_input_format("pulse"); // 音频设备的输入格式,如alsa、pulse等
    const char *dev_name = "default"; // microphone device name
    AVDictionary *format_opts = nullptr;//set stream format options
    av_dict_set(&format_opts, "sample_rate", "16000", 0);//set audio sample
    av_dict_set(&format_opts, "channels", "1", 0);//set audio channel
    av_dict_set(&format_opts, "fragment_size", "25600", 0);//set audio fragment size
    // open audio device
    if (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 info
    if (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 index
    for (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 data
    std::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.coloradmin.cn/o/1561094.html

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

相关文章

[Windows]服务注册工具(nssm)

文章目录 官网下载地址百度云下载地址NSSM常用命令 使用场景&#xff1a;例如现在我们想开启自动启动一个Java服务,nginx,node等。 官网下载地址 https://nssm.cc/download 百度云下载地址 链接&#xff1a;https://pan.baidu.com/s/111fkBWIS7CTlWIj80Kc8Sg?pwdanan 提取码…

解码视频流在opengl中的贴图投影计算

解码视频流在opengl中的贴图投影计算 修改顶点着色器cpp 文件放大缩小 我们把视频当成纹理,首先要确定贴入的坐标&#xff0c;原始坐标如下所示 static float vertices[] {// ---- 位置 ---- ---- 颜色 ---- - 纹理坐标 -1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f…

js计算点到直线的距离并使用canvas可视化

使用方程计算 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Distance to Line Visualization</…

题目:小明的背包2(蓝桥OJ 1175)

问题描述&#xff1a; 解题思路&#xff1a; 本题是完全背包模板题&#xff0c;与01背包的不同处在于状态是由小到大转移。 代码&#xff1a; #include <bits/stdc.h> using namespace std; const int N 1e3 9;int dp[N]; // N表示体积int main() {int n, m;cin >…

健身运动蓝牙耳机什么牌子好?五大业内顶级优品推荐

在当下这个健身热潮席卷的时代&#xff0c;越来越多的人开始注重运动与健康&#xff0c;而音乐作为运动时的最佳伴侣&#xff0c;无疑为锻炼过程增添了不少乐趣。为了在运动时享受音乐&#xff0c;一款优质的健身运动蓝牙耳机显得尤为重要&#xff0c;市场上各大品牌纷纷推出自…

每日面经分享(SpringBoot part4:Controller层)

SpringBoot Controller层的作用 a. 请求映射&#xff1a;Controller层使用注解&#xff08;如RequestMapping、GetMapping、PostMapping等&#xff09;将HTTP请求映射到相应的方法上。这些方法根据URL路径、请求方法、请求参数等来决定要执行的操作。 b. 参数解析&#xff1a;C…

KUKA机器人更改时间和HMI最小化设置

在使用 KUKA 机器人时&#xff0c;示教器上左边有个“表”的图标&#xff0c;点一下就会显示时间。但一般不准&#xff0c;想要更改时间可以通过HMI最小化后进行更改设置。更改时间需要将示教器界面最小化&#xff0c;也就是进入Windows 界面。通过以下步骤可以进行设置&#x…

ES学习日记(二)-------集群设置

上一节写了elasticsearch单节点安装和配置,现在说集群,简单地说就是在多台服务器上搭建单节点,在配置文件里面增加多个ip地址即可,过程同单节点部署,主要说集群配置 注意:不建议在之前单节点es上修改配置为集群,据说运行之后会生成很多文件,在单点基础上修改容易出现未知问题,…

微信支付平台与微信服务号关联配置要点

目录 JSAPI支付 前期资料及相关准备 申请微信服务号 服务号配置要点 微信认证 基本配置 功能设置 申请微信支付号 支付号配置要点 设置操作密码 API安全 开发设置 与服务号关联 小结 JSAPI支付 我们的开发应用场景以JSAPI支付为举例&#xff0c;这也是常用的一…

基于Java+SpringBoot+Mybaties+layui+Vue+elememt 实习管理系统 的设计与实现

一.项目介绍 前台功能&#xff1a;用户进入系统可以实现首页&#xff0c;系统公告&#xff0c;个人中心&#xff0c;后台管理等功能进行操作 后台由管理员&#xff0c;实习单位&#xff0c;教师和学生&#xff0c;主要功能包括首页&#xff0c;个人中心&#xff0c;班级管理&am…

Python多任务处理---多线程

引入 生活中&#xff0c;我们在电脑上打开了一个word, 这个word对操作系统来说就是一个进程。我们在进行word操作的时候&#xff0c;比如在你打字的时候&#xff0c;该word同时可以进行文字检查。发现了没&#xff0c;在同一个进程中&#xff0c;我们也可以进行同时操作。…

编程语言 MoonBit 本周有超多重磅更新等你来探索:expect 测试添加 inspect 函数,还有……

MoonBit 更新 1. expect 测试添加 inspect 函数 expect 测试添加针对 Show 接口的 inspect 函数&#xff0c;签名如下&#xff1a; pub fn inspect(obj: Show,~content: String "",~loc: SourceLoc _,~args_loc: ArgsLoc _ ) -> Result[Unit, String]⚠️ 此…

【javascript】Promise的介绍和使用方法

简言 什么是Promise&#xff1f; Promise 是一个对象&#xff0c;它代表了一个异步操作的最终完成或者失败。它可以进行链式调用、错误捕捉等操作&#xff0c;轻松解决经典的回调地狱问题&#xff0c;可以像编写同步代码那样&#xff0c;从容、简洁、优雅地实现高复杂度的异步…

【算法分析与设计】丑数 | |

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;算法分析与设计 ⛺️稳中求进&#xff0c;晒太阳 题目 给你一个整数 n &#xff0c;请你找出并返回第 n 个 丑数 。 丑数 就是质因子只包含 2、3 和 5 的正整数。 示例 示例 1&#xff1a;…

智慧城市数字孪生,综合治理一屏统览

现代城市作为一个复杂系统&#xff0c;牵一发而动全身&#xff0c;城市化进程中产生新的矛盾和社会问题都会影响整个城市系统的正常运转。智慧城市是应对这些问题的策略之一。城市工作要树立系统思维&#xff0c;从构成城市诸多要素、结构、功能等方面入手&#xff0c;系统推进…

Python基础之Class类的定义、继承、多态

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、class类1.类属性操作&#xff08;增删改&#xff09;2.类方法操作 二、类的继承1、语法2、方法重写 二、类的多态 一、class类 、三部分组成 1、类名&#xff…

makefile第五讲

更多精彩内容在公众号。 书写命令 每条规则中的命令和操作系统 Shell 的命令行是一致的。 make 会按顺序一条一条的执行命令&#xff0c; 每条命令的开头必须以[Tab]键开头&#xff0c; 除非&#xff0c;命令是紧跟在依赖规则后面的分号后的。在命令行之间中的空格或是空行会被…

FreeRTOS系列补充1:重点记忆知识点

1、FreeRTOS的调度策略、内部原理 FreeRTOS采用抢占式优先级调度策略。任务根据其优先级进行调度&#xff0c;优先级高的任务会抢占优先级低的任务的执行权。FreeRTOS使用任务控制块&#xff08;Task Control Block&#xff0c;简称TCB&#xff09;来管理任务信息和状态。调度…

好展位、抢先订!2024第19届亚洲泳池SPA展览会|广州游池展

邀请函/2024第19届亚洲泳池SPA博览会 时间&#xff1a;2024年5月10日--12日 地点&#xff1a;广州中国进出口商品交易会展馆 主办单位&#xff1a;广东省沐浴休闲协会 广东省水处理技术协会 广东鸿威国际会展集团有限公司 支持单位:国际桑拿协会 韩国SPA协会 亚洲水疗康体促…

leecode 331 |验证二叉树的前序序列化 | gdb 调试找bug

计算的本质是数据的计算 数据的计算需要采用格式化的存储&#xff0c; 规则的数据结果&#xff0c;可以快速的按照指定要求存储数据 这里就不得不说二叉树了&#xff0c;二叉树应用场景真的很多 本题讲的是&#xff0c;验证二叉树的前序序列化 换言之&#xff0c;不采用建立树的…