マーカーの使用

[このページに関連付けられている機能である Windows Media Format 11 SDK は、レガシ機能です。 これは、ソース リーダーシンク ライターによって置き換えられます。 ソース リーダーシンク ライターは、Windows 10とWindows 11用に最適化されています。 新しいコードでは、可能であれば、Windows Media Format 11 SDK ではなくソース リーダーシンク ライターを使用することを強くお勧めします。 Microsoft は、従来の API を使用する既存のコードを、可能であれば新しい API を使用するように書き直すよう提案しています。]

マーカーは、ASF ファイル内の名前付きポイントです。 各マーカーは、名前と関連付けられた時刻で構成され、ファイルの先頭からのオフセットとして測定されます。 アプリケーションでは、マーカーを使用して、コンテンツ内のさまざまなポイントに名前を割り当て、それらの名前をユーザーに表示し、マーカーの位置をシークできます。 アプリケーションは、既存の ASF ファイルに対してマーカーを追加または削除できます。

IWMHeaderInfo インターフェイスには、マーカーを操作するためのメソッドが含まれています。 メタデータ エディター オブジェクトでは、マーカーの追加と削除がサポートされています。 ライター オブジェクトとリーダー オブジェクトはマーカーを取得できますが、マーカーを追加または削除することはできません。

マーカーの追加

マーカーを追加するには、 IWMHeaderInfo インターフェイスのメタデータ エディターにクエリを実行します。 次に IWMHeaderInfo::AddMarker メソッドを呼び出し、マーカー名をワイド文字列として指定し、時刻を 100 ナノ秒単位で指定します。 時間は、ファイルの期間を超えてはなりません。 2 つのマーカーが同じ時間を持つことができます。

次の例では、複数のマーカーをファイルに追加します。

IWMMetadataEditor *pEdit = 0;
IWMHeaderInfo     *pInfo = 0;

// Create the metadata editor object.

WMCreateEditor(&pEdit);
pEdit->Open(L"C:\\example.wmv");
pEdit->QueryInterface(IID_IWMHeaderInfo, (void**)&pInfo);

// Add the markers. Note that we add the last ones first. Do this when possible
// for improved performance when writing the markers to the file.
hr = pInfo->AddMarker(L"End",  520000000);   // 52 sec.
hr = pInfo->AddMarker(L"Segue",  350000000); // 35 sec.
hr = pInfo->AddMarker(L"Intro",  15000000);  // 1.5 sec.

// Commit changes and clean up.

pEdit->Flush();
pEdit->Close(); 
pInfo->Release();
pEdit->Release();

マーカーの削除

マーカーを削除するには、削除するマーカーのインデックスを指定して IWMHeaderInfo::RemoveMarker を呼び出します。 マーカーは時間の増加順に自動的に並べ替えられるため、インデックス 0 は常に最初のマーカーです。 RemoveMarker を呼び出すと、後に続くマーカーのインデックス番号が変更されることに注意してください。 pInfoIWMHeaderInfo インターフェイスへのポインターである次のコードは、ファイルからすべてのマーカーを削除します。

WORD count = 0;
pInfo->GetMarkerCount(&count);
while (count--)
{
    pInfo->RemoveMarker(0);
}

マーカーの取得

マーカーの名前と時刻を取得するには、次の手順を実行します。

  1. IWMHeaderInfo::GetMarkerCount メソッドを呼び出して、ファイルに含まれるマーカーの数を確認します。
  2. マーカー名を含めるために必要な文字列のサイズを取得します。 これを行うには、 IWMHeaderInfo::GetMarker メソッドを 呼び出します。 取得するマーカーのインデックスを指定し、文字列バッファーに NULL を 指定します ( pwszMarkerName パラメーター)。 メソッドは、 pcchMarkerNameLen パラメーターで、終端の '\0' 文字を含む文字列の長さを返します。
  3. 名前を受け取るワイド文字列を割り当てます。
  4. GetMarker をもう一度呼び出しますが、今回は pwszMarkerName パラメーターの文字列のアドレスを渡します。 メソッドは、マーカー名を文字列に書き込み、 pcnsMarkerTime パラメーターでマーカーの時刻を返します。

次のコードは、すべてのマーカーを順番にループ処理し、名前と時刻を取得します。

WORD cMarkers = 0;
HRESULT hr = pInfo->GetMarkerCount(&cMarkers);

WCHAR *wszName = 0;
WORD  len = 0;
for (WORD iMarker = 0; iMarker < cMarkers; ++iMarker)
{
    QWORD rtTime = 0;
    WORD req_len = 0;
    hr = pInfo->GetMarker(iMarker, 0, &req_len, &rtTime);
    
    // Reallocate if necessary.
    if (len < req_len)
    {
        delete[] wszName;
        wszName = new WCHAR[req_len];
        len = req_len;
    }
    hr = pInfo->GetMarker(iMarker, wszName, &req_len, &rtTime);
    // Display the name...
}
delete[] wszName;

マーカーのシーク

マーカーの場所から再生を開始するには、マーカーのインデックスを指定して、リーダー オブジェクトの IWMReaderAdvanced2::StartAtMarker メソッドを呼び出します。 残りのパラメーターは、 IWMReader::Start メソッドのパラメーターと同じです。 次の例では、 リーダーに IWMReaderAdvanced2 インターフェイスを照会し、最初のマーカーをシークします。

IWMReaderAdvanced2 *pReader2 = 0
WORD iMarkerIndex = 0;
hr = pReader->QueryInterface(IID_IWMReaderAdvanced2, (void**)&pReader2);
if (SUCCEEDED(hr))
{
    hr = pPlayer2->StartAtMarker(iMarkerIndex, 0, 1.0, 0);
    pPlayer2->Release();
}

IWMHeaderInfo インターフェイス

IWMReaderAdvanced2::StartAtMarker

メタデータの操作