使用同步讀取器讀取檔案

[與此頁面相關聯的功能 Windows Media Format 11 SDK是舊版功能。 來源讀取器和接收寫入器已取代它。 來源讀取器和接收寫入器已針對Windows 10和Windows 11進行優化。 Microsoft 強烈建議新程式碼盡可能使用來源讀取器和接收寫入器,而不是Windows Media Format 11 SDK。 Microsoft 建議盡可能重寫使用舊版 API 的現有程式碼,以使用新的 API。]

您可以使用同步讀取器,使用同步呼叫來讀取 ASF 檔案,而不是讀取器物件中的非同步方法。 使用同步呼叫可減少讀取檔案所需的執行緒數目。 非同步讀取器會使用多個執行緒來處理資料流程。 對於具有多個資料流程的檔案,使用的執行緒數目可能會變得非常大。 同步讀取器只會使用一個執行緒。

同步讀取器的設計目的是要符合內容建立和檔案編輯應用程式的需求。 您可以將同步讀取器用於其他應用程式,但其功能有限。

同步讀取器可以使用 UNC 路徑名稱 (來開啟本機檔案或網路上的檔案,例如 「\\someshare\somedirectory\somefile.wmv」) 。 您無法將檔案串流處理至同步讀取器,或從網際網路位置開啟檔案。 同步讀取器也支援使用 IStream COM 介面作為來源。

同步讀取器提供比非同步讀取器更豐富的功能,從 ASF 檔案擷取樣本。 同步讀取器可以依資料流程編號和輸出來傳遞樣本。 資料流程編號所傳遞的樣本可以壓縮或取消壓縮。 同步讀取器也可以在播放期間,在壓縮和未壓縮的傳遞之間切換;這項功能稱為「快速編輯」。此功能可讓編輯應用程式讀取以 Windows 媒體為基礎的內容,並將它直接傳遞至寫入器,直到達到所需的畫面為止。 此時,應用程式可以告訴讀取器開始傳遞未壓縮的內容,應用程式接著可以修改並傳遞至寫入器以進行重新壓縮。 當應用程式完成修改指定的畫面格時,它可以告訴讀取器再次開始傳遞壓縮的畫面。

同步讀取器物件最基本的功能可以細分為下列步驟。 在這些步驟中,「應用程式」是指您使用 Windows 媒體格式 SDK 撰寫的程式。

  1. 應用程式會傳遞至同步讀取器要讀取的檔案名。 當同步讀取器開啟檔案時,它會將輸出號碼指派給每個資料流程。 如果檔案使用互斥,讀取器會為所有互斥資料流程指派單一輸出。
  2. 應用程式會從讀取器取得各種輸出組態的相關資訊。 收集到的資訊可讓應用程式正確轉譯媒體範例。
  3. 應用程式會從同步讀取器開始要求範例,一次一個。 同步讀取器會在緩衝區物件中傳遞其 INSSBuffer 介面的每個範例。
  4. 應用程式負責在讀取器傳遞資料之後轉譯資料。 Windows 媒體格式 SDK 不提供任何轉譯常式。 一般而言,應用程式會使用其他 SDK 來轉譯資料,例如 Microsoft Direct X SDK,或 Microsoft Windows 平臺 SDK的多媒體功能。

WMSyncReader 範例應用程式中會說明這些步驟。 如需詳細資訊,請參閱 範例應用程式

同步讀取器也支援更進階的功能。 同步讀取器可讓您執行下列動作:

  • 指定要依時間或框架編號擷取的樣本範圍。
  • 控制互斥資料流程的資料流程選取。
  • 使用標準 COM 介面 IStream開啟檔案。
  • 從檔案標頭讀取設定檔資料。
  • 從檔案標頭讀取中繼資料。
  • 在播放期間切換資料流程和輸出範例。
  • 在播放期間切換壓縮和未壓縮的資料流程範例。

下列各節將詳細說明同步讀取器物件的使用方式。

範例程式碼

下列範例程式碼示範如何使用同步讀取器從 ASF 檔案讀取範例。 它會依框架編號指定要傳遞的樣本範圍。

IWMSyncReader* pSyncReader = NULL;
INSSBuffer*    pMyBuffer   = NULL;

QWORD cnsSampleTime = 0;
QWORD cnsSampleDuration = 0;
DWORD dwFlags = 0;
DWORD dwOutputNumber;
HRESULT hr = S_OK;

// Initialize COM.
hr = CoInitialize(NULL);

// Create a synchronous reader.
hr = WMCreateSyncReader(NULL, WMT_RIGHT_PLAYBACK, &pSyncReader);

// Open an ASF file.
hr = pSyncReader->Open(L"c:\\somefile.wmv");

// TODO: Identify the properties for each output. This works 
// exactly as it does with the asynchronous reader.

// Specify a playback range from frame number 100 of the video 
// stream to the end of the file. Assume that the video stream 
// is stream number 2.
hr = pSyncReader->SetRangeByFrame(2, 100, 0);

// Loop through all the samples in the specified range.
do
{
   // Get the next sample, regardless of its stream number.
   hr = pSyncReader->GetNextSample(0,
                                   &pMyBuffer,
                                   &cnsSampleTime,
                                   &cnsSampleDuration,
                                   &dwFlags,
                                   &dwOutputNumber,
                                   NULL);

   if(SUCCEEDED(hr))
   {
      // TODO: Process the sample in whatever way is appropriate 
      // to your application. When finished, clean up.
      pMyBuffer->Release();
      pMyBuffer = NULL;
      cnsSampleTime     = 0;
      cnsSampleDuration = 0;
      dwFlags           = 0;
      dwOutputNumber    = 0;
   }
} 
while (SUCCEEDED(hr));

pSyncReader->Release();
pSyncReader = NULL;

IWMSyncReader 介面

讀取 ASF 檔案

同步讀取器物件