파일 형식 검색
디바이스로 파일을 보내기 전에 애플리케이션은 디바이스가 해당 파일 형식을 지원하는지 여부를 결정해야 합니다.
파일 형식을 검색하는 것은 복잡할 수 있습니다. 가장 간단한 방법은 특정 WMDM_FORMATCODE 열거형 값에 매핑된 파일 확장명 목록을 만드는 것입니다. 그러나 이 시스템에는 몇 가지 문제가 있습니다. 하나는 단일 형식에 여러 확장이 있을 수 있다는 것입니다(예: JPEG 이미지의 경우 .jpg, .jpe 및 .jpeg). 또한 다른 프로그램에서 다른 형식의 동일한 파일 확장자를 사용할 수 있습니다.
엄격한 매핑의 제한 사항을 극복하기 위해 애플리케이션에서 형식이 확장과 일치하는지 확인하는 것이 가장 좋습니다. DirectShow SDK는 애플리케이션이 대부분의 미디어 파일 형식에 대한 제한된 세부 정보 집합을 검색할 수 있는 도구를 제공합니다. Windows Media Format SDK는 많은 수의 세부 정보를 노출하지만 ASF 파일에 대해서만 노출합니다. 모든 파일 형식은 가능한 경우 해당 형식 코드를 확인해야 하므로 DirectShow를 사용하여 기본 형식 코드를 검색하거나 확인하고 Windows Media Format SDK를 사용하여 ASF 파일에 대해 원하는 추가 메타데이터를 검색하는 것이 가장 좋습니다. DirectShow를 사용하여 ASF가 아닌 파일에 대한 기본 메타데이터를 검색할 수도 있습니다.
다음은 확장 매핑 및 DirectShow를 사용하여 파일 형식을 검색하는 한 가지 방법입니다.
먼저 파일 이름 확장명을 알려진 확장명 목록과 비교합니다. 비교 대/소문자를 구분하지 않도록 해야 합니다. 확장이 매핑되지 않은 경우 형식을 WMDM_FORMATCODE_UNDEFINED 설정합니다.
- 형식 코드를 찾을 수 없거나 파일이 미디어 파일인지 확인하려는 경우 다음 단계를 수행할 수 있습니다.
- CoCreateInstance(CLSID_MediaDet)를 사용하고 IMediaDet 인터페이스를 검색하여 DirectShow Media Detector 개체를 만듭니다.
- IMediaDet::p ut_Filename을 호출하여 파일을 엽니다. 파일이 보호되면 이 호출이 실패합니다.
- AM_MEDIA_TYPE 반환하는 IMediaDet::get_StreamMediaType 호출하여 기본 스트림의 미디어 형식을 가져옵니다.
-
IMediaDet::get_OutputStreams 호출하여 스트림 수를 가져옵니다.
- 스트림이 하나만 있고 오디오인 경우 파일 형식이 WMDM_FORMATCODE_UNDEFINEDAUDIO
- 스트림이 하나만 있고 비디오인 경우 파일 형식이 WMDM_FORMATCODE_UNDEFINEDVIDEO
- 스트림이 하나만 있고 비디오이고 비트 속도가 0이면 파일 형식이 WMDM_FORMATCODE_WINDOWSIMAGEFORMAT.
get_StreamMediaType 검색된 VIDEOINFOHEADER 또는 WAVEFORMATEX멤버에서 오디오 또는 비디오 코덱을 일치시킬 수도 있습니다.
다음 C++ 함수는 파일 확장명 일치 및 DirectShow를 사용하여 알 수 없는 파일을 분석하는 방법을 보여 줍니다.
// 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;
}
관련 항목