Windows使用ffmpeg获取麦克风数据

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

文章目录


前言

最近突发奇想,既然ffmpeg那么好用,为什么不能拿到Windows上来用呢?由于ffmpeg官方提供的是二进制文件,不是开发库。之前尝试过很多次移植都失败了,当我准备放弃的时候,突然一次意外发现让我重燃希望。所以ffmpeg在windows上到底好不好用呢?让我们拭目以待吧。

OS:WIndows11

ffmpeg:7.0


一、安装MSYS2

今天说的这个方法可以说依赖这个环境,而环境的安装我已经在另一篇文章中说过了,这里就不再赘述了。

Windows上MSYS2的安装和使用

二、开始配置

这种方法需要安装ffmpeg,使用mingw64环境。

bash 复制代码
pacman -S mingw-w64-x86_64-ffmpeg

三、测试代码

绝大多数代码都可以和Linux通用,只有细节部分必须分开来。我们在Linux上可以使用alsapulse来获取声音系统;在Windows上可以使用dshow来获取声音系统,windows系统上貌似ffmpeg只支持dshow这一种方式。

ffmpeg_windows.cpp

cpp 复制代码
#include <iostream>
#include <cstdio>

extern "C" {
#include <libavformat/avformat.h>
#include <libavdevice/avdevice.h>
}


/**
 * @author arnold
 * @brief use alsa and default device
 * */
void read_microphone() {
//    av_version_info();
//    av_register_all();//ffmpeg 3.x version
    avdevice_register_all();
    AVFormatContext *fmt_ctx = nullptr;
    auto *input_fmt = const_cast<AVInputFormat *>(av_find_input_format("dshow")); // 音频设备的输入格式,如alsa、pulse等
    const char *dev_name = R"(audio=麦克风阵列 (英特尔® 智音技术))"; // 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, "sample_size", "16", 0);//set audio sample
//    av_dict_set(&format_opts, "channels", "1", 0);//set audio channel
//    av_dict_set(&format_opts, "fragment_size", "256", 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;
    }
    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;
    }
    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;
    }
    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;
        }
        av_packet_unref(&packet);
    }
    avformat_close_input(&fmt_ctx);
}

int main() {
    read_microphone();
    return 0;
}

CmakeLists.txt

bash 复制代码
cmake_minimum_required(VERSION 3.10)
project(read_microphone)

set(CMAKE_CXX_STANDARD 11)

if (UNIX)
	message(STATUS "OS is UNiX")
	find_package(PkgConfig REQUIRED)
	pkg_check_modules(ffmpeg_lib REQUIRED IMPORTED_TARGET libavformat libavutil libavdevice libavcodec)
	add_executable(ffmpeg_unix ffmpeg_unix.cpp)
	target_link_libraries(ffmpeg_unix PkgConfig::ffmpeg_lib)
	pkg_check_modules(alsa_lib REQUIRED IMPORTED_TARGET alsa)
	add_executable(alsa_bin alsa_lib.cpp)
	target_link_libraries(alsa_bin PkgConfig::alsa_lib)
	add_executable(pcm_2_wav pcm_2_wav.cpp)
	target_link_libraries(pcm_2_wav PkgConfig::alsa_lib PkgConfig::ffmpeg_lib)
elseif (WIN32)
	message(STATUS "OS is Windows")
	find_package(PkgConfig REQUIRED)
	pkg_check_modules(ffmpeg_lib REQUIRED IMPORTED_TARGET libavformat libavutil libavdevice)
	add_executable(ffmpeg_windows ffmpeg_windows.cpp)
	target_link_libraries(ffmpeg_windows PkgConfig::ffmpeg_lib)
endif ()

这种模式下Cmake不需要进行任何更改,和Linux上是一模一样的。唯二的差别就是input_format必须选dshowdevice必须是确切的名字才行。这一点和Linux不一样,Linux上可以选default,就是你勾选的默认麦克风,这一点差别还蛮大的。

