如何使用DirectShow播放一个文件
2014-05-07 23:05
453 查看
本文的目的是给出DirectShow编程的样式。这是一个简单的控制台应用程序,用来播放一个音频或视频文件。程序只有几行,但是它示范了DirectShow编程的某些能力。
如<DirectShow应用程序编程介绍>所写,一个DirectShow应用程序运行的基本步骤为:
1、创建一个筛选器表管理器的实例
2、使用筛选器表管理器生成一个筛选器表
3、运行表,使数据在筛选器中流动。
调用CoIntitialize来初始化COM库
HRESULT hr = CoInitialize(NULL);
if (FAILED(hr))
{
// 在这里添加错误处理代码(Omitted for clarity.)
}
为了简单化,此例子忽略了返回值,但是您最好在方法调用中检查HRESULT的值。
下面,调用CoCreateInstance来创建筛选器表管理器:
IGraphBuilder *pGraph;
HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL,
CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGraph);
如上所示,类标识(CLSID)为CLSID_FilterGraph。筛选器表管理器由一个进程内的DLL提供,所以执行上下文是 CLSCTX_INPROC_SERVER。DirectShow支持自由自由线程处理模式,因此您也可以使用COINIT_MULTITHREADED 标志调用CoInitializeEx。
对CoCreateInstance的调用返回IGraphBuilder接口,它主要包含了生成筛选器表的方法。此例中用到的另两个接口为:
IMediaControl,作用是控制流。它包含了停止和启动表的方法
IMediaEvent,它包含的方法是从筛选器表管理器中得到事件。在此例中,此接口用来等待播放的结束。
这两个接口都是出现在筛选器表管理器中。可以使用返回的IGraphBuilder指针来查询。
IMediaControl *pControl;
IMediaEvent *pEvent;
hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);
现在您可以生成筛选器表了。要播放文件,可以调用下列方法:
hr = pGraph->RenderFile(L"C://Example.avi", NULL);
IGraphBuilder::RenderFile方法生成一个筛选器表,用以播放指定的文件。第一个参数是文件名称,用一个宽字符(2字节)字符串表示。第二个参数是保留参数,必须为NULL。
如果指定的文件不存在,或文件格式无法,此方法将失败。如果方法调用成功,筛选器还原器就做好播放的准备了。要运行表,调用IMediaControl::Run方法。
hr = pControl->Run();
当筛选器运行时,数据从筛选器中移出,并以视频和音频的方式还原出来。播放会启动另一个线程。您可以调用IMediaEvent::WaitForCompletion方法。
long evCode = 0;
pEvent->WaitForCompletion(INFINITE, &evCode);
当应用程序结束时,将释放接口指针并关闭COM库。
pControl->Release();
pEvent->Release();
pGraph->Release();
CoUninitialize();
代码范例
这里列出了本文介绍的例子的完整代码:
#include <dshow.h>
void main(void)
{
IGraphBuilder *pGraph = NULL;
IMediaControl *pControl = NULL;
IMediaEvent *pEvent = NULL;
// 初始化COM库
HRESULT hr = CoInitialize(NULL);
if (FAILED(hr))
{
printf("ERROR - Could not initialize COM library");
return;
}
// 创建筛选器表管理器,并查询接口
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
IID_IGraphBuilder, (void **)&pGraph);
if (FAILED(hr))
{
printf("ERROR - Could not create the Filter Graph Manager.");
return;
}
hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);
// 创建表。重点:将字符串改为您系统上的文件名称
hr = pGraph->RenderFile(L"C://Example.avi", NULL);
if (SUCCEEDED(hr))
{
// 运行表
hr = pControl->Run();
if (SUCCEEDED(hr))
{
// 等待结束
long evCode;
pEvent->WaitForCompletion(INFINITE, &evCode);
// 注意:在实际应用程序中不要使用INFINITE
// 因为它对应用程序的阻塞很不确定
}
}
pControl->Release();
pEvent->Release();
pGraph->Release();
CoUninitialize();
}
此方法将阻塞,直到文件播放完毕,或超出了指定的时间。INFINITE值是指应用程序将阻塞到文件播放完。
如<DirectShow应用程序编程介绍>所写,一个DirectShow应用程序运行的基本步骤为:
1、创建一个筛选器表管理器的实例
2、使用筛选器表管理器生成一个筛选器表
3、运行表,使数据在筛选器中流动。
调用CoIntitialize来初始化COM库
HRESULT hr = CoInitialize(NULL);
if (FAILED(hr))
{
// 在这里添加错误处理代码(Omitted for clarity.)
}
为了简单化,此例子忽略了返回值,但是您最好在方法调用中检查HRESULT的值。
下面,调用CoCreateInstance来创建筛选器表管理器:
IGraphBuilder *pGraph;
HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL,
CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGraph);
如上所示,类标识(CLSID)为CLSID_FilterGraph。筛选器表管理器由一个进程内的DLL提供,所以执行上下文是 CLSCTX_INPROC_SERVER。DirectShow支持自由自由线程处理模式,因此您也可以使用COINIT_MULTITHREADED 标志调用CoInitializeEx。
对CoCreateInstance的调用返回IGraphBuilder接口,它主要包含了生成筛选器表的方法。此例中用到的另两个接口为:
IMediaControl,作用是控制流。它包含了停止和启动表的方法
IMediaEvent,它包含的方法是从筛选器表管理器中得到事件。在此例中,此接口用来等待播放的结束。
这两个接口都是出现在筛选器表管理器中。可以使用返回的IGraphBuilder指针来查询。
IMediaControl *pControl;
IMediaEvent *pEvent;
hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);
现在您可以生成筛选器表了。要播放文件,可以调用下列方法:
hr = pGraph->RenderFile(L"C://Example.avi", NULL);
IGraphBuilder::RenderFile方法生成一个筛选器表,用以播放指定的文件。第一个参数是文件名称,用一个宽字符(2字节)字符串表示。第二个参数是保留参数,必须为NULL。
如果指定的文件不存在,或文件格式无法,此方法将失败。如果方法调用成功,筛选器还原器就做好播放的准备了。要运行表,调用IMediaControl::Run方法。
hr = pControl->Run();
当筛选器运行时,数据从筛选器中移出,并以视频和音频的方式还原出来。播放会启动另一个线程。您可以调用IMediaEvent::WaitForCompletion方法。
long evCode = 0;
pEvent->WaitForCompletion(INFINITE, &evCode);
当应用程序结束时,将释放接口指针并关闭COM库。
pControl->Release();
pEvent->Release();
pGraph->Release();
CoUninitialize();
代码范例
这里列出了本文介绍的例子的完整代码:
#include <dshow.h>
void main(void)
{
IGraphBuilder *pGraph = NULL;
IMediaControl *pControl = NULL;
IMediaEvent *pEvent = NULL;
// 初始化COM库
HRESULT hr = CoInitialize(NULL);
if (FAILED(hr))
{
printf("ERROR - Could not initialize COM library");
return;
}
// 创建筛选器表管理器,并查询接口
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
IID_IGraphBuilder, (void **)&pGraph);
if (FAILED(hr))
{
printf("ERROR - Could not create the Filter Graph Manager.");
return;
}
hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);
// 创建表。重点:将字符串改为您系统上的文件名称
hr = pGraph->RenderFile(L"C://Example.avi", NULL);
if (SUCCEEDED(hr))
{
// 运行表
hr = pControl->Run();
if (SUCCEEDED(hr))
{
// 等待结束
long evCode;
pEvent->WaitForCompletion(INFINITE, &evCode);
// 注意:在实际应用程序中不要使用INFINITE
// 因为它对应用程序的阻塞很不确定
}
}
pControl->Release();
pEvent->Release();
pGraph->Release();
CoUninitialize();
}
此方法将阻塞,直到文件播放完毕,或超出了指定的时间。INFINITE值是指应用程序将阻塞到文件播放完。
相关文章推荐
- 如何使用DirectShow播放一个文件。
- 控制台使用directshow播放一个文件
- 如何计算 一个音视频文件 (.ts)文件 (包含pcr信息). 播放所使用的带宽
- [译]Android音频: 如何使用AudioTrack播放一个WAV格式文件?
- Android音频: 如何使用AudioTrack播放一个WAV格式文件?
- 如何计算 一个音视频文件 (.ts)文件 (包含pcr信息). 播放所使用的带宽
- 如何计算 一个音视频文件 (.ts)文件 (包含pcr信息). 播放所使用的带宽
- 关于如何使用VS高亮显示无扩展名源码文件的一个小技巧
- C语言学习笔记----伊能C语言学习笔记----如何在一个文件中使用另一个文件中定义的变量呢??
- 关于如何将一个对象保存到本地文件之ObjectOutputStream、ObjectInputStream的使用小结。
- 一个使用WINDOWS媒体库的WAV音频文件播放的示例
- 如何使用拼合图播放一个序列帧动画
- 如何使用update.exe工具升级一个sqlce1.0/2.0的sdf文件到sqlce3.0
- 如何播放一个文件
- 如何使用asp.net中的控件将一个图片文件从一个目录传到另外一个目录下?
- 如何在 Linux 上使用 SSHfs 挂载一个远程文件系统
- 如何使用FileCreate建立一个文件
- C# 如何知道一个影像文件能够播放多长时间
- 如何通过命令行或者使用代码打开一个apk文件
- 如何使用JavaExcel(jxl)读取一个文件并写入一个新文件