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 分钟就能录到能用的音频。

相关推荐
DogDaoDao1 小时前
VVC 帧间编码分区加速方法
深度学习·音视频·视频编解码·h266·vvc·预测编码·帧间编码
chushiyunen2 小时前
神雕武功排名
windows
酩酊仙人2 小时前
Windows Server部署django
windows·django·sqlite
音视频工程实战2 小时前
音频元数据标准化设计:封面、章节、时间戳全链路统一存储规范
音视频
蓝斯49717 小时前
从.到实现一个Windows上的虚拟hid键盘设备
windows·单片机·计算机外设
程序员老陆18 小时前
从零写一个 FFmpeg 播放器:架构设计远比“解码显示”复杂
ffmpeg·音视频·播放器
kuinnebula20 小时前
MP4音频帧定位与提取
音视频
CODER030420 小时前
封装忽律底层硬件差异的自定义系统
windows·microsoft
软件资深者21 小时前
Windows10、11轻松设置 使用教程:把Windows繁杂的设置集成到一个面板,关广告/关更新/调隐私全搞定,系统设置工具新手 5 分钟上手(2026)
windows