
系统级虚拟麦克风是怎么凭空出现的obs-virtual-cam 音频链路拆解与三步落地【免费下载链接】obs-virtual-camobs-studio plugin to simulate a directshow webcam项目地址: https://gitcode.com/gh_mirrors/ob/obs-virtual-cam元描述obs-virtual-cam 插件能把 OBS 的音频输出包装成系统级虚拟麦克风 OBS-Audio。本文从 DirectShow 注册讲到共享内存队列把声音为什么能进出系统设备列表讲明白并给出可直接照抄的注册与排错步骤让你 20 分钟用上处理过的声音。把 OBS 里混好的声音变成任何软件都能直接选的麦克风你其实只需要做两件事点一下启动输出然后在会议软件里把输入设备换成 OBS-Audio。而系统这边悄悄地替你完成了另外三件事——把一个 DirectShow 过滤器伪装成录音设备、在 OBS 进程与过滤器之间铺一条数据传输通道、再把两边的时钟对齐。这篇文章要拆的就是这两件事背后、系统替你做的三件事。虚拟麦克风的全部秘密藏在一行注册命令、一块共享内存和一个取数循环里。系统凭什么认识 OBS-Audio一次注册一个户口先回答最基础的问题一个 OBS 插件凭什么能在微信、Teams 的设备列表里多出一个麦克风答案在 DirectShow 的注册机制里。DirectShow 是 Windows 上音视频捕获的事实标准。任何软件在枚举录音设备时都会去系统注册表里查找CLSID_AudioInputDeviceCategory音频输入设备分类和CLSID_VideoInputDeviceCategory视频输入设备分类下的过滤器。obs-virtual-cam 做的第一件事就是在安装时把自己的 DLL 注册进这两个分类——注册那一刻系统设备列表里就多出了OBS-Audio音频和OBS Virtual Cam视频。这个注册动作不在源码里而是一条 regsvr32 命令。32 位和 64 位的 DirectShow 过滤器是分开注册的缺一不可这就是为什么官方文档要求两条都执行。想验证注册有没有成功最快的方法是打开系统声音设置看录制设备里是否出现了 OBS-Audio。注册是立户口但户口的名字只是个壳。真正有意思的是壳里面那个类CVAudio继承自 DirectShow 的CSource扮演源过滤器的角色它内部的CVAudioStream继承CSourceStream负责真正往外吐数据。设备列表里那个 OBS-Audio本质是一个无头无脸的演员它自己不产生任何声音——声音要由 OBS 那边喂进来。一条环形传送带三个角色一个队列OBS 进程和 DirectShow 过滤器各自运行在独立的内存空间里不能直接互相传指针。项目解决这个问题的思路可以想象成一家回转寿司店写端是后厨OBS 的音频回调把数据装进寿司盘放到传送带上。传送带是共享内存一块叫OBSVirtualAudio的命名共享内存用CreateFileMapping创建写端往里写、读端往外取。读端是客人CVAudioStream在传送带上按自己的节奏取盘转成 DirectShow 的媒体样本递给第三方软件。这套环形传送带的容量和位置都在queue_header结构里管理queue_length是传送带上的盘位数write_index是后厨刚放到哪个位置delay_frame是客人应该和写端错开的盘数差。整条链路走一遍就是OBS 音频回调 → 环形队列 OBSVirtualAudio → CVAudioStream 取帧 → 媒体样本 → 会议软件传送带上有个细节值得停下来看延迟缓冲不是玄学是队列自带的物理属性。写端在queue_header里记录了delay_frame读端初始化索引时不会从写指针的位置开始读而是回退延迟帧那么远——相当于客人落座前传送带上已经攒了好几盘菜。这样即使系统调度抖一下、后厨慢半拍客人手里也总有东西可拿不会因为刚好吃完下一盘还没转过来而断音。这正是后面那个延迟滑块参数的来源。相关实现在 核心源码 和 读端实现 里share_queue_init_index那段回退索引的逻辑就是客人怎么选第一盘的答案。只认 44.1kHz 一种格式不商量反而最稳音频设备必须向系统自报家门自己支持什么格式。obs-virtual-cam 的答案非常硬气——我只支持一种没有第二种。在 虚拟音频设备 里规格被写成了三个常量AUDIO_BUFFER_SIZE 4096 // 单个媒体样本的缓冲区字节数 SAMPLE_RATE 44100 // 采样率 SAMPLE_SIZE 176400 // 每秒字节数 44100 × 2声道 × 2字节GetMediaType()里把这套规格填进WAVEFORMATEX双声道、44.1kHz、每帧 4 字节2 声道 × 16 位/8、16 位量化、标准 PCM。而GetStreamCaps()更绝——它用AUDIO_STREAM_CONFIG_CAPS声明能力范围时把最小值和最大值都锁定成同一个值等于告诉系统别讨价还价就这一种。如果你正在用 48kHz 的工程也别慌OBS 这头会自动降格。在 输出侧 的virtual_output_start()里插件主动声明了格式转换conv.format AUDIO_FORMAT_16BIT; conv.samples_per_sec 44100; conv.speakers SPEAKERS_STEREO; obs_output_set_audio_conversion(out_data-output, conv);也就是说无论 OBS 内部跑的是什么采样率喂给虚拟麦克风之前都会被统一转成 44.1kHz/16bit/立体声。两头对表中间才不会出现格式对不上导致的无声或杂音。代价是想用 48kHz 得改源码重新编译——对普通用户来说这反而是省心因为永远不用担心设备不支持这种采样率。FillBuffer一帧音频的三种命运DirectShow 的拉流模型下第三方软件会不停调用CVAudioStream::FillBuffer()来讨数据。这个方法像一根定海神针它让每一帧音频都有明确的去处——好的、差的、最坏的三种情况各有一套剧本。实现见 音频源过滤器和推流逻辑。剧本一正常取到帧。从队列里取出最多 4096 字节紧接着处理时间戳。这里维护了两条时间线obs_start_ts是 OBS 侧的首帧时间戳dshow_start_ts是 DirectShow 侧的首帧时间戳。首帧到达时把两者对齐之后每一帧的播放时刻都按dshow_start_ts (timestamp - obs_start_ts) / 100推算——相当于两台钟在启动时对了一次表之后各自走各自的但刻度始终一致。第三方软件拿到的音频时间轴就和 OBS 的画面严格对上了。剧本二队列暂时为空。取不到数据时FillBuffer不报错、不返空而是小睡 5 毫秒再试一次。连续重试超过 20 次仍没有数据才判定为断流。在等待期间它把缓冲区memset成零再正常输出——你听到的是一瞬静音而不是刺耳爆音或设备整个消失。宁可给静音也不给噪音这句设计哲学撑起了虚拟麦克风的大部分听感稳定性。剧本三队列明确喊停。只有queue_header-state变成OutputStop对应 OBS 侧停止输出时过滤器才真正断开连接、重置两条时间线等待下一次重新握手。同步超时也不是拍脑袋定的。SetTimeout()会根据队列长度动态换算sync_timeout queue_length * AUDIO_SIZE * 10000000 / 44100 * 4队列越长超时越宽松等于给系统调度留更多余量代价是延迟更高。稳定性与延迟在这里是同一条曲线的两端——理解了这一点后面调参数就不是试错而是心里有数。三步落地注册、启输出、选设备原理讲完了实操其实很短。以管理员身份打开命令提示符执行两条注册命令32 位和 64 位都要regsvr32 C:\Program Files\obs-studio\bin\32bit\obs-virtualsource.dll regsvr32 C:\Program Files\obs-studio\bin\64bit\obs-virtualsource.dll注册成功后控制面板的声音设置里就会出现OBS-Audio。如果你需要多路虚拟摄像头最多 4 路先反注册再带参数重注册regsvr32 /u C:\Program Files\obs-studio\bin\64bit\obs-virtualsource.dll regsvr32 /n /i:2 C:\Program Files\obs-studio\bin\64bit\obs-virtualsource.dll/i:2表示注册 2 路视频过滤器音频过滤器始终固定 1 路。这些命令与说明都能在项目自带的 readme.MD 里找到。接下来两件事缺一不可在 OBS 里启动虚拟输出共享内存的写端必须在线然后在会议软件的声音设置里把麦克风切换为 OBS-Audio。最后是延迟微调——在 OBS 输出设置里有一个延迟帧滑块默认 5 帧可调 0–30 帧。数值越大越稳、延迟越高网络会议建议 1–5 帧本地录屏可以拉到 0。改完记得重启一次输出让配置生效。声音不对沿着链路逐段排查虚拟麦克风出问题时别急着重装先想清楚问题出在哪一段是系统认不出设备注册段、OBS 没在写写端段、还是格式/缓冲不对读端段。按这个顺序查基本不会跑偏现象可能原因处理方式会议软件里选不到 OBS-Audio过滤器未注册或注册不完整用管理员权限重新 regsvr32然后重启会议软件有画面没声音OBS 虚拟输出未启动队列未就绪在 OBS 输出面板确认虚拟输出处于运行中状态声音断断续续、像卡带系统负载高队列缓冲不足调大延迟帧数值关闭后台音视频软件说话对不上口型时间戳基准漂移重启 OBS 输出让两端时间线重新对齐提示采样率不支持第三方软件请求了非 44.1kHz 格式在软件音频设置里强制选 44100Hz排查的锚点其实就一个数据是否一路走通了从 OBS 到会议软件的完整链路。OBS 在跑、队列是 Ready、格式是 44.1kHz/16bit/立体声——这三个点全部确认虚拟麦克风基本不可能出问题。现在去会议的测试麦克风里说句话看到电平跳动的那一瞬间你就已经亲手验收了这条管线DirectShow 给了它户口共享内存给了它通路时间戳给了它节拍。理解这三层之后下次再遇到无声或卡顿你就能顺着这条链路一步步定位而不是卸载重装碰运气。设备多贵不重要重要的是你知道声音正在以 44100 次每秒的节律准确地抵达它该去的地方。【免费下载链接】obs-virtual-camobs-studio plugin to simulate a directshow webcam项目地址: https://gitcode.com/gh_mirrors/ob/obs-virtual-cam创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考