共用方式為


使用 DVD 文字字串

[與此頁面 相關的功能 DirectShow是舊版功能。 它已被 MediaPlayerIMFMediaEngineMedia Foundation 中的音訊/視訊擷取取代。 這些功能已針對Windows 10和Windows 11進行優化。 Microsoft 強烈建議新程式碼盡可能使用 MediaPlayerIMFMediaEngine音訊/視訊擷取 ,而不是 DirectShow。 Microsoft 建議盡可能重寫使用舊版 API 的現有程式碼,以使用新的 API。]

某些 DVD 光片,特別是易失的光碟,可能包含一份文字字串清單,以補充視訊或音訊內容。 這些文字字串包含內容的相關中繼資料,例如歌曲標題、音樂人名稱、內容類型資訊等等。 文字字串可以有多個語言存在。 這些字串是選擇性的,而且許多光碟沒有它們。

若要從 DVD 擷取文字字串,請使用DVD 導覽器所公開的ICdInfo2介面。 您實際上不需要建置 DVD 播放圖形來擷取文字字串。 您可以直接建立 DVD 導覽器、設定 DVD 音量,然後呼叫相關的文字字串方法:

方法 Description
IHttpInfo2::GetTextNumberOfLanguages 取得有文字字串的語言數目。
IHttpInfo2::GetTextLanguageInfo 取得單一語言之文字字串的相關資訊。
IJAVAInfo2::GetJA加值稅extStringAsUnicode 依索引取得指定語言的文字字串。
IWindowsInfo2::GetRATextStringAsNative 取得文字字串做為原始位元組陣列。 如果文字字串使用 GetWATextStringAsUnicode不支援的字元編碼,請使用這個方法。

 

