Freigeben über


Ermitteln des Dateiformats

Vor dem Senden einer Datei an das Gerät sollte eine Anwendung ermitteln, ob das Gerät dieses Dateiformat unterstützt.

Das Ermitteln des Formats einer Datei kann komplex sein. Die einfachste Möglichkeit besteht darin, eine Liste von Dateierweiterungen zu erstellen, die bestimmten WMDM_FORMATCODE Enumerationswerte zugeordnet sind. Es gibt jedoch einige Probleme mit diesem System: Eines ist, dass ein einzelnes Format mehrere Erweiterungen aufweisen kann (z. B. .jpg, JPE und JPEG für JPEG-Bilder). Außerdem kann dieselbe Dateierweiterung von verschiedenen Programmen für unterschiedliche Formate verwendet werden.

Um die Einschränkungen einer strengen Zuordnung zu überwinden, sollte eine Anwendung am besten überprüfen, ob das Format der Erweiterung entspricht. Das DirectShow SDK bietet Tools, mit denen eine Anwendung einen begrenzten Satz von Details zu den meisten Mediendateitypen ermitteln kann. Das Windows Media Format SDK macht eine große Anzahl von Details verfügbar, aber nur zu ASF-Dateien. Da bei allen Dateitypen nach Möglichkeit der Formatcode überprüft werden sollte, empfiehlt es sich daher, DirectShow zu verwenden, um den grundlegenden Formatcode zu ermitteln oder zu überprüfen, und verwenden Sie das Windows Media Format SDK, um alle zusätzlichen Metadaten zu ASF-Dateien zu ermitteln. DirectShow kann auch verwendet werden, um grundlegende Metadaten für Nicht-ASF-Dateien zu ermitteln.

Im Folgenden können Sie ein Dateiformat mithilfe von Erweiterungszuordnung und DirectShow ermitteln.

Vergleichen Sie zunächst die Dateinamenerweiterung mit einer Liste bekannter Erweiterungen. Achten Sie darauf, dass Sie beim Vergleich die Groß-/Kleinschreibung nicht berücksichtigen. Wenn die Erweiterung nicht zugeordnet ist, legen Sie das Format auf WMDM_FORMATCODE_UNDEFINED fest.

  • Wenn der Formatcode nicht gefunden wurde (oder Sie überprüfen möchten, ob es sich bei einer Datei um eine Mediendatei handelt), können Sie die folgenden Schritte ausführen:
    1. Erstellen Sie mithilfe von CoCreateInstance(CLSID_MediaDet) ein DirectShow Media Detector-Objekt und abrufen Sie die IMediaDet-Schnittstelle .
    2. Öffnen Sie die Datei, indem Sie IMediaDet::p ut_Filename aufrufen. Dieser Aufruf schlägt fehl, wenn die Datei geschützt ist.
    3. Rufen Sie den Medientyp des Standardstreams ab, indem Sie IMediaDet::get_StreamMediaType aufrufen, wodurch eine AM_MEDIA_TYPE zurückgegeben wird.
    4. Rufen Sie die Anzahl der Streams ab, indem Sie IMediaDet::get_OutputStreams aufrufen.
      • Wenn nur ein Stream vorhanden ist und es sich um Audio handelt, ist der Dateityp WMDM_FORMATCODE_UNDEFINEDAUDIO
      • Wenn nur ein Stream vorhanden ist und es sich um ein Video handelt, ist der Dateityp WMDM_FORMATCODE_UNDEFINEDVIDEO
      • Wenn es nur einen Stream gibt und es sich um Video handelt und die Bitrate null ist, ist der Dateityp WMDM_FORMATCODE_WINDOWSIMAGEFORMAT.

Sie können auch übereinstimmende Audio- oder Videocodecs aus den VIDEOINFOHEADER - oder WAVEFORMATEX-Membern ausprobieren, die von get_StreamMediaType abgerufen wurden.

Die folgende C++-Funktion veranschaulicht den Abgleich von Dateierweiterungen und die Verwendung von DirectShow zum Analysieren unbekannter Dateien.

