尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

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

把 OBS 变成系统级摄像头和麦克风:obs-virtual-cam 从装机到原理全解析

把 OBS 变成系统级摄像头和麦克风:obs-virtual-cam 从装机到原理全解析 把 OBS 变成系统级摄像头和麦克风obs-virtual-cam 从装机到原理全解析【免费下载链接】obs-virtual-camobs-studio plugin to simulate a directshow webcam项目地址: https://gitcode.com/gh_mirrors/ob/obs-virtual-cam深夜直播间里你把 OBS 的九层场景叠得漂漂亮亮——产品特写在右上角下方滚动着弹幕字幕左下角还挂着品牌 logo。可当你想把这套画面搬进另一款软件时对方却只肯认那台用了五年的旧摄像头一切精心布置瞬间归零。obs-virtual-cam 要解决的正是这个痛点它让 OBS 的输出摇身一变成为系统里一个真的摄像头和麦克风任何支持 DirectShow 的软件都能直接调用。本文先带你五分钟跑通再一层层拆开它内部的数据通路最后给出排查手册。一、先跑起来五分钟让OBS 即设备生效1.1 安装与注册整个流程里唯一绕不开的坎把压缩包里的文件解压到 OBS 的安装目录后需要以管理员身份打开 CMD执行两条注册命令。注意 32 位和 64 位的 DirectShow 过滤器彼此独立两条都要跑regsvr32 C:\Program Files\obs-studio\bin\32bit\obs-virtualsource.dll regsvr32 C:\Program Files\obs-studio\bin\64bit\obs-virtualsource.dll说白了这条命令是往 Windows 的注册表里登记户口——告诉系统这里住着几个叫 OBS-Camera 的摄像头以及一个叫 OBS-Audio 的麦克风。注册完控制面板的声音设置里就会多出一台录制设备。1.2 打开开关在 OBS 的「工具」菜单里点开VirtualCam面板按下 Start。这一步才是真正的放水OBS 开始把渲染好的画面和音频写进一块共享内存第三方软件才有东西可读。1.3 在目标软件里认领新设备打开会议或直播软件进入音视频设置把摄像头换成OBS-Camera、麦克风换成OBS-Audio即可。这里有一个必须牢记的前提OBS 要一直开着。共享内存的另一端在 OBS 进程里关了 OBS设备就是一座空城。二、一条链路看懂画面从渲染到对方屏幕经过了哪几站先建立一张全局地图后面再逐个站去参观OBS 渲染管线 → 输出插件打包帧 → 共享内存环形队列 → DirectShow 过滤器取帧 → 第三方软件这条链路里有两套完全独立的行政区OBS 进程负责产出画面和声音由virtual_output输出插件virtual_output.cpp负责搬运DirectShow 过滤器进程被第三方软件拉起由obs-virtualsource.dll提供virtual-cam.cpp、virtual-audio.cpp。两个进程不能互相传指针于是它们共用一块由操作系统担保的命名共享内存作为接头地点。写端往里放读端往里取谁也锁不住谁这就是它轻巧的根源。顺带说一句这块内存的名字是全局唯一的门牌号——视频通道叫OBSVirtualVideo音频通道叫OBSVirtualAudio定义在 share_queue.h 里。三、中转站解剖共享内存环形队列的运营手册共享内存不是一坨裸数据而是一个设计过的环形队列。你可以在 share_queue.h 里亲眼看到它的结构。3.1 写在墙上的运营状态表queue_header队列头部躺着一个queue_header结构相当于贴在仓库门口的一块白板写着所有关键运营参数struct queue_header { int state; // 队列状态停止/启动/就绪 int queue_length; // 能装多少个元素 int write_index; // 写指针停在哪一格 int delay_frame; // 延迟帧数蓄水池的深度 int recommended_width; // 推荐分辨率方便读端提前做准备 uint64_t frame_time; // 每帧间隔 };这块白板的两端都能看OBS 侧更新它过滤器侧读取它。state是双方约定的暗号——OutputStop停止表示写端收摊走人了OutputReady就绪表示队列已经转过一整圈、里面的数据是新鲜的。读者拿到这个暗号就能判断该不该信这池子水。3.2 读写双方如何不打架环形队列的妙处在于先进先出、首尾相接。写端每写满一圈就回到开头继续写读端只追自己该读的那一格。判断有没有新货只需要比一个数字读索引是否等于写索引。相等说明写端还没追上来那就不取等下一轮。3.3 延迟帧蓄水池的深度是怎么定的delay_frame是全文最值得理解的一个参数。读端首次初始化索引时不会傻乎乎地从队头开始而是主动往后退delay_frame格见 share_queue_read.cpp 里的share_queue_init_index。这意味着什么把队列想象成一条水渠写端在上游放水读端在下游取水中间的delay_frame格就是蓄水池。系统调度稍有抖动上游某秒没来水下游手里还有存量顶着声音就不会断。代价也写在明面上蓄水池越深水从上游流到下游的时间越长——延迟越高。这就是为什么 OBS 面板里那个延迟滑块0–30 帧会直接影响稳定性和延迟鱼和熊掌只能自己权衡。四、穿上 DirectShow 的工装虚拟设备如何骗过系统要让系统认这个假摄像头光写数据还不够得先解决身份问题。这一步在 dllmain.cpp 里完成。4.1 注册到底做了什么注册的核心动作有两个缺一不可通过AMovieSetupRegisterServer在注册表里建立 COM 服务器条目让系统知道这个 CLSID 对应的 DLL 在哪儿通过IFilterMapper2::RegisterFilter把过滤器挂到设备分类下——视频挂到CLSID_VideoInputDeviceCategory音频挂到CLSID_AudioInputDeviceCategory。第二步才是关键。挂进分类就等于给过滤器发了工牌从此它出现在系统设备列表里会议软件枚举摄像头时能看到它、选它、拉它干活。注册时还特意把MERIT设成DO_NOT_USE意思是没事别自动选我只有用户明确指定时才启用——避免污染系统的自动设备选择。4.2 四个摄像头加一个麦克风默认注册 1 路音频和 4 路视频OBS-Camera到OBS-Camera4外加一个OBS-Audio。音频过滤器恒定 1 路视频数量可调。想少注册几路先反注册再带上参数重注册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 路摄像头。多路的好处是可以在不同软件里各取所需——一个给直播推流一个给会议互不干扰。五、讨价还价的艺术格式协商设备身份搞定后第三方软件还会问一句你能提供什么规格这就是格式协商双方必须把口径对齐。5.1 视频一份写死的清单视频侧对外提供的格式见 virtual-cam.cpp默认清单一列出来就是 1920×1080、1280×720、960×540、640×360全部 YUY2 编码、16 位色深、30 帧。同时它用GetStreamCaps声明能力边界分辨率在 320×240 到 4096×3072 之间帧率在 10–60fps 之间且只认16:9 和 4:3两种宽高比——超出范围的请求一律打回。有意思的是如果 OBS 输出正在运行过滤器会把 OBS 当前的分辨率插到清单最前面等于告诉对方用我这个最省事。取到帧之后内部会用sws_scale把像素格式统一转成 YUY2 再交付。5.2 音频一张嘴只有一种声音音频侧更干脆规格固定在44.1kHz / 16 位 / 双声道 / PCM常量定义在 virtual-audio.h#define AUDIO_BUFFER_SIZE 4096 // 单个媒体样本的字节数 #define SAMPLE_RATE 44100 // 采样率 #define SAMPLE_SIZE 176400 // 每秒字节数 44100 × 2声道 × 2字节协商时GetStreamCaps把最小值和最大值全部锁死在同一个值上——我就这一种格式不接受议价。好处是兼容性极其稳定代价是想用 48kHz 就得改源码重新编译。与此同时OBS 输出侧在启动时主动做了格式转换声明virtual_output.cppconv.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/双声道。两端口径一致才不会出现格式对不上、只有画面没声音的尴尬。六、心跳与兜底FillBuffer 的每秒节奏DirectShow 是拉流模式第三方软件会不停敲FillBuffer的门要数据。这个方法virtual-audio.cpp是音频模块的日常工作循环同时处理三件事。6.1 取不到数据先等一下每次调用先从共享内存里取最多 4096 字节。取不到不慌睡 5 毫秒再试。连续试 20 次仍无数据才判定这路水管可能断了。6.2 时间轴校准代码里维护了两条时间线obs_start_tsOBS 侧和dshow_start_ts过滤器侧。首帧到达时让两者对齐之后每帧的播放时刻都按基准 相对偏移推算保证第三方软件看到的声音节奏和 OBS 里的画面严丝合缝不会越走越飘。6.3 宁可静音也不爆音这是整套设计里最有人情味的一处数据不够或短暂断流时FillBuffer不会摔门返回错误而是把缓冲区memset成全零再照常输出——用户听到的只是一瞬安静而不是刺耳的爆音或设备整个消失。视频侧同理取不到帧就填一帧中性灰。给静音不给噪音这种温和失败的态度正是听感稳定的关键。6.4 同步超时的逻辑超时也不是随手写的。音频的同步超时按队列长度动态计算sync_timeout queue.header-queue_length * AUDIO_SIZE * 10000000 / 44100 * 4;队列越长超时越宽——给系统调度留更多余量同时把延迟的代价转嫁给用户这就是延迟滑块的物理来源。七、几个值得拨动的旋钮打开 OBS 的 VirtualCam 面板你会看到几个设置作用如下设置项作用建议Start / Stop启动或停止虚拟输出平时保持运行目标设备Target选择写入哪一路摄像头默认 OBS-Camera 即可延迟帧滑块0–30控制蓄水池深度网络会议用 1–5本地录屏可拉低水平翻转镜像画面用前置摄像头做直播时常需要保持宽高比画面不足时用中性灰填充不变形场景比例不匹配时打开开机自启OBS 启动时自动开启虚拟输出常用就勾上另外这个插件还提供一种过滤器模式virtual_filter.cpp把它挂到某个具体来源上只把这一路画面送出去适合只给观众看游戏画面、不暴露整个场景的用法。八、出问题按图索骥现象可能原因处理方式第三方软件里找不到 OBS-Camera / OBS-Audio过滤器没注册或注册不完整管理员权限重新 regsvr32重启目标软件能选到设备但画面黑屏OBS 侧虚拟输出没启动打开 VirtualCam 面板确认在运行画面与声音断断续续系统负载高蓄水池不够深调大延迟帧关掉多余的后台软件音画节奏对不上时间轴基准漂移重启一次 OBS 输出让两端重新对齐软件提示采样率不支持对方请求了非 44.1kHz 的格式在该软件音频设置里强制选 44100Hz排查时记住一条主线OBS 在跑 → 队列 Ready → 格式 44.1kHz/16bit/立体声。这三个节点挨个验证绝大多数问题都能定位。九、想去读源码按这个顺序如果你想亲手验证上面讲的每一环建议按这个顺序读从外围到核心readme.MD —— 安装、注册、构建说明一页看全share_queue.h —— 队列的数据结构总纲一切的地基share_queue_write.cpp —— 写端视角队列怎么建、帧怎么入队share_queue_read.cpp —— 读端视角索引初始化、延迟帧、取帧virtual_output.cpp —— OBS 侧如何接住渲染管线并写队列virtual-cam.cpp 与 virtual-audio.cpp —— DirectShow 侧如何取帧、协商格式、补静音dllmain.cpp —— 最后的身份登记环节。想从源码自己编译一份参考 readme.MD 里的 Build 一节需要 CMake Visual Studio 2017先把 OBS 项目构建好再配置QTDIR、DepsPath、LIBOBS_INCLUDE_DIR等 CMake 变量即可。写在最后如果只让你记住一句话这个插件干的事是让 OBS 和第三方软件通过一块命名共享内存完成隔空交接再用 DirectShow 过滤器的身份让系统认账——写端持续放水读端按帧取水中间的延迟帧是缓冲垫静音兜底是安全网时间戳校准是节拍器。看懂这条链路再遇到无声、卡顿、不同步你就不再是瞎猜而是能顺着数据流一站一站去摸。设备清单里多出的一行 OBS-Camera背后是两套进程隔着共享内存的握手言和。把这套机制握在手里你的 OBS 就不再只是个直播工具而是整台电脑的信号中枢——想让哪路画面被谁看见、哪路声音抵达哪场会议都由你说了算。【免费下载链接】obs-virtual-camobs-studio plugin to simulate a directshow webcam项目地址: https://gitcode.com/gh_mirrors/ob/obs-virtual-cam创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表