至于怎么查看Windows上的麦克风设备,请执行以下的命令:

bash 复制代码
ffmpeg -f dshow -list_devices true -i dummy


[dshow @ 000001765c475840] "HP HD Camera" (video)
[dshow @ 000001765c475840]   Alternative name "@device_pnp_\\?\usb#vid_30c9&pid_0009&mi_00#6&23fdf108&1&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global"
[dshow @ 000001765c475840] "麦克风阵列 (英特尔® 智音技术)" (audio)
[dshow @ 000001765c475840]   Alternative name "@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{8730737C-26AF-44E6-A535-1A478CFB2509}"
[dshow @ 000001765c475840] "麦克风 (ToDesk Virtual Audio)" (audio)
[dshow @ 000001765c475840]   Alternative name "@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{C8461EAB-1635-4144-BE61-6BDC555C9B16}"

括号里带(audio)都是麦克风设备,带(video)的都是摄像头设备。

命令行测试麦克风:

bash 复制代码
ffmpeg -f dshow -i audio="麦克风阵列 (英特尔® 智音技术)" -f null -

#或
ffmpeg -f dshow -i audio="@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{8730737C-26AF-44E6-A535-1A478CFB2509}" -f null -

同样的代码里填这两种名字都行,就是不能用default

四、缺陷

感觉也不算缺陷,但是它就是不支持,看我代码里注释掉的代码。sample_rate可以设置但是不能随便设置,比如32000HZ44100HZ48000HZ都是可以的,但是有些需要的16000HZ就不行。

下面的命令报错:

bash 复制代码
ffmpeg -sample_rate 16000 -f dshow -i audio="@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{8730737C-26AF-44E6-A535-1A478CFB2509}" -f null -

下面的命令可以:

bash 复制代码
ffmpeg -sample_rate 32000-f dshow -i audio="@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{8730737C-26AF-44E6-A535-1A478CFB2509}" -f null -

实际上WIndows原生的获取麦克风声音的方法也不是都支持随便设置采样率的,感兴趣的可以试试。

问题是同样的硬件alsa和pulse都支持设置16000的采样率,会给出警告但不会报错。虽说,16000的采样率绝大多数场景用不到,但是有些声音识别的算法就用16000的采样率,真的是头疼。如果你知道方法,麻烦你在回复里告诉我,我感激不尽。

当然,也可以通过后期处理来转化解决。毕竟转换声音没有转换图像那么消耗性能。


总结

1、美中不足,但是对于快速开发足够了,毕竟我觉得ffmpeg还是比自带的好用一些,不知道是不是错觉。

相关推荐
凯子坚持 c24 分钟前
CANN 性能剖析实战:从原始事件到交互式火焰图
windows·microsoft
开开心心就好1 小时前
发票合并打印工具,多页布局设置实时预览
linux·运维·服务器·windows·pdf·harmonyos·1024程序员节
獨枭1 小时前
PyCharm 跑通 SAM 全流程实战
windows
仙剑魔尊重楼2 小时前
音乐制作电子软件FL Studio2025.2.4.5242中文版新功能介绍
windows·音频·录屏·音乐·fl studio
PHP小志2 小时前
Windows 服务器怎么修改密码和用户名?账户被系统锁定如何解锁
windows
凉辰3 小时前
使用uni.createInnerAudioContext()播放指定音频(踩坑分享功能)
开发语言·javascript·音视频
AI资源库3 小时前
Remotion 一个用 React 程序化制作视频的框架
人工智能·语言模型·音视频
专注VB编程开发20年4 小时前
vb.net datatable新增数据时改用数组缓存
java·linux·windows
仙剑魔尊重楼4 小时前
专业音乐制作软件fl Studio 2025.2.4.5242中文版新功能
windows·音乐·fl studio
永远都不秃头的程序员(互关)4 小时前
基于CANN的ops-signal仓库实现AIGC音频生成中的动态窗函数融合优化——从STFT预处理到端到端低延迟合成
aigc·音视频