// For IMediaDet, you must link to strmiids.lib. Also include the following:
//#include <Qedit.h>  // for IMediaDet declaration.
//#include <Dshow.h>  // for VIDEOINFOHEADER declaration.
WMDM_FORMATCODE CWMDMController::myGetWMDM_FORMATCODE(LPCWSTR pFileName)
{
    HRESULT hr = S_OK;

    // Declare the variable to hold the WMDM format code.
    WMDM_FORMATCODE fmt = WMDM_FORMATCODE_UNDEFINED;
    
    // Get the file extension.
    wstring ext = pFileName;
    ext = ext.substr(ext.find_last_of(L".") + 1);

    // This is not an exhaustive list. 
    // It is also case-sensitive.
    if (ext == L"js" || ext == L"vb")
        fmt = WMDM_FORMATCODE_SCRIPT;
    else if (ext == L".exe")
        fmt = WMDM_FORMATCODE_EXECUTABLE;
    else if (ext == L"txt")
        fmt = WMDM_FORMATCODE_TEXT;
    else if (ext == L"html" || ext == L"htm" || ext == L"shtm")
        fmt = WMDM_FORMATCODE_HTML;
    else if (ext == L"aiff")
        fmt = WMDM_FORMATCODE_AIFF;
    else if (ext == L"wav")
        fmt = WMDM_FORMATCODE_WAVE;
    else if (ext == L"mp3")
        fmt = WMDM_FORMATCODE_MP3;
    else if (ext == L"mpg" || ext == L"mpeg" || ext == L"mp2")
        fmt = WMDM_FORMATCODE_MPEG;
    else if (ext == L"bmp")
        fmt = WMDM_FORMATCODE_IMAGE_BMP;
    else if (ext == L"avi")
        fmt = WMDM_FORMATCODE_AVI;
    else if (ext == L"asf")
        fmt = WMDM_FORMATCODE_ASF;
    else if (ext == L"tif")
        fmt = WMDM_FORMATCODE_IMAGE_TIFF;
    else if (ext == L"gif")
        fmt = WMDM_FORMATCODE_IMAGE_GIF;
    else if (ext == L"pct")
        fmt = WMDM_FORMATCODE_IMAGE_PICT;
    else if (ext == L"png")
        fmt = WMDM_FORMATCODE_IMAGE_PNG;
    else if (ext == L"wma")
        fmt = WMDM_FORMATCODE_WMA;
    else if (ext == L"wpl")
        fmt = WMDM_FORMATCODE_WPLPLAYLIST;
    else if (ext == L"asx")
        fmt = WMDM_FORMATCODE_ASXPLAYLIST;
    else if (ext == L"m3u")
        fmt = WMDM_FORMATCODE_M3UPLAYLIST;
    else if (ext == L"wmv")
        fmt = WMDM_FORMATCODE_WMV;
    else if (ext == L"jpg" || ext == L"jpeg" || ext == L"jpe")
        fmt = WMDM_FORMATCODE_IMAGE_EXIF;
    else if (ext == L"jp2")
        fmt = WMDM_FORMATCODE_IMAGE_JP2;
    else if (ext == L"jpx" || ext == L"jpf")
        fmt = WMDM_FORMATCODE_IMAGE_JPX;

    // If we couldn't get the type from the extension, perhaps DirectShow 
    // can determine the type. You could also modify this to verify that 
    // the major media type matches the file extension (for example, that 
    // a .gif file has a video image stream with a bit rate of zero).
    if (fmt == WMDM_FORMATCODE_UNDEFINED)
    {
        CComPtr<IMediaDet> pIMediaDet;
        hr = pIMediaDet.CoCreateInstance(CLSID_MediaDet, NULL);
        if (hr == S_OK && pIMediaDet != NULL)
        {
            hr = pIMediaDet->put_Filename(BSTR(pFileName));
            if (FAILED(hr)) return WMDM_FORMATCODE_UNDEFINED;

            AM_MEDIA_TYPE mediaType;
            if (hr == S_OK)
            {
                hr = pIMediaDet->get_StreamMediaType(&mediaType);
                CHECK_HR(hr, 
                  "get_StreamMediaType succeeded in myGetWMDM_FORMATCODE.", 
                  "get_StreamMediaType failed in myGetWMDM_FORMATCODE.");
            }

            if (hr == S_OK)
            {
                LONG numStreams = 0;
                hr = pIMediaDet->get_OutputStreams(&numStreams);

                // If there is at least one video stream, the file is video. 
                // If there are only audio streams, it is audio.
                // Loop through all streams or until first video stream is found.
                for (int i = 0; i < numStreams; i++)
                {
                    // Choices are either VIDEOINFOHEADER or WAVEFORMATEX. 
                    // VIDEOINFOHEADER2 is not supported.
                    if (IsEqualGUID(mediaType.formattype, 
                        FORMAT_VideoInfo))
                    {
                        VIDEOINFOHEADER* data = 
                            (VIDEOINFOHEADER*) mediaType.pbFormat;

                        // If only one stream and there was no matching 
                        // extension, it is undefined video. If no 
                        // bit rate, it's a still image.
                        if (data->dwBitRate == 0) fmt = 
                            WMDM_FORMATCODE_WINDOWSIMAGEFORMAT;
                        else fmt = WMDM_FORMATCODE_UNDEFINEDVIDEO;
                        break; // Found video--any additional streams are soundtracks.
                    }
                    if (IsEqualGUID(mediaType.formattype, FORMAT_WaveFormatEx))
                    {
                        // If only one stream and there was no matching 
                        // extension, it is undefined audio. 
                        if (fmt == WMDM_FORMATCODE_UNDEFINED)
                        {
                            fmt = WMDM_FORMATCODE_UNDEFINEDAUDIO;
                        }
                        WAVEFORMATEX* data = 
                            (WAVEFORMATEX*) mediaType.pbFormat;
                    }
                } // Loop through streams.
            }     // Got a stream media type.
        }         // Created a media detector object.
    }
    return fmt;
}

Schreiben von Dateien auf das Gerät