Работа с текстовыми строками DVD
[Функция, связанная с этой страницей, DirectShow, является устаревшей функцией. Он был заменён MediaPlayer, IMFMediaEngineи аудио/видео захватом в Media Foundation. Эти функции оптимизированы для Windows 10 и Windows 11. Корпорация Майкрософт настоятельно рекомендует по возможности использовать в новом коде MediaPlayer, IMFMediaEngine и аудио-видеозахват в Media Foundation вместо DirectShow. Корпорация Майкрософт предлагает, что существующий код, использующий устаревшие API, будет перезаписан для использования новых API, если это возможно.]
Некоторые DVD-диски, особенно караоке-диски, могут содержать список текстовых строк для дополнения видео или звукового содержимого. Эти текстовые строки содержат метаданные о содержимом, такие как названия песен, имена художников, сведения о жанре и т. д. Текстовые строки могут присутствовать на нескольких языках. Эти строки являются необязательными, и многие диски не имеют их.
Чтобы получить текстовые строки из DVD-диска, используйте интерфейс IDvdInfo2, который предоставляется DVD-навигатором. На самом деле вам не нужно создавать граф воспроизведения DVD для получения текстовых строк. Вы можете просто создать DVD-навигатор, задать том DVD, а затем вызвать соответствующие методы текстовой строки:
Метод | Описание |
---|---|
IDvdInfo2::GetDVDTextNumberOfLanguages | Возвращает количество языков, для которых существуют текстовые строки. |
IDvdInfo2::GetDVDTextLanguageInfo | Возвращает сведения о текстовых строках для одного языка. |
IDvdInfo2::GetDVDTextStringAsUnicode | Возвращает текстовую строку для указанного языка по индексу. |
IDvdInfo2::GetDVDTextStringAsNative | Возвращает текстовую строку в виде необработанного массива байтов. Используйте этот метод, если текстовая строка использует кодировку символов, не поддерживаемую GetDVVDTextStringAsUnicode. |
Ниже приведена базовая процедура получения текстовых строк:
- Вызовите IDvdInfo2::GetDVDTextNumberOfLanguages, чтобы найти общее количество языков, в которых отображаются текстовые строки. Если число равно нулю, это означает, что DVD-диск не имеет текстовых строк. (Это, возможно, самый распространенный случай, на самом деле.)
- Если число языков по крайней мере одно, вызовите IDvdInfo2::GetDVDTextLanguageInfo, чтобы получить сведения о каждом языке. Язык указывается индексом. Метод возвращает общее количество текстовых строк на этом языке, идентификатор языкового стандарта (LCID) для языка и кодировку символов (Юникод или другое). Текстовые строки 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 (0x30) | "Заголовок 1" | Название первого тайтла. |
DVD_Struct_Title (0x02) | "" | Идентификатор структуры для второго заголовка. |
DVD_Общее_Имя (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-форума.
Метод CDvdCore::GetDvdText в приложении DVDSample демонстрирует основные шаги в перечислении и отображении текстовых строк DVD.
Связанные разделы