📄 fileinfodialog.cpp
字号:
_T("Warning: The file extension of \"%s\" does not match the file extension ")
_T("typically used for that file format. You may want to rename the file to ")
_T("use one of those file extension \"%s\" for properly using or viewing that ")
_T("file format."), pszFileName, pszExtensions);
}
bool GetMediaInfo(HWND hWndOwner, const CKnownFile* pFile, SMediaInfo* mi, bool bSingleFile)
{
if (!pFile)
return false;
ASSERT( !pFile->GetFilePath().IsEmpty() );
/*FILE* fp = _fsopen(pFile->GetFilePath(), "rb", _SH_DENYWR);
if (fp)
{
BYTE aucBuff[8192];
int iRead = fread(aucBuff, 1, sizeof aucBuff, fp);
if (iRead > 0)
{
USES_CONVERSION;
LPWSTR pwszMime = NULL;
HRESULT hr = FindMimeFromData(NULL, T2W(pFile->GetFilePath()), aucBuff, iRead, NULL, 0, &pwszMime, 0);
if (SUCCEEDED(hr) && pwszMime != NULL && wcscmp(pwszMime, L"application/octet-stream") != 0 && wcscmp(pwszMime, L"text/plain") != 0)
{
mi->strMimeType = W2T(pwszMime);
}
}
fclose(fp);
}*/
if (pFile->IsPartFile())
{
// Do *not* pass a part file which does not have the beginning of file to the following code.
// - The MP3 reading code will skip all 0-bytes from the beginning of the file and may block
// the main thread for a long time.
//
// - The RIFF reading code will not work without the file header.
//
// - Most (if not all) other code will also not work without the beginning of the file available.
if (!((CPartFile*)pFile)->IsComplete(0, 16*1024))
return false;
}
else
{
if (pFile->GetFileSize() < 16*1024)
return false;
}
mi->ulFileSize = pFile->GetFileSize();
TCHAR szExt[_MAX_EXT];
_tsplitpath(pFile->GetFileName(), NULL, NULL, NULL, szExt);
_tcslwr(szExt);
bool bResult = false;
////////////////////////////////////////////////////////////////////////////
// Check for AVI file
//
bool bIsAVI = false;
try
{
if (GetRIFFHeaders(pFile->GetFilePath(), mi, bIsAVI))
{
if (bIsAVI && _tcscmp(szExt, _T(".avi")) != 0)
WarnAboutWrongFileExtension(mi, pFile->GetFileName(), _T("avi"));
return true;
}
}
catch(...)
{
}
if (!IsWindow(hWndOwner))
return false;
////////////////////////////////////////////////////////////////////////////
// Check for MPEG Audio file
//
if (_tcscmp(szExt, _T(".mp3"))==0 || _tcscmp(szExt, _T(".mp2"))==0 || _tcscmp(szExt, _T(".mp1"))==0 || _tcscmp(szExt, _T(".mpa"))==0)
{
try
{
USES_CONVERSION;
ID3_Tag myTag;
myTag.Link(T2CA(pFile->GetFilePath()));
const Mp3_Headerinfo* mp3info;
mp3info = myTag.GetMp3HeaderInfo();
if (mp3info)
{
mi->strFileFormat = _T("MPEG audio");
if (!bSingleFile)
{
//m_fi.SetSelectionCharFormat(m_cfBold);
if (!mi->strInfo.str.IsEmpty())
mi->strInfo << _T("\n\n");
//m_fi.SetSelectionCharFormat(m_cfBold);
mi->strInfo << _T("File: ") << pFile->GetFileName() << _T("\n");
mi->strInfo << _T("MP3 Header Info\n");
//m_fi.SetSelectionCharFormat(m_cfDef);
}
switch (mp3info->version)
{
case MPEGVERSION_2_5:
mi->strAudioFormat = _T("MPEG-2.5,");
mi->audio.wFormatTag = 0x0055;
break;
case MPEGVERSION_2:
mi->strAudioFormat = _T("MPEG-2,");
mi->audio.wFormatTag = 0x0055;
break;
case MPEGVERSION_1:
mi->strAudioFormat = _T("MPEG-1,");
mi->audio.wFormatTag = 0x0055;
break;
default:
break;
}
mi->strAudioFormat += _T(" ");
switch (mp3info->layer)
{
case MPEGLAYER_III:
mi->strAudioFormat += _T("Layer 3");
break;
case MPEGLAYER_II:
mi->strAudioFormat += _T("Layer 2");
break;
case MPEGLAYER_I:
mi->strAudioFormat += _T("Layer 1");
break;
default:
break;
}
if (!bSingleFile)
{
mi->strInfo << _T(" Version:\t") << mi->strAudioFormat << _T("\n");
mi->strInfo << _T(" Bitrate:\t") << mp3info->bitrate/1000 << _T(" kBit/s\n");
mi->strInfo << _T(" Frequency:\t") << mp3info->frequency/1000 << _T(" kHz\n");
}
mi->iAudioStreams++;
mi->audio.nAvgBytesPerSec = mp3info->bitrate/8;
mi->audio.nSamplesPerSec = mp3info->frequency;
if (!bSingleFile)
mi->strInfo << _T(" Mode:\t");
switch (mp3info->channelmode){
case MP3CHANNELMODE_STEREO:
if (!bSingleFile)
mi->strInfo << _T("Stereo");
mi->audio.nChannels = 2;
break;
case MP3CHANNELMODE_JOINT_STEREO:
if (!bSingleFile)
mi->strInfo << _T("Joint Stereo");
mi->audio.nChannels = 2;
break;
case MP3CHANNELMODE_DUAL_CHANNEL:
if (!bSingleFile)
mi->strInfo << _T("Dual Channel");
mi->audio.nChannels = 2;
break;
case MP3CHANNELMODE_SINGLE_CHANNEL:
if (!bSingleFile)
mi->strInfo << _T("Mono");
mi->audio.nChannels = 1;
break;
}
if (!bSingleFile)
mi->strInfo << _T("\n");
// length
if (mp3info->time)
{
if (!bSingleFile)
{
CString strLength;
SecToTimeLength(mp3info->time, strLength);
mi->strInfo << _T(" Length:\t") << strLength;
if (pFile->IsPartFile()){
// mi->strInfo.SetSelectionCharFormat(m_cfRed);
mi->strInfo << _T(" (This may not reflect the final total length!)");
// mi->strInfo.SetSelectionCharFormat(m_cfDef);
}
mi->strInfo << "\n";
}
mi->fAudioLengthSec = mp3info->time;
}
bResult = true;
}
int iTag = 0;
ID3_Tag::Iterator* iter = myTag.CreateIterator();
const ID3_Frame* frame;
while ((frame = iter->GetNext()) != NULL)
{
if (iTag == 0)
{
if (mp3info && !bSingleFile)
mi->strInfo << _T("\n");
// mi->strInfo.SetSelectionCharFormat(m_cfBold);
mi->strInfo << _T("MP3 Tags\n");
// mi->strInfo.SetSelectionCharFormat(m_cfDef);
}
iTag++;
LPCSTR desc = frame->GetDescription();
if (!desc)
desc = frame->GetTextID();
mi->strInfo << _T(" ") << A2CT(desc) << _T(":\t");
ID3_FrameID eFrameID = frame->GetID();
switch (eFrameID)
{
case ID3FID_ALBUM:
case ID3FID_BPM:
case ID3FID_COMPOSER:
case ID3FID_CONTENTTYPE:
case ID3FID_COPYRIGHT:
case ID3FID_DATE:
case ID3FID_PLAYLISTDELAY:
case ID3FID_ENCODEDBY:
case ID3FID_LYRICIST:
case ID3FID_FILETYPE:
case ID3FID_TIME:
case ID3FID_CONTENTGROUP:
case ID3FID_TITLE:
case ID3FID_SUBTITLE:
case ID3FID_INITIALKEY:
case ID3FID_LANGUAGE:
case ID3FID_SONGLEN:
case ID3FID_MEDIATYPE:
case ID3FID_ORIGALBUM:
case ID3FID_ORIGFILENAME:
case ID3FID_ORIGLYRICIST:
case ID3FID_ORIGARTIST:
case ID3FID_ORIGYEAR:
case ID3FID_FILEOWNER:
case ID3FID_LEADARTIST:
case ID3FID_BAND:
case ID3FID_CONDUCTOR:
case ID3FID_MIXARTIST:
case ID3FID_PARTINSET:
case ID3FID_PUBLISHER:
case ID3FID_TRACKNUM:
case ID3FID_RECORDINGDATES:
case ID3FID_NETRADIOSTATION:
case ID3FID_NETRADIOOWNER:
case ID3FID_SIZE:
case ID3FID_ISRC:
case ID3FID_ENCODERSETTINGS:
case ID3FID_YEAR:
{
char *sText = ID3_GetString(frame, ID3FN_TEXT);
mi->strInfo << sText << _T("\n");
delete [] sText;
break;
}
case ID3FID_USERTEXT:
{
char
*sText = ID3_GetString(frame, ID3FN_TEXT),
*sDesc = ID3_GetString(frame, ID3FN_DESCRIPTION);
mi->strInfo << _T("(") << sDesc << _T("): ") << sText << _T("\n");
delete [] sText;
delete [] sDesc;
break;
}
case ID3FID_COMMENT:
case ID3FID_UNSYNCEDLYRICS:
{
char
*sText = ID3_GetString(frame, ID3FN_TEXT),
*sDesc = ID3_GetString(frame, ID3FN_DESCRIPTION),
*sLang = ID3_GetString(frame, ID3FN_LANGUAGE);
mi->strInfo << _T("(") << sDesc << _T(")[") << sLang << _T("]: ") << sText << _T("\n");
delete [] sText;
delete [] sDesc;
delete [] sLang;
break;
}
case ID3FID_WWWAUDIOFILE:
case ID3FID_WWWARTIST:
case ID3FID_WWWAUDIOSOURCE:
case ID3FID_WWWCOMMERCIALINFO:
case ID3FID_WWWCOPYRIGHT:
case ID3FID_WWWPUBLISHER:
case ID3FID_WWWPAYMENT:
case ID3FID_WWWRADIOPAGE:
{
char *sURL = ID3_GetString(frame, ID3FN_URL);
mi->strInfo << sURL << _T("\n");
delete [] sURL;
break;
}
case ID3FID_WWWUSER:
{
char
*sURL = ID3_GetString(frame, ID3FN_URL),
*sDesc = ID3_GetString(frame, ID3FN_DESCRIPTION);
mi->strInfo << _T("(") << sDesc << _T("): ") << sURL << _T("\n");
delete [] sURL;
delete [] sDesc;
break;
}
case ID3FID_INVOLVEDPEOPLE:
{
size_t nItems = frame->GetField(ID3FN_TEXT)->GetNumTextItems();
for (size_t nIndex = 0; nIndex < nItems; nIndex++)
{
char *sPeople = ID3_GetString(frame, ID3FN_TEXT, nIndex);
mi->strInfo << sPeople;
delete [] sPeople;
if (nIndex + 1 < nItems)
mi->strInfo << _T(", ");
}
mi->strInfo << _T("\n");
break;
}
case ID3FID_PICTURE:
{
char
*sMimeType = ID3_GetString(frame, ID3FN_MIMETYPE),
*sDesc = ID3_GetString(frame, ID3FN_DESCRIPTION),
*sFormat = ID3_GetString(frame, ID3FN_IMAGEFORMAT);
size_t
nPicType = frame->GetField(ID3FN_PICTURETYPE)->Get(),
nDataSize = frame->GetField(ID3FN_DATA)->Size();
mi->strInfo << _T("(") << sDesc << _T(")[") << sFormat << _T(", ")
<< nPicType << _T("]: ") << sMimeType << _T(", ") << nDataSize
<< _T(" bytes") << _T("\n");
delete [] sMimeType;
delete [] sDesc;
delete [] sFormat;
break;
}
case ID3FID_GENERALOBJECT:
{
char
*sMimeType = ID3_GetString(frame, ID3FN_MIMETYPE),
*sDesc = ID3_GetString(frame, ID3FN_DESCRIPTION),
*sFileName = ID3_GetString(frame, ID3FN_FILENAME);
size_t
nDataSize = frame->GetField(ID3FN_DATA)->Size();
mi->strInfo << _T("(") << sDesc << _T(")[")
<< sFileName << _T("]: ") << sMimeType << _T(", ") << nDataSize
<< _T(" bytes") << _T("\n");
delete [] sMimeType;
delete [] sDesc;
delete [] sFileName;
break;
}
case ID3FID_UNIQUEFILEID:
{
char *sOwner = ID3_GetString(frame, ID3FN_OWNER);
size_t nDataSize = frame->GetField(ID3FN_DATA)->Size();
mi->strInfo << sOwner << _T(", ") << nDataSize
<< _T(" bytes") << _T("\n");
delete [] sOwner;
break;
}
case ID3FID_PLAYCOUNTER:
{
size_t nCounter = frame->GetField(ID3FN_COUNTER)->Get();
mi->strInfo << nCounter << _T("\n");
break;
}
case ID3FID_POPULARIMETER:
{
char *sEmail = ID3_GetString(frame, ID3FN_EMAIL);
size_t
nCounter = frame->GetField(ID3FN_COUNTER)->Get(),
nRating = frame->GetField(ID3FN_RATING)->Get();
mi->strInfo << sEmail << _T(", counter=")
<< nCounter << _T(" rating=") << nRating << _T("\n");
delete [] sEmail;
break;
}
case ID3FID_CRYPTOREG:
case ID3FID_GROUPINGREG:
{
char *sOwner = ID3_GetString(frame, ID3FN_OWNER);
size_t
nSymbol = frame->GetField(ID3FN_ID)->Get(),
nDataSize = frame->GetField(ID3FN_DATA)->Size();
mi->strInfo << _T("(") << nSymbol << _T("): ") << sOwner
<< _T(", ") << nDataSize << _T(" bytes") << _T("\n");
break;
}
case ID3FID_SYNCEDLYRICS:
{
char
*sDesc = ID3_GetString(frame, ID3FN_DESCRIPTION),
*sLang = ID3_GetString(frame, ID3FN_LANGUAGE);
size_t
//nTimestamp = frame->GetField(ID3FN_TIMESTAMPFORMAT)->Get(),
nRating = frame->GetField(ID3FN_CONTENTTYPE)->Get();
//const char* format = (2 == nTimestamp) ? "ms" : "frames";
mi->strInfo << _T("(") << sDesc << _T(")[") << sLang << _T("]: ");
switch (nRating)
{
case ID3CT_OTHER: mi->strInfo << _T("Other"); break;
case ID3CT_LYRICS: mi->strInfo << _T("Lyrics"); break;
case ID3CT_TEXTTRANSCRIPTION: mi->strInfo << _T("Text transcription"); break;
case ID3CT_MOVEMENT: mi->strInfo << _T("Movement/part name"); break;
case ID3CT_EVENTS: mi->strInfo << _T("Events"); break;
case ID3CT_CHORD: mi->strInfo << _T("Chord"); break;
case ID3CT_TRIVIA: mi->strInfo << _T("Trivia/'pop up' information"); break;
}
mi->strInfo << _T("\n");
/*ID3_Field* fld = frame->GetField(ID3FN_DATA);
if (fld)
{
ID3_MemoryReader mr(fld->GetRawBinary(), fld->BinSize());
while (!mr.atEnd())
{
mi->strInfo << io::readString(mr).c_str();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -