次の方法で共有


SAMI (CC) パーサー フィルタ

SAMI (Synchronized Accessible Media Interchange) ファイルからのキャプション データを解析する。

SAMI は、HTML に似たテキスト フォーマットであり、タイム ベース キャプションのエンコードに使われる。このフィルタは、SAMI データをテキスト ストリームに変換する。ストリームの各サンプルには、1 つのキャプション エントリとフォーマット情報が含まれている。サンプルのタイム スタンプは、SAMI ファイルのタイム情報から生成される。

このフィルタは、内部スクリプト コマンド レンダリング フィルタと共に使うように設計されている。内部スクリプト コマンド レンダラは、テキスト サンプルを受け取り、イベント通知としてアプリケーションに送る。詳細については、「注意」を参照すること。

フィルタ インターフェイス IAMStreamSelectIBaseFilter
入力ピン メディア タイプ MEDIATYPE_Stream
入力ピン インターフェイス IPinIQualityControl
出力ピン メディア タイプ MEDIATYPE_Text、MEDIASUBTYPE_NULL
出力ピン インターフェイス IMediaSeekingIPinIQualityControl
フィルタ CLSID {33FACFE0-A9BE-11D0-A520-00A0D10129C0}
プロパティ ページ CLSID プロパティ ページなし。
実行モジュール quartz.dll
メリット MERIT_UNLIKELY
フィルタ カテゴリ CLSID_LegacyAmFilterCategory

注意

以下に、簡単な SAMI ファイルを示す。

<SAMI>
<Head>
<STYLE TYPE="text/css"> <!--
    .ENCC {Name: English; lang:en-US; SAMI_TYPE: CC;}
    .FRCC {Name: French; lang:fr-FR; SAMI_TYPE: CC;}
    #NORMAL {Name: Normal; font-family: arial;}
    #GREENTEXT {Name: GreenText; color:green; font-family: verdana;}
-->
</STYLE>
</Head>
<BODY>
<Sync Start=1000>
    <P CLASS="ENCC">One
    <P CLASS="FRCC">Un

<Sync Start=2000>
    <P CLASS="ENCC">Two
    <P CLASS="FRCC">Deux

<Sync Start=3000>
    <P CLASS="ENCC">Three
    <P CLASS="FRCC">Trois
</BODY>
</SAMI>

STYLE タグは、英語 (.ENCC) とフランス語 (.FRCC) の 2 つの言語設定を定義する。また、#NORMAL および #GREENTEXT という 2 つのスタイルも定義する。各 SYNC タグは、キャプションの開始タイムをミリ秒で定義する。P タグはキャプション テキストを格納し、CLASS 属性はキャプションの言語設定を指定する。

フィルタは、各言語とスタイルについて 1 つの論理ストリームを作成する。常に、1 つの言語ストリームと 1 つのスタイル ストリームが有効である。フィルタがサンプルを生成する際は、現在の言語のキャプションを選択し、現在のスタイルを適用する。デフォルトでは、ファイルで宣言する最初の言語とスタイルが有効になる。アプリケーションは IAMStreamSelect::Enable メソッドを使って、異なるストリームを有効にできる。

既定の設定では、サンプル ファイルの最初のキャプションによって、次の出力が作成される。

<P STYLE=" Name: English; lang:en-US; SAMI_TYPE: CC; Name: Normal; font-family: arial;">One

出力が内部スクリプト コマンド レンダラに送られると、このフィルタは EC_OLE_EVENT イベント通知を送る。2 つ目のイベント パラメータは、キャプション テキストを持つ BSTR である。アプリケーションは、イベントを取得してキャプションを表示できる。

次のサンプル コードは、SAMI ファイルのレンダリング方法、ストリーム情報の取得方法、ストリームを有効にする方法、キャプション テキストの表示方法について示している。この例では、以前の SAMI ファイルが C:\Sami_test_file.sami として保存されていることを想定している。

簡潔にするために、このサンプル コードでは、IAMStreamSelect::Enable メソッドを呼び出す際にハード コーディングされたストリーム インデックスを使っている。また、最小限のエラー チェックを実行する。

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

    CoInitialize(NULL);
    
        // フィルタ グラフ マネージャを作成する。
    CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, 
                        IID_IGraphBuilder, (void **)&pGraph);
    pGraph->QueryInterface(IID_IMediaControl, (void **)&pMediaControl);
    pGraph->QueryInterface(IID_IMediaEventEx, (void**)&pEv);

        // グラフを作成し、SAMI パーサーを探す。
    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);

                        // フランス語および "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);
                if (hr == S_OK)
                {
                    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();
}

このフィルタは、IAsyncReader インターフェイスを使ってソース フィルタからサンプルを取得している。そのため、このフィルタは、入力ピン上で IMemInputPin インターフェイスをサポートしていない。