SOL9 Sample: MusicPlayer

SOL9 2.0 Samples

1 Screenshot


2 Source code

/*
 * MusicPlayer.cpp 
 * Copyright (c) 2015 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED. 
 */


// 2011/02/25 Sample program to play music files (*.wmv, *.wma and *.mp3) without a window
// by using WindowsMedia classes of SOL9.

#include <sol/Object.h>
#include <sol/ole/OleSite.h>
#include <wmp.h>

#include <sol/ole/MediaEvents.h>
#include <sol/ArgListT.h>

namespace SOL {

#define WM_PLAY_FINISHED (WM_USER + 2011)

//MediaEvents Listener class derived from SOL::MediaEvents 

class MusicMediaEvents :public MediaEvents {
private:
  DWORD threadId;

private:
  IWMPPlayer4* pPlayer;

public:
  //Constructor
  MusicMediaEvents(DWORD thread)
    :pPlayer(NULL),
    threadId(thread)
  {
  }

public:
  void putPlayer(IWMPPlayer4* player)
  {
    pPlayer = player;
  }

public:
  virtual void __stdcall PlayStateChange (__in long NewState)
  {
    static const ArgT<TCHAR> states[] = {
    {_T("Undefined"),   0},
    {_T("Stopped"),   1}, 
    {_T("Paused"),     2}, 
    {_T("Playing"),   3}, 
    {_T("ScanForward"),   4}, 
    {_T("ScanReverse"),   5}, 
    {_T("Buffering"),   6}, 
    {_T("Waiting"),   7}, 
    {_T("MediaEnded"),   8}, 
    {_T("Transitioning"),   9}, 
    {_T("Ready"),   10},
    };

    ArgListT<TCHAR> argList(states, SizeOf(states));

    const TCHAR* name =argList.getName(NewState);
    _tprintf(_T("PlayStateChange NewState=%s (%d)\n"), name, NewState);
    if (NewState == 1) {
      printf("...Play finished\n");
      //Playing haved stopped, so post a user-defined message WM_PLAY_FINISHED 
      //to terminate a message loop in _tmain.
      PostThreadMessage(threadId, WM_PLAY_FINISHED, 0, 0);
    }

    if (NewState == 3) {
      double duration = 0.0;
      //We are notified to be 'playing' a media, so try to get a duration time of the media.
      if (pPlayer) {
        IWMPMedia* pMedia = NULL;
        HRESULT hr = pPlayer->get_currentMedia(&pMedia);
        if (SUCCEEDED(hr)) {
          pMedia->get_duration(&duration);
          pMedia->Release();
        }
      }
      printf("...Play started duration=%f(seconds)\n", duration);  
    }
  }
};


// Windowless WindowsMediaPlay to play a music of the windows media or mp3 files.

class MusicPlayer :public Object {

private:
  IOleObject*  oleObject;
  IWMPPlayer4* pPlayer;

  COleSite oleSite;
  MusicMediaEvents mediaEvents;

public:
  // Constructor
  MusicPlayer(DWORD threadId)
    :oleObject(NULL),
    pPlayer(NULL),
    mediaEvents(threadId)
  {
    IWMPSettings *pSetting = NULL;

    try {
      HRESULT hr = CoCreateInstance( __uuidof(WindowsMediaPlayer), 0, CLSCTX_INPROC_SERVER, 
        IID_IOleObject, (void **)&oleObject);

      if (FAILED(hr)) {
        throw Exception("Failed to cocreateInstance\n", hr);
      }

      hr = oleObject->QueryInterface(__uuidof(IWMPPlayer), (void**)&pPlayer);
      if (FAILED(hr)) {
        throw Exception("Failed to queryInterface\n", hr);
      }

      hr = oleObject-> SetClientSite(&oleSite);
      if (FAILED(hr)) {
        throw Exception("SetClientSite failed\n", hr);
      }
  
      hr = mediaEvents.Advise(oleObject, __uuidof(IWMPEvents));
      if (FAILED(hr)) {
        throw Exception("Advise failed\n", hr);
      }

      hr = pPlayer->QueryInterface(__uuidof(IWMPSettings), (void **)&pSetting);
      if (FAILED(hr)) {
        throw Exception("QueryInterface to Setting failed\n", hr);
      }
      //Auto-start
      pSetting->put_autoStart(VARIANT_TRUE);

      mediaEvents.putPlayer(pPlayer);

    } catch (Exception& ex) {
      ex.printf();
    } catch (HRESULT ) {
    }
    //
    if (pSetting) pSetting->Release();

    if (oleObject==NULL) {
      throw Exception("Failed to create OleObject\n");
    }
    if (pPlayer==NULL) {
      throw Exception("Failed to create MusicPlayer\n");
    }
  }

public:
  // Destructor
  ~MusicPlayer()
  {
    mediaEvents.Unadvise(oleObject, __uuidof(IWMPEvents));

    if (oleObject) oleObject->Release();
    if (pPlayer)   pPlayer->Release();
  }

public:
  void play(const TCHAR* file)
  {
    _bstr_t filename = file;
    pPlayer->put_URL(filename);
  }
};

}

// Console application 
void _tmain(int argc, _TCHAR* argv[])
{
  if (argc !=2) {
    _tprintf(_T("Usage: %s musicfile(*.mp3 or *.wmv or *.wma)\n"), argv[0]);
    _tprintf(_T("Ex: %s chichibu.wmv\n"), argv[0]);
    return;
  }

  if (GetFileAttributes(argv[1]) == 0xffffffff) {
    _tprintf(_T("File not found %s\n"), argv[1]);
    return;
  }

  OleInitialize(NULL);
  try {
    DWORD threadId = GetCurrentThreadId();

    MusicPlayer musicPlayer(threadId);
    musicPlayer.play(argv[1]);

    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0)) {
      if (msg.message == WM_PLAY_FINISHED) {
        //We got a message from MusicMediaEvents class to termainte this message loop
        break;
      }
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    }
  } catch (Exception& ex) {
    ex.printf();
  } catch (HRESULT hr) {
    printf("Exception HRESULT=%x\n", hr);
  } catch (...) {
  }
  OleUninitialize();
}


Last modified: 2 May 2016

Copyright (c) 2016 Antillia.com ALL RIGHTS RESERVED.