FFmpeg6 在 Windows 打开麦克风并录成 PCM:不走 Qt Multimedia,也不碰 WASAPI

目录

[一、Windows 下 FFmpeg 抓音频的唯一正解:dshow](#一、Windows 下 FFmpeg 抓音频的唯一正解:dshow)

[二、先确认你的 FFmpeg 能行](#二、先确认你的 FFmpeg 能行)

三、最简命令行版

[四、C/C++(FFmpeg 6 API)最小录音流程](#四、C/C++(FFmpeg 6 API)最小录音流程)

核心思路

[五、完整可编译示例代码(Windows / FFmpeg 6)](#五、完整可编译示例代码(Windows / FFmpeg 6))

[六、PCM 参数是谁决定的?](#六、PCM 参数是谁决定的?)

[七、为什么不用 swr_convert?](#七、为什么不用 swr_convert?)

[八、常见坑(Windows + FFmpeg 专属)](#八、常见坑(Windows + FFmpeg 专属))

中文设备名乱码

打开成功但没数据

录出来全是杂音

九、进阶路线(你迟早会问)

十、总结


在 Windows 系统中使用 FFmpeg 录制麦克风并将其输出为 PCM(脉冲码调制)格式,你可以按照以下步骤操作。首先,确保你已经安装了 FFmpeg。如果没有安装,可以从 FFmpeg官网 下载适用于 Windows 的版本并安装。

很多人以为 FFmpeg 只能解封装、播视频,其实它原生就能抓 Windows 麦克风 ------而且不依赖 Qt Multimedia、不碰 Win32 Audio API,一条 dshow设备链就能干活。

今天这篇,目标是:

FFmpeg 6

Windows

打开默认麦克风

录 N 秒

直接写 裸 PCM(16bit / 44.1kHz / 双声道)

不整花活,能拷就能跑。


一、Windows 下 FFmpeg 抓音频的唯一正解:dshow

FFmpeg 在 Windows 支持三种音频输入:

方式 现状
dshow 主流、稳定
wasapi 更底层,采样率诡异
wavein 老古董

麦克风录音 = DirectShow = dshow


二、先确认你的 FFmpeg 能行

复制代码
ffmpeg -hide_banner -devices

看到 D后有 dshow,说明 libavdevice 编进去了:

复制代码
Devices:
 D. = Demuxer
 ---
 D  dshow           DirectShow input device

再看看有哪些麦克风:

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

输出里找:

复制代码
[dshow @ xxx] "麦克风阵列 (适用于数字麦克风的英特尔® 智音技术)" (audio)

名字要原样复制,中文也没事,但要引号包住。


三、最简命令行版

复制代码
ffmpeg -f dshow -i audio="Microphone (Realtek Audio)" ^
-t 5 ^
-f s16le -ar 44100 -ac 2 ^
out.pcm

用 Audacity 打开 PCM:

  • Signed 16-bit PCM

  • Little Endian

  • 44100 Hz

  • Stereo

能听 → 代码一定行


四、C/C++(FFmpeg 6 API)最小录音流程

核心思路

复制代码
av_find_input_format("dshow")
↓
avformat_open_input(audio=...)
↓
av_read_frame → AVPacket
↓
直接写 packet.data(PCM)

dshow 默认输出就是 交错 PCM packet,不用 filter 也能直接落盘。


五、完整可编译示例代码(Windows / FFmpeg 6)

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

int main()
{
    AVFormatContext* fmt_ctx = nullptr;
    AVInputFormat* ifmt = av_find_input_format("dshow");

    const char* dev_name = "audio=Microphone (Realtek Audio)";

    if (avformat_open_input(&fmt_ctx, dev_name, ifmt, nullptr) < 0) {
        printf("open mic failed\n");
        return -1;
    }

    FILE* fp = fopen("mic.pcm", "wb");

    AVPacket pkt;
    int count = 0;
    while (av_read_frame(fmt_ctx, &pkt) >= 0 && count < 220) { // ~5s @44k
        fwrite(pkt.data, 1, pkt.size, fp);
        av_packet_unref(&pkt);
        count++;
    }

    fclose(fp);
    avformat_close_input(&fmt_ctx);
    return 0;
}

六、PCM 参数是谁决定的?

dshow 默认给你:

参数
sample_fmt s16
rate 44100
ch 2
layout stereo
packing interleaved

packet.data 就是裸 PCM

如果你想改:

复制代码
AVDictionary* opts = nullptr;
av_dict_set(&opts, "sample_rate", "48000", 0);
av_dict_set(&opts, "channels", "1", 0);
avformat_open_input(&fmt_ctx, dev_name, ifmt, &opts);

有些声卡 只认特定组合,失败就回退默认。


七、为什么不用 swr_convert?

你现在是:

复制代码
麦克风 → dshow → PCM packet → 文件

链路里:

  • 无 resample

  • 无 latency

  • CPU ≈ 0

只有两种理由碰 swresample:

  1. 要 float / s32

  2. 重采样成 AAC / OPUS

否则:裸写文件就行


八、常见坑(Windows + FFmpeg 专属)

中文设备名乱码

UTF-8 源码 + MSVC / mingw-w64 都能过

audio="...",别手敲空格


打开成功但没数据

  • 麦克风被独占(Teams / Chrome)

  • 隐私设置没开"允许桌面应用访问麦克风"


录出来全是杂音

  • Audacity 声道数选错

  • s32le打开 s16le


九、进阶路线

需求 下一步
边录边播 abuffer → aformat → sink
存 WAV 写 44-byte header
实时推流 encode opus → RTP
Qt UI QThread + av_read_frame
低延迟 wasapi+ exclusive

十、总结

FFmpeg 6 + Windows 麦克风 = libavdevice + dshow + avformat_open_input + av_read_frame,PCM 直接落盘;不折腾 WASAPI、不碰 WinMM,5 分钟就能录到能用的音频。

相关推荐
易点云徐源2 小时前
(已解决)Foxmail打开后2分钟左右崩溃
windows·foxmail
其实防守也摸鱼2 小时前
每天一个知识点——RCE漏洞
运维·服务器·数据库·windows·安全·github·漏洞
世岩清上3 小时前
展厅数字内容同质化严重,怎样打造专属叙事风格?
大数据·前端·javascript·人工智能·html·音视频·展厅改造
江湖人称菠萝包3 小时前
【Windows】《深入浅出Windows API程序设计:核心编程篇》笔记-Chapter6-动态链接库
windows·笔记
LCG元3 小时前
STM32F407 I2S驱动WM8978音频播放实战:PLLI2S时钟整定、DMA双缓冲防爆音与WAV采样率实测
stm32·嵌入式硬件·音视频
jbk33114 小时前
PixiuCut「视频批量分割」支持智能镜头分割、按时长、按数量分割,可定义最小时长避免无效片段等多可选参数可设置
人工智能·音视频·剪辑软件·剪映自动化软件
投票竞赛4 小时前
作品投票版权注意事项,线上评选上传图片视频须知
python·音视频
2601_962364975 小时前
重装系统后,Windows Hello 为什么要重新录入人脸?
windows·安全·电脑
水饺编程5 小时前
第5章,[Win32 章节] :在平面直角坐标系中描点
c语言·c++·windows·visual studio
三玖诶7 小时前
DeepSeek Launcher:内置 Node.js,为什么首次启动仍需要网络?
windows·开源·deepseek