在 DirectShow 中读取 ASF 文件 (Windows Media Format 11 SDK)

[与此页面关联的功能 Windows Media Format 11 SDK 是旧版功能。 它已被源读取器和接收器编写器取代。 源读取器和接收器编写器已针对Windows 10和Windows 11进行了优化。 Microsoft 强烈建议新代码尽可能使用源读取器和接收器编写器,而不是 Windows Media Format 11 SDK。 如果可能,Microsoft 建议重写使用旧 API 的现有代码以使用新 API。]

ASF 文件的播放由 WM ASF 读取器 筛选器处理。 当 WM ASF 读取器读取文件时,它会自动为每个流(包括 Web 流、脚本命令流和任何其他类型的任意流)创建输出引脚。 对于多个比特率文件,仅为当前所选流创建引脚。

WM ASF 读取器支持 DirectShow IMediaSeeking 接口,这使应用程序能够在文件中执行临时查找。 但是,不支持 IMediaSeeking::SetRate) 中指定的速度 (1.0 以外的速度播放。

筛选器还公开多个 Windows Media Format SDK 接口,如下表所述。

接口 公开方式 注释
IWMDRMReader 通过筛选器上的 IServiceProvider 为需要播放受数字版权管理 (DRM) 保护的内容的应用程序提供。 此接口还可用于直接获取读取器对象上的其他接口。
IWMHeaderInfo 筛选器上的 QueryInterface 提供以便应用程序可以读取文件和内容属性,以及标记和脚本信息和元数据。
IWMReaderAdvanced 筛选器上的 QueryInterface 在筛选器上部分实现,以便应用程序可以访问 WM Reader 对象上的信息方法。
IWMReaderAdvanced2 筛选器上的 QueryInterface 在筛选器上部分实现,以便应用程序可以访问 Reader 对象上的信息方法。

 

WM ASF 读取器筛选器首次在 DirectShow 8.0 中提供。 DirectShow 8.1 和 9.0 随附的筛选器版本支持版本 7。Windows 媒体格式 SDK 的 x 。 最新版本的筛选器以及其他 QASF 组件附带并支持 Windows Media Format 9 系列 SDK 及更高版本,并取代 DirectX 9.0 中的筛选器。 如果在安装 DirectX 8 后安装 Windows Media Format SDK。x 或 9。x SDK,你将使用 9 系列版本覆盖 qasf.dll 的 DirectX 版本。 这不应造成任何问题,除非在一种方案中,它会导致 DirectShow IGraphBuilder::RenderFile 方法中出现不同行为。 WM ASF 读取器的 Windows Media Format 9 系列 SDK 版本是 .asf、.wmv 和 .wma 文件扩展名的默认源筛选器。 这意味着,指定此类型的文件时,筛选器图形管理器会自动创建 WM ASF 读取器并将其添加到筛选器图中,方法如 IGraphBuilder::RenderFileIGraphBuilder::AddSourceFilter 。 在 DirectX 9.0 及更早版本以及 Windows XP Service Pack 1 及更早版本中, RenderFile 方法使用较旧的 Windows 媒体源筛选器。 保持此行为是为了确保与使用 Windows 媒体播放器 6.4 的应用程序向后兼容。 有关旧版 Windows 媒体源筛选器的详细信息,请参阅 DirectShow SDK 文档。

若要使用 WM ASF 读取器播放 ASF 文件与基于 Windows Media 的内容,三个主要步骤是创建 Filter Graph Manager 的实例,调用 IGraphBuilder::RenderFile 以创建图形,然后调用 IMediaControl::Run 来播放该文件。 下面的代码示例是使用 DirectShow 播放 ASF 文件的完整程序。 若要运行此示例,必须安装 DirectX SDK,并且必须按照 DirectShow SDK 文档主题“设置生成环境”中的说明配置生成环境。此外,必须在调用 RenderFile 时在计算机上指定文件。

#include <dshow.h>
#include <stdio.h>

void main(void)
{
    IGraphBuilder *pGraph = NULL;
    IMediaControl *pControl = NULL;
    IMediaEvent   *pEvent = NULL;

    // Initialize the COM library.
    HRESULT hr = CoInitialize(NULL);
    if (FAILED(hr))
    {
        printf("ERROR - Could not initialize COM library");
        return;
    }

    // Create the Filter Graph Manager and query for interfaces.
    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);

    // Build the graph. IMPORTANT: Change this string to a file
    // on your system.
    hr = pGraph->RenderFile(L"test.wmv", NULL);
    if (SUCCEEDED(hr))
    {
        // Run the graph.
        hr = pControl->Run();
        if (SUCCEEDED(hr))
        {
            // Wait for completion.
            long evCode;
            pEvent->WaitForCompletion(INFINITE, &evCode);

            // Note: Do not use INFINITE in a real application, because it
            // can block indefinitely.
        }
    }
    pControl->Release();
    pEvent->Release();
    pGraph->Release();
    CoUninitialize();
}

请注意,此简单示例的应用程序代码从不专门引用 WM ASF 读取器。 筛选器由 Filter Graph 管理器创建、连接、运行并最终释放。 但是,在许多情况下,可能需要在开始播放之前配置 WM ASF 读取器。