使用 DVD 文字字串
[與此頁面 相關的功能 DirectShow是舊版功能。 它已被 MediaPlayer、 IMFMediaEngine和 Media Foundation 中的音訊/視訊擷取取代。 這些功能已針對Windows 10和Windows 11進行優化。 Microsoft 強烈建議新程式碼盡可能使用 MediaPlayer、 IMFMediaEngine 和 音訊/視訊擷取 ,而不是 DirectShow。 Microsoft 建議盡可能重寫使用舊版 API 的現有程式碼,以使用新的 API。]
某些 DVD 光片,特別是易失的光碟,可能包含一份文字字串清單,以補充視訊或音訊內容。 這些文字字串包含內容的相關中繼資料,例如歌曲標題、音樂人名稱、內容類型資訊等等。 文字字串可以有多個語言存在。 這些字串是選擇性的,而且許多光碟沒有它們。
若要從 DVD 擷取文字字串,請使用DVD 導覽器所公開的ICdInfo2介面。 您實際上不需要建置 DVD 播放圖形來擷取文字字串。 您可以直接建立 DVD 導覽器、設定 DVD 音量,然後呼叫相關的文字字串方法:
方法 | Description |
---|---|
IHttpInfo2::GetTextNumberOfLanguages | 取得有文字字串的語言數目。 |
IHttpInfo2::GetTextLanguageInfo | 取得單一語言之文字字串的相關資訊。 |
IJAVAInfo2::GetJA加值稅extStringAsUnicode | 依索引取得指定語言的文字字串。 |
IWindowsInfo2::GetRATextStringAsNative | 取得文字字串做為原始位元組陣列。 如果文字字串使用 GetWATextStringAsUnicode不支援的字元編碼,請使用這個方法。 |
以下是取得文字字串的基本程式:
- 呼叫 IInfo2::GetTextNumberOfLanguages 來尋找文字字串顯示的語言總數。 如果數位為零,表示 DVD 沒有任何文字字串。 (這可能是最常見的案例。)
- 如果語言數目至少為一種,請呼叫 IHttpInfo2::GetTextLanguageInfo 以取得每個語言的相關資訊。 語言是由索引所指定。 方法會傳回該語言的文字字串總數、語言的地區設定識別碼 (LCID) ,以及 unicode 或其他) 的字元編碼 (。 DVD 文字字串可以使用數個不同的字元集;這些會列在 DVD_TextCharSet 列舉中。
- 若要取得文字字串,請呼叫 IJAVAInfo2::GetJA加值稅extStringAsUnicode 或 IJAVAInfo2::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」 | 第二個標題的名稱。 |
GetRATextStringAsUnicode和GetJA加值稅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 文字字串的基本步驟。
相關主題