This will be the simplest way to play mp3's in C++ using DirectShow. Before you can even use DirectShow though, if you haven't already, download the latest Windows SDK. Next you will need to compile the BaseClasses hidden in the SDK over in this file path:
C:\Program Files\Microsoft SDKs\Windows\v7.1\Samples\multimedia\directshow\baseclasses.
Open up the solution file using Visual C++ 2010, and compile it in both Debug and Release. If it doesn't compile right, and sometimes it doesn't, refer to Google for a solution like I did. Unfortunately I forgot the issue I had since it was a long time ago. Once you successfully compiled it in Debug and Release, you won't ever have to do that again and can now work with DirectShow anytime.
Create a new empty VC++ project, and right click your project and goto Properties. Then goto Configuration Properties > Linker > Input and where it says Additional Dependencies, click on it until you see a [v] symbol, and open it. Then click <Edit...>. Next in the large box, just put strmiids.lib, hit enter, and put quartz.lib. Click Ok. Then in the Properties window, click Ok there too. Copy and paste this code, change the name of the mp3 you desire and put it where your exe is being compiled to, whether its Debug or Release, and run it. Right now I got World of Warcraft - Seasons of War.mp3. It should play majority of the mp3's. For some reason it doesn't play all of em out there. And I have to conduct some experiments to find out which ones run and which ones don't but it should play. And heres the code. If you want shorter code then this, then you would have to eliminate the error handling and hr's, but its not wise to run without error handling:
C++ Code:
#include <DShow.h> #include <string> using namespace std; void ShowError(HRESULT hr); int CALLBACK WinMain( _In_ HINSTANCE hInstance, _In_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow ) { HRESULT hr; IGraphBuilder *pGraph = NULL; IMediaControl *pControl = NULL; IMediaEvent *pEvent = NULL; try { hr = CoInitialize(NULL); ShowError(hr); hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGraph); ShowError(hr); char File_Name[255] = "World of Warcraft - Seasons Of War.mp3"; char buffer[MAX_PATH]; string Result; GetModuleFileName( NULL, buffer, MAX_PATH ); string startuppath = string(buffer); string filename = string(File_Name); startuppath = startuppath.substr(0, startuppath.find_last_of( "\\/" )); Result = startuppath + string("\\") + filename; const char *File_Path = Result.c_str(); WCHAR *MediaFile = new WCHAR[strlen(File_Path)+1]; MultiByteToWideChar(CP_ACP, 0, File_Path, -1, MediaFile, strlen(File_Path)+1); hr = pGraph->RenderFile(MediaFile, NULL); ShowError(hr); hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl); ShowError(hr); hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent); ShowError(hr); hr = pControl->Run(); ShowError(hr); long evCode = 0; hr = pEvent->WaitForCompletion(INFINITE, &evCode); ShowError(hr); } catch(TCHAR szErr[]) { MessageBox(NULL, (LPCSTR)szErr, TEXT("DirectShow"), 0); } if(pGraph) { pGraph->Release(); pGraph = NULL; } if (pControl) { pControl->Release(); pControl = NULL; } if (pEvent) { pEvent->Release(); pEvent = NULL; } CoUninitialize(); return hr; } void ShowError(HRESULT hr) { if (FAILED(hr)) { TCHAR szErr[MAX_ERROR_TEXT_LEN] = {0}; DWORD res = AMGetErrorText(hr, szErr, MAX_ERROR_TEXT_LEN); if (res == 0) { StringCchPrintf(szErr, MAX_ERROR_TEXT_LEN, "Unknown Error: 0x%2x", hr); } throw szErr; } }
The short short hello world version (no error handling)
C++ Code:
#include <DShow.h> #include <string> using namespace std; int CALLBACK WinMain( _In_ HINSTANCE hInstance, _In_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow ) { IGraphBuilder *pGraph = NULL; IMediaControl *pControl = NULL; IMediaEvent *pEvent = NULL; CoInitialize(NULL); CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGraph); char File_Name[255] = "World of Warcraft - Seasons Of War.mp3"; char buffer[MAX_PATH]; string Result; GetModuleFileName( NULL, buffer, MAX_PATH ); string startuppath = string(buffer); string filename = string(File_Name); startuppath = startuppath.substr(0, startuppath.find_last_of( "\\/" )); Result = startuppath + string("\\") + filename; const char *File_Path = Result.c_str(); WCHAR *MediaFile = new WCHAR[strlen(File_Path)+1]; MultiByteToWideChar(CP_ACP, 0, File_Path, -1, MediaFile, strlen(File_Path)+1); pGraph->RenderFile(MediaFile, NULL); pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl); pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent); pControl->Run(); long evCode = 0; pEvent->WaitForCompletion(INFINITE, &evCode); pGraph->Release(); pGraph = NULL; pControl->Release(); pControl = NULL; pEvent->Release(); pEvent = NULL; CoUninitialize(); }
Do I have to make it shorter.....yeeeesh. Fine but the mp3 will be in the C drive instead
C++ Code:
#include <DShow.h> int CALLBACK WinMain( _In_ HINSTANCE hInstance, _In_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow ) { IGraphBuilder *pGraph = NULL; IMediaControl *pControl = NULL; IMediaEvent *pEvent = NULL; CoInitialize(NULL); CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGraph); pGraph->RenderFile(L"C:\\World of Warcraft - Seasons of War.mp3", NULL); pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl); pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent); pControl->Run(); long evCode = 0; pEvent->WaitForCompletion(INFINITE, &evCode); pGraph->Release(); pGraph = NULL; pControl->Release(); pControl = NULL; pEvent->Release(); pEvent = NULL; CoUninitialize(); }