在视频文件中嵌入目录

本主题演示如何创建目录 (TOC) 并将其嵌入视频文件中。 为使示例代码保持简短,目录非常简单:它只包含一个条目,并且该条目填充了最少的信息。

若要创建目录并将其嵌入文件,必须通过调用 CoCreateInstance 创建以下四个对象。

  • TOC 条目
  • TOC 条目列表
  • 目录
  • TOC 分析程序

对象的类标识符在 目录分析器的类标识符中提供。

首先,使用描述视频文件的一部分的信息填充 TOC 条目。 将 TOC 条目添加到 TOC 条目列表,然后将 TOC 条目列表添加到 TOC。 最后,将 TOC 添加到 TOC 分析程序,后者提供用于在视频文件中嵌入 TOC 的功能。 以下列表提供了更详细的步骤。

  1. 创建 TOC Entry 对象并获取其上的 ITocEntry 接口。
  2. 填充 TOC_ENTRY_DESCRIPTOR 结构并将其传递给 ITocEntry::SetDescriptor
  3. 创建 TOC 条目列表对象并获取其上的 ITocEntryList 接口。
  4. 通过调用 ITocEntryList::AddEntryByIndex,将步骤 1 中创建的 TOC Entry 对象添加到 TOC 条目列表对象。
  5. 创建 TOC 对象并获取其 上的 IToc 接口。
  6. 通过调用 IToc::AddEntryListByIndex,将步骤 3 中创建的 TOC 条目列表对象添加到 TOC 对象。
  7. 创建 TOC Parser 对象并获取其上的 ITocParser 接口。
  8. 调用 ITocParser::Init 以初始化 TOC Parser 对象并将其与视频文件关联。
  9. 通过调用 ITocParser::AddToc 将步骤 5 中创建的 TOC 对象添加到 TOC 分析器对象。
  10. 通过调用 ITocParser::Commit 将目录嵌入视频文件中。

以下代码演示上述列表中提供的步骤。

#include <wmcodecdsp.h>
HRESULT InitTocParserAndCommit(IToc* pToc);

void main()
{
   HRESULT hr = CoInitialize(NULL);
   
   if(SUCCEEDED(hr))
   {    
      ITocEntry* pEntry = NULL;
      hr = CoCreateInstance(CLSID_CTocEntry, NULL, 
         CLSCTX_INPROC_SERVER, IID_ITocEntry, (VOID**)&pEntry); 

      if(SUCCEEDED(hr))
      {
         TOC_ENTRY_DESCRIPTOR tocDesc = {0};
         tocDesc.qwStartTime = 4; 
         tocDesc.qwEndTime = 8;
         pEntry->SetDescriptor(&tocDesc); // HRESULT ignored for simplicity.    
    
         ITocEntryList* pEntryList = NULL;
         hr = CoCreateInstance(CLSID_CTocEntryList, NULL, 
            CLSCTX_INPROC_SERVER, IID_ITocEntryList, (VOID**)&pEntryList);

         if(SUCCEEDED(hr))
         {
            pEntryList->AddEntryByIndex(0, pEntry); // HRESULT ignored.
      
            IToc* pToc = NULL;
            hr = CoCreateInstance(CLSID_CToc, NULL, 
               CLSCTX_INPROC_SERVER, IID_IToc, (VOID**)&pToc);

            if(SUCCEEDED(hr))
            {
               pToc->AddEntryListByIndex(0, pEntryList); // HRESULT ignored.
               hr = InitTocParserAndCommit(pToc);
            }
         }
      }
     
      CoUninitialize();
   }
}

HRESULT InitTocParserAndCommit(IToc* pToc)
{
   ITocParser* pTocParser = NULL;
   HRESULT hr = CoCreateInstance(CLSID_CTocParser, NULL, 
      CLSCTX_INPROC_SERVER, IID_ITocParser, (VOID**)&pTocParser);

   if(SUCCEEDED(hr))
   {
      hr = pTocParser->Init(L"\\\\?\\c:\\experiment\\seattle.wmv");

      if(SUCCEEDED(hr))
      {
         DWORD tocIndex = 0;
         hr = pTocParser->AddToc(TOC_POS_TOPLEVELOBJECT, pToc, &tocIndex);

         if(SUCCEEDED(hr))
         {
            hr = pTocParser->Commit();
         }
      }

      pTocParser->Release();
      pTocParser = NULL;
   }

   return hr;
}

从视频文件读取目录

目录分析器对象

目录分析程序编程指南