使用标记
[与此页面关联的功能 Windows Media Format 11 SDK 是旧版功能。 它已被源读取器和接收器编写器取代。 源读取器和接收器编写器已针对Windows 10和Windows 11进行了优化。 Microsoft 强烈建议新代码尽可能使用源读取器和接收器编写器,而不是 Windows Media Format 11 SDK。 如果可能,Microsoft 建议重写使用旧 API 的现有代码以使用新 API。]
标记是 ASF 文件中的命名点。 每个标记由一个名称和一个关联时间组成,以与文件开头的偏移量度量。 应用程序可以使用标记为内容中的不同点分配名称,向用户显示这些名称,然后查找标记位置。 应用程序可以在现有 ASF 文件中添加或删除标记。
IWMHeaderInfo 接口包含用于处理标记的方法。 元数据编辑器对象支持添加和删除标记。 编写器和读取器对象可以检索标记,但不能添加或删除标记。
添加标记
若要添加标记,请在元数据编辑器中查询 IWMHeaderInfo 接口。 然后调用 IWMHeaderInfo::AddMarker 方法,将标记名称指定为宽字符字符串,时间以 100 纳秒为单位。 时间不得超过文件持续时间。 两个标记可以具有相同的时间。
以下示例将多个标记添加到文件:
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 会更改后续任何标记的索引号。 以下代码(其中 pInfo 是指向 IWMHeaderInfo 接口的指针)从文件中删除所有标记:
WORD count = 0;
pInfo->GetMarkerCount(&count);
while (count--)
{
pInfo->RemoveMarker(0);
}
检索标记
若要检索标记的名称和时间,请执行以下步骤:
- 调用 IWMHeaderInfo::GetMarkerCount 方法以确定文件包含的标记数。
- 检索包含标记名称所需的字符串大小。 为此,请调用 IWMHeaderInfo::GetMarker 方法。 指定要检索的标记的索引, (pwszMarkerName 参数) 为字符串缓冲区的 NULL。 方法返回字符串的长度,包括 pcchMarkerNameLen 参数中的终止“\0”字符。
- 分配一个宽字符字符串以接收名称。
- 再次调用 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();
}
相关主题