DirectShow中通过IAMStreamSelect接口实现多音轨切换

IAMStreamSelect 接口

(只有英文版的,中文搜索起来不方便,MSDN中文版翻译太慢,故写之,转载时请注明,源自vcmute,原文地址 http://blog.youkuaiyun.com/vcmute/archive/2005/10/16/504909.aspx)


IAMStreamSelect 接口控制哪些流被播放并获取他们的信息. 典型的应用是不用的语言编码的一套音频流之间的选择. 举例来说, 用户可选择在英语、德语和法语间切换音轨,所以在MediaPlayer音频和语言音轨切换是同一菜单项.

方法描述
Count得到有效流的总数.
Info获取一个指定流的信息.
Enable使能或禁止一个指定流.

示例

下面例子讲述如何使用IAMStreamSelect 接口, 获取流的信息, 使能指定流, 并显示对应信息. 
该例子假设播放文件存在 C:/Sami_test_file.sami.并使用固定索引1和3来调用Enable函数:

void __cdecl main()
{
    HRESULT hr;
    IGraphBuilder *pGraph;
    IMediaControl *pMediaControl;
    IMediaEventEx *pEv;
    IBaseFilter   *pSAMI;

    CoInitialize(NULL);
    
    // 创建 filter graph manager.
    CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, 
                        IID_IGraphBuilder, (void **)&pGraph);
    pGraph->QueryInterface(IID_IMediaControl, (void **)&pMediaControl);
    pGraph->QueryInterface(IID_IMediaEventEx, (void**)&pEv);

    // 建立 graph 并寻找 SAMI parser.
    pGraph->RenderFile(L"C://Sami_test_file.sami", NULL);
    hr = pGraph->FindFilterByName(L"SAMI (CC) Parser", &pSAMI);
    if (SUCCEEDED(hr)) 
    {
        IAMStreamSelect *pStrm = NULL;
        hr = pSAMI->QueryInterface(IID_IAMStreamSelect, (void**)&pStrm);
        if (SUCCEEDED(hr)) 
        {
            DWORD dwStreams = 0;
            pStrm->Count(&dwStreams);
            printf("Stream count: %d/n", dwStreams);

            // 选择流1和流3(French 和 "GreenText")
            hr = pStrm->Enable(1, AMSTREAMSELECTENABLE_ENABLE);
            hr = pStrm->Enable(3, AMSTREAMSELECTENABLE_ENABLE);

            // 打印各个流的信息
for (DWORD index = 0; index < dwStreams; index++) { DWORD dwFlags; WCHAR *wszName; hr = pStrm->Info(index, NULL, &dwFlags, NULL, NULL, &wszName, NULL, NULL); wprintf(L"Stream %d: %s [%s]/n", index, wszName, (dwFlags ? L"ENABLED" : L"DISABLED")); CoTaskMemFree(wszName); } pStrm->Release(); } pSAMI->Release(); } // 播放 pMediaControl->Run(); while (1) { long evCode, lParam1, lParam2; pEv->GetEvent(&evCode, &lParam1, &lParam2, 100); if (evCode == EC_OLE_EVENT) { wprintf(L"%s/n", (BSTR)lParam2); } pEv->FreeEventParams(evCode, lParam1, lParam2); if (evCode == EC_USERABORT || evCode == EC_COMPLETE || evCode == EC_ERRORABORT) break; } // 释放. pMediaControl->Release(); pEv->Release(); pGraph->Release(); CoUninitialize(); }
注:有些切换器如MMSwitch只能在运行中切换,所以在切换前要加一句 pMediaControl->Pause();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值