Udostępnij przez


Praca z ciągami tekstowymi DVD

[Funkcja skojarzona z tą stroną, DirectShow, jest starszą funkcją. Został zastąpiony przez MediaPlayer, IMFMediaEngineoraz Audio/Video Capture w Media Foundation. Te funkcje zostały zoptymalizowane pod kątem systemów Windows 10 i Windows 11. Firma Microsoft zdecydowanie zaleca, aby nowy kod używał MediaPlayer, IMFMediaEngine i Audio/Video Capture w programie Media Foundation zamiast DirectShow, jeśli to możliwe. Firma Microsoft sugeruje, że istniejący kod, który używa starszych interfejsów API, należy przepisać go do korzystania z nowych interfejsów API, jeśli to możliwe.]

Niektóre dyski DVD, zwłaszcza dyski karaoke, mogą zawierać listę ciągów tekstowych, aby uzupełnić zawartość wideo lub audio. Te ciągi tekstowe zawierają metadane dotyczące zawartości, takie jak tytuły piosenek, nazwy artystów, informacje o gatunku itd. Ciągi tekstowe mogą być obecne w więcej niż jednym języku. Te ciągi są opcjonalne, a wiele dysków ich nie ma.

Aby pobrać ciągi tekstowe z dysku DVD, użyj interfejsuIDvdInfo2, który jest udostępniany przez DVD Navigator. W rzeczywistości nie trzeba tworzyć grafu odtwarzania DVD w celu pobrania ciągów tekstowych. Możesz po prostu utworzyć nawigator DVD, ustawić wolumin DVD, a następnie wywołać odpowiednie metody ciągów tekstowych:

Metoda Opis
IDvdInfo2::GetDVDTextNumberOfLanguages Pobiera liczbę języków, dla których istnieją ciągi tekstowe.
IDvdInfo2::GetDVDTextLanguageInfo Pobiera informacje o ciągach tekstowych dla jednego języka.
IDvdInfo2::GetDVDTextStringAsUnicode Pobiera ciąg tekstowy dla określonego języka według indeksu.
IDvdInfo2::GetDVDTextStringAsNative Pobiera ciąg tekstowy jako nieprzetworzona tablica bajtów. Użyj tej metody, jeśli ciąg tekstowy używa kodowania znaków, które nie jest obsługiwane przez GetDVDTextStringAsUnicode.

 

Oto podstawowa procedura pobierania ciągów tekstowych:

  1. Wywołaj IDvdInfo2::GetDVDTextNumberOfLanguages, aby znaleźć łączną liczbę języków, w których są wyświetlane ciągi tekstowe. Jeśli liczba jest równa zero, oznacza to, że dysk DVD nie ma żadnych ciągów tekstowych. (Jest to prawdopodobnie najbardziej typowy przypadek, w rzeczywistości).
  2. Jeśli liczba języków jest co najmniej jedna, wywołaj IDvdInfo2::GetDVDTextLanguageInfo, aby uzyskać informacje o każdym języku. Język jest określany przez indeks. Metoda zwraca całkowitą liczbę ciągów tekstowych w tym języku, identyfikator ustawień regionalnych (LCID) dla języka oraz kodowanie znaków (Unicode lub inne). Ciągi tekstowe DVD mogą używać kilku różnych zestawów znaków; są one wymienione w Enumeracji DVD_TextCharSet.
  3. Aby uzyskać ciąg tekstowy, wywołaj IDvdInfo2::GetDVDTextStringAsUnicode lub IDvdInfo2::GetDVDTextStringAsNative. Pierwsza metoda zwraca ciąg o szerokim znaku, ale nie obsługuje każdego zestawu znaków. Druga metoda zwraca tablicę bajtów zawierającą nieprzetworzone dane tekstowe. W przypadku obu metod można wywołać metodę za pomocą wskaźnika bufora null w celu określenia rozmiaru ciągu i typu tekstu. Następnie przydziel bufor i wywołaj metodę ponownie, aby pobrać ciąg.

Każdy ciąg tekstowy ma skojarzony kod identyfikatora, który wskazuje znaczenie ciągu tekstowego. Identyfikator jest zwracany jako wartość DVD_TextStringType. Istnieją dwie kategorie identyfikatorów: identyfikatory struktury i identyfikatory zawartości . Identyfikatory struktury mają kody liczbowe w zakresie 0x00–0x02F. Identyfikatory zawartości mają zakres 0x30 i wyższe. (Wyliczenie DVD_TextStringType definiuje podzestaw najczęściej używanych identyfikatorów, ale metody IDvdInfo2mogą zwracać dowolny kod identyfikatora). Identyfikator struktury opisuje logiczną część dysku DVD, taką jak wolumin, tytuł lub część tytułu (PTT). Identyfikator zawartości wskazuje znaczenie określonego ciągu tekstowego, takiego jak tytuł filmu, tytuł piosenki lub gatunek.

Identyfikatory struktury nie mają skojarzonych ciągów tekstowych. Gdy identyfikator struktury pojawia się w danych ciągu tekstowego, sygnalizuje, że następujące ciągi tekstowe mają zastosowanie do tej logicznej części dysku DVD aż do następnego identyfikatora struktury. Położenie identyfikatorów struktury w danych tekstowych odpowiada hierarchii logicznej woluminu DVD. Na przykład pierwsze wystąpienie identyfikatora DVD_Struct_Title (0x02) reprezentuje pierwszy tytuł w woluminie, a następne wystąpienie reprezentuje drugi tytuł.

W poniższej tabeli przedstawiono sposób definiowania ciągów tekstowych dla dysku DVD z dwoma tytułami.

DVD_TextStringType Ciąg tekstowy Opis
DVD_Struct_Volume (0x01) "" Identyfikator struktury dla całej strony dysku.
DVD_Nazwa_Ogólna (0x30) "Wolumin DVD" Nazwa woluminu DVD.
Tytuł_Strukt_DVD (0x02) "" Identyfikator struktury pierwszego tytułu.
DVD_General_Name (0x30) "Tytuł 1" Nazwa pierwszego tytułu.
DVD_Struct_Tytuł (0x02) "" Identyfikator struktury drugiego tytułu.
DVD_General_Name (0x30) "Tytuł 2" Nazwa drugiego tytułu.

 

Metody GetDVDTextStringAsUnicode i GetDVDTextStringAsNative traktują takie same identyfikatory struktury i identyfikatory zawartości. Jedyną różnicą jest to, że w przypadku identyfikatorów struktury skojarzony bufor tekstowy jest pusty. Do aplikacji należy śledzenie relacji między ciągami tekstowymi a logicznymi fragmentami dysku DVD.

W poniższym przykładzie pokazano, jak pobrać ciągi tekstowe z dysku DVD. W tym przykładzie są ignorowane pewne szczegóły wymagane przez rzeczywistą aplikację. (Na przykład ignoruje identyfikatory struktury). W przykładzie pokazano tylko prawidłową sekwencję wywołań.

#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;
}

Aby uzyskać informacje na temat ciągów tekstowych DVD, zobacz witrynę internetową forum DVD .

Metoda CDvdCore::GetDvdText w aplikacji DVDSample przedstawia podstawowe kroki wyliczania i wyświetlania ciągów tekstowych DVD.

Aplikacje DVD