SAMI (CC) パーサー フィルタ
SAMI (Synchronized Accessible Media Interchange) ファイルからのキャプション データを解析する。
SAMI は、HTML に似たテキスト フォーマットであり、タイム ベース キャプションのエンコードに使われる。このフィルタは、SAMI データをテキスト ストリームに変換する。ストリームの各サンプルには、1 つのキャプション エントリとフォーマット情報が含まれている。サンプルのタイム スタンプは、SAMI ファイルのタイム情報から生成される。
このフィルタは、内部スクリプト コマンド レンダリング フィルタと共に使うように設計されている。内部スクリプト コマンド レンダラは、テキスト サンプルを受け取り、イベント通知としてアプリケーションに送る。詳細については、「注意」を参照すること。
フィルタ インターフェイス | IAMStreamSelect、IBaseFilter |
入力ピン メディア タイプ | MEDIATYPE_Stream |
入力ピン インターフェイス | IPin、IQualityControl |
出力ピン メディア タイプ | MEDIATYPE_Text、MEDIASUBTYPE_NULL |
出力ピン インターフェイス | IMediaSeeking、IPin、IQualityControl |
フィルタ 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 インターフェイスをサポートしていない。