Работа с текстовыми строками 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 Возвращает текстовую строку в виде необработанного массива байтов. Используйте этот метод, если в текстовой строке используется кодировка символов, не поддерживаемая GetDVDTextStringAsUnicode.

 

Ниже приведена базовая процедура получения текстовых строк.

  1. Вызовите IDvdInfo2::GetDVDTextNumberOfLanguages , чтобы найти общее количество языков, на которых отображаются текстовые строки. Если число равно нулю, это означает, что DVD-диск не содержит текстовых строк. (На самом деле это, пожалуй, самый распространенный случай.)
  2. Если число языков не меньше одного, вызовите IDvdInfo2::GetDVDTextLanguageInfo , чтобы получить сведения о каждом языке. Язык определяется индексом. Метод возвращает общее количество текстовых строк на этом языке, идентификатор языкового стандарта (LCID) для языка и кодировку символов (Юникод или другое). Текстовые строки DVD могут использовать несколько разных наборов символов; Они перечислены в DVD_TextCharSet Перечисление.
  3. Чтобы получить текстовую строку, вызовите метод 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-форума.

Метод CDvdCore::GetDvdText в приложении DVDSample демонстрирует основные шаги по перечислению и отображению текстовых строк DVD.

Dvd-приложения