ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

为什么你在 OBS 里调好的声音,一进别的软件就“打回原形“

为什么你在 OBS 里调好的声音,一进别的软件就“打回原形“ 为什么你在 OBS 里调好的声音一进别的软件就打回原形【免费下载链接】obs-virtual-camobs-studio plugin to simulate a directshow webcam项目地址: https://gitcode.com/gh_mirrors/ob/obs-virtual-cam深夜两点你终于把压缩器、EQ、噪声抑制一路调到了自己都心动的状态录了一段回放满意得差点给自己鼓掌。然后你打开另一款录屏软件想补录个演示出来的声音瞬间回到毛坯房级别——干、涩、还有底噪。这不是你的问题而是obs-virtual-cam想替你解决的问题它能让 OBS 的成品画面和成品声音变成一个系统级的虚拟摄像头加虚拟麦克风任何 DirectShow 软件都能直接取货。这是给 OBS Studio 写的一个插件Windows 7/8/10OBS 24.0源码就在项目src/目录下。先泼一句冷水OBS 26.0 之后官方已经内置了虚拟摄像头但如果你的 OBS 还停留在旧版本或者你想搞清楚虚拟设备这种狠活到底是怎么从无到有造出来的这个项目就是最好的解剖样本。为什么值得装四个被反复踩中的坑效果链不外流你在 OBS 里堆的降噪、EQ、压缩、VST第三方软件拿到的永远是成品而不是干声——这是虚拟麦克风最大的价值。告别设备来回切不用在麦克风阵列和立体声混音之间反复横跳OBS 混好的声音就是默认输入。一路声音多处用直播、录课、会议可以同时吃同一路流不用挨个软件单独配置。零驱动污染纯软件方案不开虚拟声卡驱动不往系统音频设备列表里塞垃圾。一句话它把先调音、后分发的工作流压缩成了你点一下启动虚拟输出。它是怎么凭空出现的报户口与投信口想让系统把一个插件当摄像头用核心是两件事让系统看得见它让数据跑得动。第一件事靠 DirectShow 过滤器机制。安装时DllInstall会调用RegisterFilters源码在 src/virtual-source/dllmain.cpp把过滤器注册到CLSID_VideoInputDeviceCategory/CLSID_AudioInputDeviceCategory这两个设备分类下。说白了就是往系统的设备户籍本上登记了五个户口四路摄像头OBS-Camera到OBS-Camera4加一路音频OBS-Audio。登记完会议软件的摄像头列表里就多出了它们。第二件事靠一块共享内存。OBS 进程和 DirectShow 过滤器是两个独立上下文不能直接传指针于是项目在 src/queue/share_queue.h 里用CreateFileMapping/MapViewOfFile开了一条信道每路通道有固定门牌#define MAPPING_NAMEV OBSVirtualVideo #define MAPPING_NAMEV2 OBSVirtualVideo2 #define MAPPING_NAMEV3 OBSVirtualVideo3 #define MAPPING_NAMEV4 OBSVirtualVideo4 #define MAPPING_NAMEA OBSVirtualAudio把这条路想象成一堵墙上的投信口OBS 是送信人把每一帧画面、每一段音频塞进墙上的信箱DirectShow 过滤器是取信人按序号从另一侧一封封取走。两侧互不阻塞OBS 不用等取信人取信人也不怕送信人迟到。OBS输出 → 共享内存环形队列(OBSVirtualAudio / OBSVirtualVideoN) → 过滤器取帧 → DirectShow媒体样本 → 第三方软件队列内部的门道状态机、写指针与回退取信投信口不是乱塞的信箱口上挂着一块公告牌queue_header写端和读端全靠它对齐struct queue_header { int state; // 当前状态 int format; // 像素/采样格式 int queue_length; // 队列容量 int write_index; // 写指针 int delay_frame; // 延迟帧数 int recommended_width; int recommended_height; int aspect_ratio_type; uint64_t last_ts; // 最近一帧视频时间戳 uint64_t frame_time; // 单帧时长 };其中state是三态状态机OutputStop/OutputStart/OutputReady见 src/queue/share_queue.h创建映射时置为OutputStart写满一圈才翻转为OutputReady——取信人看到OutputReady才会动手取。这是数据就绪才放行的闸门。delay_frame是延迟缓冲。读端初始化索引时不是从写指针原地开始而是往回退几帧再开始取src/queue/share_queue_read.cppq-index q-header-write_index - q-header-delay_frame; if (q-index 0) q-index q-header-queue_length;音频通道更讲究它从last_ts往前推frame_time * delay_frame找到对应时间点的帧。这相当于给整条链路预留了一段缓冲期系统调度一抖动也不至于立刻断音。你要付出的代价就是多一点点延迟——这就是后面那个延迟帧滑块的物理来源。一份写死的格式清单44.1kHz 立体声与 YUY2第三方软件来问你支持什么格式音频过滤器在GetMediaType()里用WAVEFORMATEX一口气答完src/virtual-source/virtual-audio.h 和 .cpp#define AUDIO_BUFFER_SIZE 4096 // 单个媒体样本缓冲区字节数 #define SAMPLE_RATE 44100 // 采样率 #define SAMPLE_SIZE 176400 // 每秒字节数 44100 × 2 × 2 paf-nChannels 2; paf-nSamplesPerSec SAMPLE_RATE; paf-nAvgBytesPerSec SAMPLE_SIZE; paf-nBlockAlign 4; // 单帧样本字节数 声道 × 位深/8 paf-wBitsPerSample 16; paf-wFormatTag WAVE_FORMAT_PCM;配套的GetStreamCaps()里MinimumSampleFrequency和MaximumSampleFrequency都被锁死在 44100MinimumChannels/MaximumChannels锁死在 2。翻译成人话我就支持这一种格式别跟我讨价还价。兼容性稳到极致代价是想上 48kHz 得改源码重编译。OBS 这一侧也得对表。在 src/virtual-output/virtual_output.cpp 的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 里跑的是 48kHz 还是 96kHz 无所谓喂给虚拟麦克风之前都被统一压成 44.1kHz/16bit/立体声两头对表格式才不会打架。画面那头是另一套规格默认支持 1920×1080、1280×720、960×540、640×360帧间隔 33333330fps编码一律 YUY2YUV 42216bit分辨率校验范围 320×240 到 4096×3072只认 16:9、4:3 或 OBS 当前分辨率见ValidateResolution。FillBuffer 的三层保险取数、对表、兜底DirectShow 拉流模式下CVAudioStream::FillBuffer()会被疯狂调用它要做三件事先取数。每次从队列取最多AUDIO_BUFFER_SIZE字节取不到就睡 5 毫秒再试连试 20 次以上仍无数据就视为断流。再对表。代码里维护两条时间线obs_start_tsOBS 侧起点和dshow_start_tsDirectShow 侧起点。首帧到达时把两者对齐之后每帧播放时刻都按下式推算start_time dshow_start_ts (timestamp - obs_start_ts) / 100;最后兜底。拿不到数据时视频帧被memset(dst, 127, size)填成中性灰音频帧被memset清零。你看到的是灰屏、听到的是一瞬静音而不是花屏爆音或设备消失。只有状态明确变为OutputStop才真正断开——这是宁可给空白也不给噪音的工程态度。同步超时也是动态算的SetTimeout()sync_timeout queue.header-queue_length * AUDIO_SIZE * 10000000 / 44100 * 4;队列越长超时给得越宽等于给系统调度多留余量——代价就是延迟变高。上手三步走注册、启动、选设备第一步解压并注册。把压缩包解到 OBS 安装目录后用管理员身份打开 CMD 分别注册 32 位和 64 位过滤器regsvr32 C:\Program Files\obs-studio\bin\32bit\obs-virtualsource.dll regsvr32 C:\Program Files\obs-studio\bin\64bit\obs-virtualsource.dll想多路虚拟摄像头最多 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 路。第二步启动虚拟输出。在 OBS 的虚拟输出面板点启动选目标摄像头OBS-Camera 到 OBS-Camera4。这里还有个延迟帧滑块默认 3 帧数值越大越稳、延迟越高——会议场景用默认值就好本地录屏可以拉低。第三步在目标软件里选设备。进 Zoom / 微信 / Teams 的音频设置把输入设备切到OBS-Audio摄像头切到OBS-Camera。记住铁律OBS 必须保持运行因为投信口的另一端在 OBS 进程里。想自己编译研究的先装好 CMake 和 Visual Studio再git clone https://gitcode.com/gh_mirrors/ob/obs-virtual-cam配置好QTDIR、LIBOBS_INCLUDE_DIR、LIBOBS_LIB等 CMake 变量即可。常见问题速查现象可能原因处理方式软件列表里看不到 OBS-Camera / OBS-Audio过滤器没注册或注册不完整管理员权限重跑 regsvr32重启目标软件有画面没声音虚拟输出没启动或队列状态不是 Ready回 OBS 确认虚拟输出在运行中声音一顿一顿像卡带系统负载高、队列缓冲不够调大延迟帧滑块关掉后台音视频软件画面正常但颜色发灰刚好赶上无数据的兜底帧属于正常容错检查 OBS 输出是否稳定运行软件提示采样率不支持对方请求了非 44.1kHz 格式在软件音频设置里强制选 44100Hz音画对不上两条时间线基准漂移重启一次 OBS 虚拟输出让两端重新对齐排查顺序永远是OBS 在跑吗 → 队列 Ready 吗 → 格式是 44.1kHz/16bit/立体声吗。三个节点全对基本不会出问题。把 OBS 变成一台虚拟摄像头本质不是造假设备而是给声音和画面修了一条最体面的路——你负责调出好声音它负责把好声音送到该去的地方。真正的专业不是设备多贵而是你的每一帧都恰好抵达想让它抵达的地方。【免费下载链接】obs-virtual-camobs-studio plugin to simulate a directshow webcam项目地址: https://gitcode.com/gh_mirrors/ob/obs-virtual-cam创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表