DVD 텍스트 문자열 작업

[이 페이지와 연결된 기능인 DirectShow는 레거시 기능입니다. MediaPlayer, IMFMediaEngine 및 Media Foundation의 오디오/비디오 캡처로 대체되었습니다. 이러한 기능은 Windows 10 및 Windows 11 최적화되었습니다. 가능한 경우 새 코드가 DirectShow 대신 Media Foundation에서 MediaPlayer, IMFMediaEngine오디오/비디오 캡처를 사용하는 것이 좋습니다. 가능한 경우 레거시 API를 사용하는 기존 코드를 다시 작성하여 새 API를 사용하도록 제안합니다.]

일부 DVD 디스크, 특히 노래방 디스크에는 비디오 또는 오디오 콘텐츠를 보완하기 위한 텍스트 문자열 목록이 포함될 수 있습니다. 이러한 텍스트 문자열에는 노래 제목, 아티스트 이름, 장르 정보 등 콘텐츠에 대한 메타데이터가 포함됩니다. 텍스트 문자열은 둘 이상의 언어로 표시될 수 있습니다. 이러한 문자열은 선택 사항이며 많은 디스크에는 이러한 문자열이 없습니다.

DVD에서 텍스트 문자열을 검색하려면 DVD 탐색기에서 노출되는 IDvdInfo2 인터페이스를 사용합니다. 실제로 텍스트 문자열을 검색하기 위해 DVD 재생 그래프를 작성할 필요가 없습니다. DVD 탐색기를 만들고 DVD 볼륨을 설정한 다음 관련 텍스트 문자열 메서드를 호출할 수 있습니다.

메서드 Description
IDvdInfo2::GetDVDTextNumberOfLanguages 텍스트 문자열이 있는 언어 수를 가져옵니다.
IDvdInfo2::GetDVDTextLanguageInfo 한 언어의 텍스트 문자열에 대한 정보를 가져옵니다.
IDvdInfo2::GetDVDTextStringAsUnicode 인덱스별로 지정된 언어의 텍스트 문자열을 가져옵니다.
IDvdInfo2::GetDVDTextStringAsNative 텍스트 문자열을 원시 바이트 배열로 가져옵니다. 텍스트 문자열이 GetDVDTextStringAsUnicode에서 지원되지 않는 문자 인코딩을 사용하는 경우 이 메서드를 사용합니다.

 

다음은 텍스트 문자열을 가져오기 위한 기본 절차입니다.

  1. IDvdInfo2::GetDVDTextNumberOfLanguages를 호출하여 텍스트 문자열이 표시되는 총 언어 수를 찾습니다. 숫자가 0이면 DVD에 텍스트 문자열이 없음을 의미합니다. (아마도 가장 일반적인 경우일 것입니다.)
  2. 언어 수가 하나 이상인 경우 IDvdInfo2::GetDVDTextLanguageInfo 를 호출하여 각 언어에 대한 정보를 가져옵니다. 언어는 인덱스로 지정됩니다. 메서드는 해당 언어의 총 텍스트 문자열 수, 언어에 대한 로캘 식별자(LCID) 및 문자 인코딩(유니코드 또는 기타)을 반환합니다. DVD 텍스트 문자열은 여러 문자 집합을 사용할 수 있습니다. 이러한 항목은 DVD_TextCharSet 열거형에 나열됩니다.
  3. 텍스트 문자열을 얻으려면 IDvdInfo2::GetDVDTextStringAsUnicode 또는 IDvdInfo2::GetDVDTextStringAsNative를 호출합니다. 첫 번째 메서드는 와이드 문자열을 반환하지만 모든 문자 집합을 지원하지는 않습니다. 두 번째 메서드는 원시 텍스트 데이터를 포함하는 바이트 배열을 반환합니다. 두 메서드 모두 NULL 버퍼 포인터를 사용하여 메서드를 호출하여 문자열의 크기와 텍스트 형식을 찾을 수 있습니다. 그런 다음 버퍼를 할당하고 메서드를 다시 호출하여 문자열을 가져옵니다.

각 텍스트 문자열에는 텍스트 문자열의 의미를 나타내는 연결된 식별자 코드가 있습니다. 식별자는 DVD_TextStringType 값으로 반환됩니다. 식별자에는 구조 식별자콘텐츠 식별자의 두 가지 범주가 있습니다. 구조 식별자에는 0x00-0x02F 범위의 숫자 코드가 있습니다. 콘텐츠 식별자에는 0x30 이상의 범위가 있습니다. (DVD_TextStringType 열거형은 가장 일반적인 식별자의 하위 집합을 정의하지만 IDvdInfo2 메서드는 식별자 코드를 반환할 수 있습니다.) 구조 식별자는 볼륨, 제목 또는 PTT(타이틀의 일부)와 같은 DVD의 논리적 부분을 설명합니다. 콘텐츠 식별자는 영화 제목, 노래 제목 또는 장르와 같은 특정 텍스트 문자열의 의미를 나타냅니다.

구조체 식별자에는 연결된 텍스트 문자열이 없습니다. 구조체 식별자가 텍스트 문자열 데이터에 나타나면 다음 구조 식별자까지 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" 두 번째 타이틀의 이름입니다.

 

GetDVDTextStringAsUnicodeGetDVDTextStringAsNative 메서드는 구조 식별자와 콘텐츠 식별자를 동일하게 처리합니다. 유일한 차이점은 구조 식별자의 경우 연결된 텍스트 버퍼가 비어 있다는 것입니다. 텍스트 문자열과 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 텍스트 문자열을 열거하고 표시하는 기본 단계를 보여 줍니다.

DVD 응용 프로그램