下面的文章將指導您完成創建基於桌面對話框的應用程序的過程,該應用程序可用於相互轉換音頻文件。包括:
「engine」-一個類庫,用於從一種格式到另一種格式的實際轉換
枚舉給定路徑中的文件以及其中的任何子文件夾。

用戶界面和用戶體驗
我開發的程序無需安裝即可運行,無需外部DLL,甚至不需要靜態庫。只需構建並運行即可。
背景
MicrosoftMediaFoundation是一個基於Windows的多媒體平台,使開發人員能夠創建各種多媒體軟體。
轉換音頻文件
使用MicrosoftMediaFoundation轉換音頻文件需要對音頻流進行編碼和解碼,這將在以下教程中進行說明。
第一步是為此類音頻處理創建我們自己的類,我們稱之為SG_Audio(Convert)。
SG_AudioConvert::SG_AudioConvert()
{
// Initialize whatever needs to be initialized
Init();
}
SG_AudioConvert::~SG_AudioConvert()
{
// Clean up whatever needs to be cleaned up
Cleanup();
}1234567891011複製代碼類型:[c]初始化中
我們的Init()功能由構造調用,執行以下操作:
檢查它是否已經通過初始化。我們不希望(也不應該)多次這樣做。
調用HeapSetInformation()為我們的堆啟用某些功能。請注意,我們正在初始化單線程單元,您可以在這篇出色的文章中了解有關該術語的更多信息。
調用MFStartup()以啟動WindowsMediaFoundation。
設置m_bInit為true,表示初始化已完成。
int SG_AudioConvert::Init()
{
HRESULT hr = S_OK;
// check already initialized
if (m_bInit)
return RET_OK;
(void)HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);
hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
if (SUCCEEDED(hr))
{
hr = MFStartup(MF_VERSION);
m_bInit = TRUE;
return RET_OK; // success
}
m_bInit = FALSE;
return RET_FAIL; // fail
}12345678910111213141516171819202122複製代碼類型:[c]打掃乾淨
在繼續之前,我們還介紹一下我們類的Destructor調用的清理過程。
int SG_AudioConvert::Cleanup()
{
MFShutdown();
CoUninitialize();
return RET_OK; // success
}1234567複製代碼類型:[c]在清理過程中,我們執行以下操作:
致電MFShutdown()
呼叫CoUninitialize()
我們的通用音頻轉換功能
我們開發
intSG_AudioConvert::ConvertProc()以將所有文件轉換從支持的任何音頻類型轉換為其他任何類型。
我們將以下參數傳遞給它:
p_szSrc-我們的源文件
p_szDst-我們的目標文件
TargetFormat-我們目標格式的GUID-請參閱「音頻編解碼器」
ContainerType-我們的容器類型-請參閱「文件容器」
該函數的原型如下所示:
int SG_AudioConvert::ConvertProc(
const wchar_t* p_szSrc,
const wchar_t* p_szDst,
const GUID TargetFormat,
const GUID ContainerType);12345複製代碼類型:[c]轉換
我們的通用轉換函數如下所示:ConvertProc()
註:WriteLogFile()是在描述我的舊的日誌記錄功能之一這個文章。
int SG_AudioConvert::ConvertProc(const wchar_t* p_szSrc, const wchar_t* p_szDst,
const GUID TargetFormat, const GUID ContainerType)
{
CTranscoder transcoder;
HRESULT hr = S_OK;
// Create a media source for the input file.
hr = transcoder.OpenFile(p_szSrc);
if (SUCCEEDED(hr))
{
//Configure the profile and build a topology.
hr = transcoder.ConfigureAudioOutput(TargetFormat);
}
else
{
return RET_INPUT_FAIL; // open input file fail
}
if (SUCCEEDED(hr))
{
hr = transcoder.ConfigureContainer(ContainerType);
}
//Transcode and generate the output file.
if (SUCCEEDED(hr))
{
hr = transcoder.EncodeToFile(p_szDst);
}
if (SUCCEEDED(hr))
{
WriteLogFile(L"Output file created: %sn", p_szDst);
}
else
{
WriteLogFile(L"Output file was not created due to error: %sn", p_szDst);
}
if (!SUCCEEDED(hr))
{
return RET_ENC_FAIL; // encoding failed
}
return RET_OK; // encoding success
}123456789101112131415161718192021222324252627282930313233343536373839404142434445複製代碼類型:[c]我們的轉換功能
這是我們的轉換函數:
以下六個功能涵蓋了以下音頻格式的每種組合之間的轉換:.mp3,.wav和.m4a。
// Convert to MP3
int SG_AudioConvert::Wav_to_Mp3(const wchar_t* p_szWavFile, const wchar_t* p_szMp3File)
{
// check initialize
if (!m_bInit)
return RET_NOT_INIT;
// convert
return(ConvertProc(p_szWavFile, p_szMp3File,
MFAudioFormat_MP3, MFTranscodeContainerType_MP3));
}
int SG_AudioConvert::M4A_to_Mp3(const wchar_t* p_szM4AFile, const wchar_t* p_szMp3File)
{
// check initialize
if (!m_bInit)
return RET_NOT_INIT;
// Convert
return(ConvertProc(p_szM4AFile, p_szMp3File,
MFAudioFormat_MP3, MFTranscodeContainerType_MP3));
}
// Convert to M4A
int SG_AudioConvert::Wav_to_M4A(const wchar_t* p_szWavFile, const wchar_t* p_szM4AFile)
{
// check initialize
if (!m_bInit)
return RET_NOT_INIT;
// Convert
return(ConvertProc(p_szWavFile, p_szM4AFile, MFAudioFormat_AAC,
MFTranscodeContainerType_MPEG4));
}
int SG_AudioConvert::MP3_to_M4A(const wchar_t* p_szMp3File, const wchar_t* p_szM4AFile)
{
// check initialize
if (!m_bInit)
return RET_NOT_INIT;
// Convert
return(ConvertProc(p_szMp3File, p_szM4AFile,MFAudioFormat_AAC,
MFTranscodeContainerType_MPEG4));
}
// Convert to Wav
int SG_AudioConvert::MP3_to_Wav(const wchar_t* p_szMp3File, const wchar_t* p_szWavFile)
{
// check initialize
if (!m_bInit)
return RET_NOT_INIT;
// Convert
return(ConvertProc(p_szMp3File, p_szWavFile, MFAudioFormat_PCM,
MFTranscodeContainerType_WAVE));
}
int SG_AudioConvert::M4A_to_Wav(const wchar_t* p_szM4AFile, const wchar_t* p_szWavFile)
{
// check initialize
if (!m_bInit)
return RET_NOT_INIT;
// Convert
return(ConvertProc(p_szM4AFile, p_szWavFile, MFAudioFormat_PCM,
MFTranscodeContainerType_WAVE));
}1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768複製代碼類型:[c]我們的文件搜索機制
我最近更新了一些舊代碼(感謝LoukaDiagnekov)來支持現代應用程序,包括UNICODE字元串,並且該代碼託管在此存儲庫中。
此類的一個不錯的功能是可以在一個搜索中設置多個查詢的功能。我們還可以遞歸地掃描文件夾及其子文件夾,以查找與我們的標準相匹配的文件。
這是struct運行搜索之前填寫的主要內容。請注意,當涉及到數百萬個文件時,此類有點慢,但是就我們的音頻轉換器工具而言,它可以正常工作。
// Specifies settings to use for searching for files
struct FindFileOptions_t
{
bool recursive; // Whether to look inside subdirectories
bool returnFolders; // Return folder names as results too
bool *terminateValue; // Value to check to see whether search should be
// terminated
wstring location; // Where to search for files
wstring filter; // Filter for files to be included
wstring excludeFile; // Exclude filter for files
wstring excludeDir; // Exclude filter for directories
};12345678910111213141516複製代碼類型:[c]我們的運作模式
我們定義了9種操作模式,可以將一種或兩種格式秘密轉換為第三種。這樣,我們可以在給定路徑中搜索一種或兩種類型的文件,並在找到時將其轉換為第三種格式。
typedef enum
{
M4A_WAV_TO_MP3 = 0, // convert m4a and wav to mp3
MP3_M4A_TO_WAV = 1, // convert mp3 and m4a to wav
MP3_WAV_TO_M4A = 2, // convert mp3 and wav to m4a
M4A_TO_MP3 = 3, // convert m4a to mp3
WAV_TO_MP3 = 4, // convert wav to mp3
MP3_TO_WAV = 5, // convert mp3 to wav
M4A_TO_WAV = 6, // convert m4a to wav
WAV_TO_M4A = 7, // convert wav to m4a
MP3_TO_M4A = 8, // convert mp3 to m4a
LAST_ELEMENT = 9
} OperationMode;1234567891011121314複製代碼類型:[c]讓我們採用一種「操作模式」並對其進行詳細說明。例如,MP3_WAV_TO_M4A。
在此模式下,我們希望在給定路徑中搜索.mp3和.wav文件,並將所有找到的文件轉換為m4a。
選擇此模式後,我們將執行以下操作:
使用以下查詢搜索文件:
#define QUERY_MP3_WAV L"*.mp3;*.wav";1複製代碼類型:[cpp]因此,回到我們的FindFile課程,我們將其設置為:
opts.filter = QUERY_MP3_WAV;1複製代碼類型:[cpp]然後,我們調用:
scanPath(wstring path)1複製代碼類型:[cpp]開始我們的文件搜索。搜索完成後,我們將得到一個數組,其中包含所有找到的文件,然後將這些文件轉換為我們的目標音頻類型。
用戶界面

該軟體基於基於Dialog的MFC應用程序。對話框可調整大小,並且每次調整對話框大小時都會調整每個元素。這是使用MarcRicharme的以下文章中的一些非常古老(但堅如磐石)的代碼實現的。對話框也有其自己的皮膚,背景顏色,透明元素,因此它看起來比標準MFC應用程序更好。
原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/226176.html
微信掃一掃
支付寶掃一掃