處理 DVD 文字字串
[與此頁面相關聯的功能,DirectShow是舊版功能。 它已被 MediaPlayer、IMFMediaEngine和媒體基礎中的音訊/視訊擷取 取代。 這些功能已針對 Windows 10 和 Windows 11 進行優化。 Microsoft強烈建議新程式代碼盡可能在媒體 基礎中使用 MediaPlayer、IMFMediaEngine 和 音訊/視訊擷取,而不是 DirectShow。 Microsoft建議使用舊版 API 的現有程式代碼,盡可能改寫成使用新的 API。]
某些 DVD 光碟,特別是卡拉OK光碟,可能包含一份文字字串清單,以補充視訊或音訊內容。 這些文字字串包含內容的相關元數據,例如歌曲標題、藝術家名稱、內容類型資訊等等。 文字字串可以存在於多種語言中。 這些字串是選擇性的,而且許多光碟沒有這些字串。
若要從 DVD 取得文字字串,請使用 IDvdInfo2 介面,這個介面由 DVD 導覽器提供。 您實際上不需要建置 DVD 播放圖形來擷取文字字串。 您可以直接建立 DVD 導覽器、設定 DVD 磁碟區,然後呼叫相關的文字字串方法:
方法 | 描述 |
---|---|
IDvdInfo2::GetDVDTextNumberOfLanguages | 取得有文字字串的語言數目。 |
IDvdInfo2:GetDVDTextLanguageInfo | 取得單一語言文字字串的相關信息。 |
IDvdInfo2::GetDVDTextStringAsUnicode | 依索引取得指定語言的文字字串。 |
IDvdInfo2::GetDVDTextStringAsNative | 取得文字字串做為原始位元組陣列。 如果文字字串使用 GetDVDTextStringAsUnicode不支援的字元編碼,請使用這個方法。 |
以下是取得文字字串的基本程式:
- 呼叫 IDvdInfo2::GetDVDTextNumberOfLanguages,以尋找文字字元串出現的語言總數。 如果數位為零,表示 DVD 沒有任何文字字串。 (事實上,這可能是最常見的情況。
- 如果語言數目至少為一種,請呼叫 IDvdInfo2::GetDVDTextLanguageInfo 以取得每個語言的相關信息。 語言是由索引所指定。 方法會傳回該語言的文字字串總數、語言的地區設定標識碼(LCID),以及字元編碼(Unicode 或其他)。 DVD 文字字串可以使用數個不同的字元集:這些會列在 DVD_TextCharSet 列舉中。
- 若要取得文字字串,請呼叫 IDvdInfo2::GetDVDTextStringAsUnicode 或 IDvdInfo2::GetDVDTextStringAsNative。 第一個方法會傳回寬字元字串,但不支援每個字元集。 第二個方法會傳回包含原始文字數據的位元組陣列。 對於這兩種方法,您可以使用一個設為 NULL 的緩衝區指標呼叫方法,以確定字串的大小和文字類型。 然後配置緩衝區,然後再次呼叫 方法以取得字串。
每個文字字串都有相關聯的標識碼,表示文字字串串的意義。 標識碼會以 DVD_TextStringType 值傳回。 識別碼有兩種類別:結構識別碼 和 內容識別碼。 結構識別碼具有數值代碼範圍0x00–0x02F。 內容標識碼的範圍在0x30及以上。 (DVD_TextStringType 列舉會定義最常見的標識符子集,但 IDvdInfo2 方法可以傳回任何標識符碼。結構標識符描述 DVD 的邏輯部分,例如磁碟區、標題或標題的一部分(PTT)。 內容標識元表示特定文字字串的意義,例如電影標題、歌曲標題或內容類型。
結構標識碼沒有相關聯的文字字串。 當結構標識碼出現在文字字串數據中時,它會指出下列文字字串會套用至 DVD 的該邏輯部分,直到下一個結構標識元為止。 文字數據中結構標識碼的位置會對應至 DVD 磁碟區的邏輯階層。 例如,第一個出現的DVD_Struct_Title標識符 (0x02) 代表磁碟區中的第一個標題,而下一個出現代表第二個標題。
下表顯示文字字串如何針對具有兩個標題的 DVD 定義。
DVD_TextStringType | 文字字串 | 描述 |
---|---|---|
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” | 第二個標題的名稱。 |
GetDVDTextStringAsUnicode 和 GetDVDTextStringAsNative 方法會將結構識別符和內容識別符視為相同。 唯一的差別在於結構標識符,相關聯的文字緩衝區是空的。 應用程式必須追蹤文字字串與 DVD 邏輯部分之間的關聯性。
下列範例示範如何從 DVD 取得文字字串。 此範例會忽略實際應用程式需要的某些詳細數據。 (例如,它會忽略結構標識碼。)此範例只是為了顯示正確的呼叫順序。
#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 應用程式中 CDvdCore::GetDvdText 方法示範列舉和顯示 DVD 文字字串的基本步驟。
相關主題