I am trying to play a movie using Windows Media Player, later on will add some other functionality. Following is the code I have written:
const CLSID CLSID_WindowsMediaPlayer = {0x6BF52A52, 0x394A, 0x11d3, {0xB1, 0x53, 0x00, 0xC0, 0x4F, 0x79, 0xFA, 0xA6 } };
HRESULT hr;
IWMPPlayer *pMediaPlayer = NULL;
hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
if(FAILED(hr))
{
std::cout << "ERR -- Could not Initialize COM engine for you" << std::endl;
return 0;
}
hr = CoCreateInstance(CLSID_WindowsMediaPlayer, NULL, CLSCTX_INPROC_SERVER, IID_IDispatch, (void**)&pMediaPlayer);
if(FAILED(hr))
{
std::cout << "ERR - Could not get WMPPlayer Interface Pointer" << std::endl;
return 0;
}
std::cout << "Got MediaPlayer Pointer" << std::endl;
IWMPSettings *pMediaPlayerSettings = NULL;
hr = pMediaPlayer->get_settings(&pMediaPlayerSettings);
if(FAILED(hr))
{
std::cout << "ERR - Could not get WMPSettings Interface Pointer" << std::endl;
ReleaseInterfaces((IUnknown**)&pMediaPlayer);
return 0;
}
std::cout << "Got MediaPlayerSettings Pointer" << std::endl;
hr = pMediaPlayerSettings->put_autoStart(VARIANT_TRUE);
if(FAILED(hr))
{
std::cout << "ERR - Could not put auto_start to true" << std::endl;
ReleaseInterfaces((IUnknown**)&pMediaPlayerSettings);
ReleaseInterfaces((IUnknown**)&pMediaPlayer);
return 0;
}
std::cout << "Have put it to autostart" << std::endl;
hr = pMediaPlayerSettings->put_volume(50);
if(FAILED(hr))
{
std::cout << "ERR - Could not put volume" << std::endl;
ReleaseInterfaces((IUnknown**)&pMediaPlayerSettings);
ReleaseInterfaces((IUnknown**)&pMediaPlayer);
return 0;
}
std::cout << "Have put volume to listen-able" << std::endl;
hr = pMediaPlayer->put_URL(L"C:\\background.mp3");
if(FAILED(hr))
{
std::cout << "ERR - Could not set URL" << std::endl;
ReleaseInterfaces((IUnknown**)&pMediaPlayerSettings);
ReleaseInterfaces((IUnknown**)&pMediaPlayer);
return 0;
}
std::cout << "Have set URL" << std::endl;
So far all is good. But file is never played. Upon further investigation, I found out that WMPPlayState
never becomes wmppsPlaying
, So i tested if file is opened using WMPOpenState
but here I always get wmposOpeningUnknownURL
. I first thought this might be because I have put file in C:
, which needs admin rights, but using other location also yields same result. I have checked if the URL i set using put_URL
is actually put, and yes, get_URL
gives out my set url. I have also tested with different files and formats.
Moreover, Windows Media Player is NOT opened!
hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
That's a pretty common selection. We can't see the rest of your code, but the shoe fits. It requires you to do the other thing that's a hard requirement for an STA thread. You must pump a message loop. Failure to do so causes various problems, deadlock is not uncommon. And yes, the state won't change, the signaling between worker threads inside WMP and your apartment thread is borken because you don't pump.
You get a message loop in a GUI app, pick the Win32 Project project template for example, not the Win32 Console Application template. Or add the code, boilerplate is:
MSG msg;
while(GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
And do beware that you don't get a window, you asked for CLSCTX_INPROC_SERVER. In other words, WMP runs in-process, inside your program. Getting a window requires using ActiveX hosting, not something you'd typically want to tackle without significant help from a class library like MFC or Winforms. Maybe what you really meant to do is run it out-of-process so it can display its own window?