You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Vivek VCAM扩展虚拟音视频设备无音频回调问题咨询

基于Vivek VCAM源码实现音视频同步虚拟摄像头的音频传输修复

问题描述

我已基于Vivek的VCAM滤镜源码成功实现虚拟摄像头设备,现需要将其扩展为可同时传输音视频的单一虚拟摄像头,同步输出视频与音频流。
针对该需求我已完成如下修改:

  1. 注册媒体类型与输出Pin配置:
const AMOVIESETUP_MEDIATYPE AMSMediaTypesVCam[] =
{
    {
        &MEDIATYPE_Video,
        &MEDIASUBTYPE_NULL
    },
    {
        &MEDIATYPE_Audio,
        &MEDIASUBTYPE_NULL
    }
};

const AMOVIESETUP_PIN AMSPinVCam =
{
    L"Output",             // Pin字符串名称
    FALSE,                 // 是否为渲染Pin
    TRUE,                  // 是否为输出Pin
    FALSE,                 // 是否允许无实例
    FALSE,                 // 是否允许多实例
    &CLSID_NULL,           // 连接的滤镜CLSID
    NULL,                  // 连接的Pin
    2,                     // 支持的媒体类型数量
    AMSMediaTypesVCam      // Pin支持的媒体类型列表
};

其余代码与Vivek原有虚拟摄像头实现完全一致,但目前音频媒体类型相关逻辑始终未被调用,无法将音频缓冲区传输到虚拟摄像头。
2. GetMediaType函数适配:

// GetMediaType函数内逻辑
if (IsEqualGUID(*pmt->Type(), MEDIATYPE_Video) || iPosition == 1)
{
    // 配置位图格式(视频相关逻辑)
}
else if (IsEqualGUID(*pmt->Type(), MEDIATYPE_Audio))
{
    // 配置波形格式(音频相关逻辑)
}
  1. DecideBufferSize函数适配:
// DecideBufferSize函数内逻辑
if (IsEqualGUID(*m_mt.Type(), MEDIATYPE_Video))
{
    // 视频缓冲区分配逻辑
}
else if (IsEqualGUID(*m_mt.Type(), MEDIATYPE_Audio))
{
    // 音频缓冲区分配逻辑
}

需要明确还需完成哪些修改才能实现音频流正常传输。

问题根因

你当前的实现本质上是给单个输出Pin同时注册了音视频两种媒体类型,这不符合DirectShow的滤镜设计规范:单个输出Pin在同一连接生命周期内只能协商一种主媒体类型,绝大多数应用枚举虚拟摄像头设备时,只会优先请求视频媒体类型,永远不会触发同个Pin上的音频类型协商逻辑,这就是音频分支代码始终不被调用的根本原因。
另外Windows系统对摄像头类设备的枚举逻辑默认只会采集视频Pin的流,音频流需要暴露独立的音频输出Pin,同时完成设备端的音频接口注册,否则系统和应用根本不会识别到设备支持音频输出。

必须完成的修改项

  • 拆分输出Pin:不要在同一个输出Pin上同时注册音视频媒体类型,新增独立的音频输出Pin。视频输出Pin仅保留MEDIATYPE_Video相关的媒体类型配置,音频输出Pin单独注册MEDIATYPE_Audio相关的媒体类型。两个Pin独立实现GetMediaType、CheckMediaType、DecideBufferSize、FillBuffer逻辑,不要共用一套判断分支。
  • 修正媒体类型枚举逻辑:你当前GetMediaType中iPosition == 1的判断写在视频分支是错误的,音频Pin的媒体类型枚举要从iPosition=0开始,按音频支持的格式依次返回(比如PCM等目标音频子类型),不要和视频的位置索引混在一起。
  • 补全音频媒体类型完整参数:不要只设置主类型为MEDIATYPE_Audio,必须完整填充WAVEFORMATEX结构体,明确采样率、位深、声道数、块对齐、平均字节率等参数,否则应用枚举时会认为音频Pin格式无效直接跳过。
  • 补全音频流推送逻辑:在音频Pin的FillBuffer函数中按采样间隔填充音频帧数据,同时做好音视频时间戳对齐:音视频帧的起始参考时间要匹配同一时钟源,音频帧时长按照采样数/采样率计算,视频帧时长按照帧率计算,避免音画不同步。
  • 修改设备注册逻辑:原有VCAM的注册信息只在视频设备类下注册,你需要补充在音频输入设备分类(CLSID_AudioInputDeviceCategory)下注册音频输出接口,否则系统音频枚举列表里看不到你的虚拟设备音频端,通讯、直播类应用自然不会请求音频流。
  • 实现流状态同步控制:两个输出Pin要共用同一个参考时钟,在滤镜的Run、Pause、Stop状态切换时,同时控制两个Pin的流启动、暂停、停止动作,避免单端流启动导致的连接异常。

注意事项

不要尝试用单个输出Pin同时推音视频,除了不符合DirectShow规范外,大部分基于MediaFoundation框架的新应用(比如Win10/11自带相机、Teams、新版Chrome)根本不识别单Pin混合媒体类型的设备,拆分为独立音视频Pin是唯一兼容全场景的实现方案。

内容的提问来源于stack exchange,提问作者enzio91900

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.31 21:30:42