以下是取得文字字串的基本程式:

  1. 呼叫 IInfo2::GetTextNumberOfLanguages 來尋找文字字串顯示的語言總數。 如果數位為零,表示 DVD 沒有任何文字字串。 (這可能是最常見的案例。)
  2. 如果語言數目至少為一種,請呼叫 IHttpInfo2::GetTextLanguageInfo 以取得每個語言的相關資訊。 語言是由索引所指定。 方法會傳回該語言的文字字串總數、語言的地區設定識別碼 (LCID) ,以及 unicode 或其他) 的字元編碼 (。 DVD 文字字串可以使用數個不同的字元集;這些會列在 DVD_TextCharSet 列舉中。
  3. 若要取得文字字串,請呼叫 IJAVAInfo2::GetJA加值稅extStringAsUnicodeIJAVAInfo2::GetJA加值稅extStringAsNative。 第一個方法會傳回寬字元字串,但不支援每個字元集。 第二個方法會傳回包含原始文字資料的位元組陣列。 針對這兩種方法,您可以使用 Null 緩衝區指標呼叫 方法,以尋找字串和文字類型的大小。 然後配置緩衝區,然後再次呼叫 方法以取得字串。

每個文字字串都有相關聯的識別碼代碼,表示文字字串的意義。 識別碼會以 DVD_TextStringType 值傳回。 識別碼有兩種類別: 結構識別碼內容識別碼。 結構識別碼的範圍0x00-0x02F中有數值碼。 內容識別碼的範圍0x30及更新版本。 (DVD_TextStringType 列舉會定義最常見識別碼的子集,但 ICdInfo2 方法可以傳回任何識別碼代碼。) 結構識別碼描述 DVD 的邏輯部分,例如磁片區、標題或 (PTT) 的標題部分。 內容識別碼表示特定文字字串的意義,例如電影標題、歌曲標題或內容類型。

結構識別碼沒有相關聯的文字字串。 當結構識別碼出現在文字字串資料中時,它會表示下列文字字串會套用至 DVD 的該邏輯部分,直到下一個結構識別碼為止。 文字資料中結構識別碼的位置會對應至 DVD 磁片區的邏輯階層。 例如,第一次出現DVD_Struct_Title識別碼 (0x02) 代表磁片區中的第一個標題,而下一個出現專案則代表第二個標題。

下表顯示如何使用兩個標題為 DVD 定義文字字串。

DVD_TextStringType 文字字串 Description
DVD_Struct_Volume (0x01) "" 整個光碟端的結構識別碼。
DVD_General_Name (0x30) 「DVD 磁片區」 DVD 音量名稱。
DVD_Struct_Title (0x02) "" 第一個標題的結構識別碼。
DVD_General_Name (0x30) 「標題 1」 第一個標題的名稱。
DVD_Struct_Title (0x02) "" 第二個標題的結構識別碼。
DVD_General_Name (0x30) 「標題 2」 第二個標題的名稱。

 

GetRATextStringAsUnicodeGetJA加值稅extStringAsNative方法會將結構識別碼和內容識別碼視為相同。 唯一的差別在於,針對結構識別碼,相關聯的文字緩衝區是空的。 應用程式可以追蹤文字字串與 DVD 邏輯部分之間的關聯性。

下列範例示範如何從 DVD 取得文字字串。 此範例會忽略實際應用程式需要的某些詳細資料。 (例如,它會忽略結構 identifiers.) 此範例只是為了顯示正確的呼叫順序。

#define CHECK_HR(hr) if (FAILED(hr)) { goto done; }
#define SAFE_ARRAY_DELETE(x) { if (x != NULL) { delete [] x; x = NULL; } }

HRESULT GetDVDTextStrings()
{
    HRESULT hr = S_OK;
    ULONG cLangs = 0;       // Number of languages.
    ULONG cStrings = 0;     // Number of text strings.
    ULONG cchBuffer = 0;    // Buffer size.
    ULONG cchActual = 0;    // Actual string size.

    LCID lcid;              // Locale identifier.
    DVD_TextCharSet     characterSet;
    DVD_TextStringType  stringType;

    WCHAR *pszBuffer = NULL;

    CComPtr<IBaseFilter> pFilter;
    CComPtr<IDvdInfo2> pInfo;
    CComPtr<IDvdControl2> pControl;

    // Set up the DVD Navigator.
    CHECK_HR(hr = pFilter.CoCreateInstance(CLSID_DVDNavigator));
    CHECK_HR(hr = pFilter.QueryInterface(&pInfo));
    CHECK_HR(hr = pFilter.QueryInterface(&pControl));
    CHECK_HR(hr = pControl->SetDVDDirectory(NULL));

    // Find the number of text-string languages.
    CHECK_HR(hr = pInfo->GetDVDTextNumberOfLanguages(&cLangs));
    if (cLangs == 0)
    {
        return S_FALSE; // No text strings.
    }

    // Get information about the 0'th language.
    CHECK_HR(hr = pInfo->GetDVDTextLanguageInfo(
        0, &cStrings, &lcid, &characterSet));

    // First check if this character set is compatible with the 
    // GetDVDTextStringAsUnicode method.

    if (characterSet == DVD_CharSet_Unicode || 
        characterSet == DVD_CharSet_ISO646)
    {
        // Loop through all of the strings.
        for (ULONG i = 0; i < cStrings; i++)
        {
            // Get the i'th string for the 0'th language.

            // Find the required buffer size and the string type.
            CHECK_HR(hr = pInfo->GetDVDTextStringAsUnicode(
                0,            // Language index.
                i,            // String index.
                NULL,         // Pass NULL pointer to get the buffer size.
                0,            // Size of the buffer we are passing in.
                &cchBuffer,   // Receives the required buffer size.
                &stringType   // Receives the identifier code.
                ));

            // Skip structure identifiers (0x00 - 0x2F).
            if ((cchBuffer > 0) && (stringType >= 0x30))
            {
                // Allocate a buffer and get the text string.
                pszBuffer = new WCHAR[cchBuffer];
                if (pszBuffer == NULL)
                {
                    CHECK_HR(hr = E_OUTOFMEMORY);
                }

                CHECK_HR(hr = pInfo->GetDVDTextStringAsUnicode(
                    0, i, pszBuffer, cchBuffer, &cchActual, &stringType));

                // TODO: Display the text string.

                SAFE_ARRAY_DELETE(pszBuffer);
            }
        }
    }

done:
    SAFE_ARRAY_DELETE(pszBuffer);
    return hr;
}

如需 DVD 文字字串的資訊,請參閱 DVD 論壇的網站

DVDSample 應用程式中的 CCore::GetHttpText 方法示範列舉和顯示 DVD 文字字串的基本步驟。

DVD 應用程式