在directshow中以编程方式更改录制文件

时间:2011-05-17 10:12:36

标签: directshow asf

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

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

我看了一下GMFBridge,但我的例子中有一些编译问题。 我想知道是否有一种方法可以分离叠加过滤器和音频源中存在的内容,将它们连接到另一个asf writer(暂停),然后每隔60分钟切换一次。 暂停的asf过滤器的文件名必须更改(pp.asf,pp2.asf,pp4.asf ...)。像这样:

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

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

3 个答案:

答案 0 :(得分:1)

好吧,我的产品(http://www.videophill.com)完全符合您的描述(用于广播合规性录制目的) - 而且我发现只有这样才能做到这一点:

  • 创建一个仅用于捕获音频和视频的dshow图表
  • 然后,在图表的末尾,插入samplegrabber过滤器,包括音频和视频
  • 然后,使用IWMWritter创建并保存wmv文件,使用从samplegrabber过滤器获取的样本
  • 当时间到了,关闭一个IWMWritter并创建另一个。

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

当然,还存在排队和存储样本(切换写入时)和正确重新调整音频/视频时间戳的问题,但从我的研究来看,这是唯一“正常”的方式,我在实践中使用过。

答案 1 :(得分:1)

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

答案 2 :(得分:0)

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

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

pWriterAdv->RemoveSink(NULL);

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

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

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

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