# VBForums CodeBank > CodeBank - C++ >  DirectShow Play Mp3's!!! (Hello World Version)

## Jacob Roman

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();
}

----------


## Jacob Roman

This is pretty much the same concept, without the error handling for readability, only this one actually opens a window, so you can close out of it to close the program, or you can press escape. Now in the previous example, if you were to run the exe itself and not through VC++, you won't be able to close out of it unless you Ctrl+Alt+Delete. At least through VC++ theres a stop button. So heres a windowed version with the ability to close out of it (without error handling. If you want, add the error handling in the previous example):


C++ Code:
#include <Windows.h>#include <DShow.h>#include <string>using namespace std; IGraphBuilder *DirectShow_GraphBuilder = NULL;IMediaEvent *DirectShow_Event = NULL;IMediaControl *DirectShow_Control = NULL; HWND hWnd;MSG msg; int DirectShow_Load_Media();LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM); int DirectShow_Load_Media(const char *File_Name){    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);        CoInitialize(NULL);    CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&DirectShow_GraphBuilder);    DirectShow_GraphBuilder->QueryInterface(IID_IMediaControl,(void **)&DirectShow_Control);    DirectShow_GraphBuilder->QueryInterface(IID_IMediaEvent, (void **)&DirectShow_Event);    DirectShow_GraphBuilder->RenderFile(MediaFile, NULL);    //MessageBoxW(NULL, MediaFile, L"test", MB_OK);    return 0;} int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nCmdShow){    WNDCLASSEX wc = {sizeof(WNDCLASSEX), CS_VREDRAW|CS_HREDRAW|CS_OWNDC, WindowProcedure, 0, 0, hInstance, NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, "TUTORIAL", NULL};    RegisterClassEx(&wc);    hWnd = CreateWindowEx (0, "TUTORIAL", "MP3 Player", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 330, 250, HWND_DESKTOP, NULL, hInstance, NULL);    ShowWindow (hWnd, nCmdShow);    DirectShow_Load_Media("World of Warcraft - Seasons of War.mp3");    while (1)    {        if (PeekMessage(&msg,NULL,0,0,PM_REMOVE) > 0)        {            if (WM_QUIT == msg.message) break;            TranslateMessage (&msg);            DispatchMessage (&msg);        }        else            DirectShow_Control->Run();    }    return msg.wParam;} LRESULT CALLBACK WindowProcedure (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){    switch (msg)    {        case WM_DESTROY:            DirectShow_Control->Release();            DirectShow_Event->Release();            DirectShow_GraphBuilder->Release();            DirectShow_Control = NULL;            DirectShow_Event = NULL;            DirectShow_GraphBuilder = NULL;            CoUninitialize();            PostQuitMessage (0);            break;        case WM_KEYDOWN:            if(wParam == VK_ESCAPE)            {                DestroyWindow(hWnd);                return(0);            }        default:            return DefWindowProc (hWnd, msg, wParam, lParam);    }    return 0;}

----------

