使用 DirectShow.NET 的音频同步问题

本文关键字:同步 问题 音频 DirectShow NET 使用 | 更新日期: 2023-09-27 18:31:43

我已经在DirectShow.NET的论坛上发起了一个关于这个问题的话题,这里是链接 http://sourceforge.net/projects/directshownet/forums/forum/460697/topic/5194414/index/page/1但不幸的是,问题仍然存在...

有一个应用程序可以从网络摄像头捕获视频和从麦克风捕获音频并将其保存到文件中,由于某种原因,音频和视频从未同步,我尝试了以下方法:1. 从 ffdshow 编码器开始并更改为 AVI 复用器 - 问题仍然存在,音频延迟,在视频结束时,图片保持冻结,音频继续2. 从 AVI Mux 更改为 WM ASF 编写器 - 视频在开始时冻结(2 秒),视频的其余部分同步(但前两秒不可用)3. 创建打印音频和视频时间戳的 SampleGrabber - 看到音频时间戳早了 500 毫秒,但我不知道如何处理这个事实......4. 尝试手动将参考时钟设置为其中一个捕获过滤器(音频/视频),但两者都不会投射到 IReferenceClock5. 创建了一个系统时钟并设置了它与参考时钟 - 没有区别6. 在抓取上设置 SyncUsingStreamOffset(true) - 时间戳现在更接近,但最终结果是相同的7.尝试将音频和视频保存到两个不同的文件中,并使用VirtualDub查看它们是否匹配,它们仍然不匹配...

哦,我忘了提我也尝试过在GraphEditPlus中构建图形,但问题仍然存在,这是图表的链接:http://www2.picturepush.com/photo/a/8030745/img/8030745.png

目前,我正在测试我对 DirectShow.NET 样本中的 CapWMV 样本的所有更改。

请任何建议将不胜感激,我很绝望:/

谢谢

伊兰。

更新:

音频和视频之间似乎有一个恒定的 500 毫秒差距,如果我使用 virtualDub 将音频延迟 500 毫秒,它看起来不错,如何在图表中设置它?

使用 DirectShow.NET 的音频同步问题

音频流的延迟等于捕获缓冲区的大小。也就是说,您将获得在 0.5 秒外开始捕获的完整缓冲区。需要使用较小的缓冲区和/或在缓冲区上应用偏移量来调整延迟。

看:

  • 最小化 DirectShow 中的音频捕获延迟
  • 如何消除 DirectShow 过滤器链中的 1 秒延迟?(使用Delphi和DSPACK)

IAMBufferNegotiation是关键词。

只是想为我的情况添加解决方案,也许它会帮助某人。

我试图录制来自网络摄像头的视频以及来自麦克风的音频,视频是高清 (1080p),所以我想保存一个以 MPEG4 编码的 AVI 文件,所以我使用 ffshow-tryous(免费的 Mpeg4 编码器)和 Avi 复用过滤器,问题是我的一些(其中大多数:))的视频有同步问题。

我发现 Avi Mux 不处理同步,它假设数据在适当的时间到达(写在这里 - http://msdn.microsoft.com/en-us/library/dd407208(v=vs.85).aspx),所以我尝试使用 WMAsfWriter 它确实处理同步并且工作正常(我上面提到的 2 秒冻结只是 VLC 播放器的故障),但它在高分辨率下效果不佳,我在自定义配置文件中使用它时遇到了麻烦(过滤器不会得到已连接)。

我也尝试了 Roman 的建议,虽然这些链接非常有趣和有前途(我真的建议阅读它们 - 还不能给帖子 +1 ......),但它没有任何区别:/

我的最终解决方案是放弃MPEG4而只使用MPEG2,我从Avi Mux切换到Microsoft MPEG2编码器,效果很好,早就应该考虑一下:)

希望这会帮助其他人。

谢谢

伊兰。

我遇到了同样的问题,使用 Xvid MPEG-4 解码器将视频从 WMV 渲染到 AVI。

在不放弃MPEG-4的情况下,我的最终解决方案是配置AviMuxer设置ConfigAviMux::SetMasterStream属性

如从 MSDN 配置捕获视频到 AVI 文件一文中所述:

如果要从两个单独的设备捕获音频和视频,则 使音频流成为主流的好主意。这有助于 防止两个流之间的漂移,因为 AVI 多路复用器过滤器 调整视频流的播放速率以匹配音频 流。

示例代码 :

IConfigAviMux _filterAVIMuxerCfg = (IConfigAviMux)_filterAVIMuxer;
_filterAVIMuxerCfg.SetMasterStream(0); // I've add first audio ;)