1

我使用directshow制作了一个控制台应用程序,该应用程序从实时源(现在是网络摄像头,然后是电视采集卡)录制,在叠加层中添加当前日期和时间,然后将音频和视频另存为.asf。现在我希望输出文件每 60 分钟更改一次而不停止图表。我不能错过任何几秒钟的直播。图表是这样的:

http://imageshack.us/photo/my-images/543/graphp.jpg/

我查看了 GMFBridge,但我对他们的示例有一些编译问题。我想知道是否有办法将覆盖过滤器和音频源中存在的内容分开,将它们连接到另一个 asf 编写器(暂停),然后每 60 分钟切换一次。暂停的 asf 过滤器的文件名必须更改(pp.asf、pp2.asf、pp4.asf ...)。像这样的东西:

http://imageshack.us/photo/my-images/546/graph1f.jpg/

pp1 暂停。我在互联网上发现有人说如果图形没有进入停止模式,asf 编写器会删除当前文件。

4

3 回答 3

1

好吧,我的产品 (http://www.videophill.com) 完全符合您的描述(它用于广播合规录制目的) - 我发现这样做的唯一方法是:

  • 创建一个仅用于捕获音频和视频的 dshow 图表
  • 然后,在图表的末尾,插入用于音频和视频的采样器过滤器
  • 然后,使用IWMWritter从 samplegrabber 过滤器中获取的样本来创建和保存 wmv 文件
  • 时机成熟时,关闭一个IWMWritter并创建另一个。

这样,您在切换输出文件时不会丢失单帧。

当然,还有排队和存储样本(切换写入器时)和正确重新对齐音频/视频时间戳的问题,但根据我的研究,这是唯一的“正常”方法,我在实践中使用。

于 2011-05-18T10:04:33.373 回答
1

解决方案是在您的情况下编写一个带有两个输入引脚的自定义 DShow 过滤器。一个用于音频流,另一个用于视频流。在该过滤器内部(从架构的角度来看,不必在内部,因为您也可以使用回调并在其他地方完成工作),您应该创建 asf 文件。在切换文件时,A/V 数据将存储在缓存中(例如足够大的循环缓冲区)。您还可以在该过滤器中观看和修改 A/V 同步。对于编写 ASF 文件,我会推荐 Windows Media Format SDK。
如果您想进一步传递 A/V 数据以进行预览、并行流式传输等,还可以添加输出引脚...

于 2011-05-18T10:19:48.670 回答
0

GMFBridge 是一个可行但复杂的解决方案,我过去实施的一种更直接的方法是查询 ASF Writer 的IWMWriterAdvanced2接口并设置自定义接收器。在该界面中,您可以使用方法来删除和添加接收器到 ASF 编写器。自动连接的接收器将写入您指定的文件。一种写任何你想写的方法是

1.)删除所有默认接收器:

pWriterAdv->RemoveSink(NULL);

2.) 注册一个自定义接收器:

pWriterAdv->AddSink((IWMWriterSink*)&streamSink);

自定义接收器可以是一个实现类IWMWriterSink,它需要实现调用的回调方法,即在写入 ASF 标头时 ( OnHeader(/* [in] */ INSSBuffer *pHeader);) 和写入数据包时 ( OnDataUnit(/* [in] */ INSSBuffer *pDataUnit);) - 在您的实现中,您可以将它们写入任何您想要的位置,例如示例在此类上提供其他方法,您可以在其中指定要写入的文件名。

请注意,如果您需要在每个 60 分钟文件中写出标头信息,此解决方案并不能完全满足您的要求 - 在初始标头之后,您只会获得 ASF 数据包数据。一种解决方法可能是在每个文件的任何数据包数据之前重写初始标头,但这将产生一个未索引(不可搜索)的 ASF 文件。

于 2011-05-18T09:33:17.587 回答