SOL9 Sample: MusicPlayer

SOL9 2.0 Samples

1 Screenshot


2 Source code

/*
 * MusicPlayer.cpp 
 * Copyright (c) 2011 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 hr) {
        }
        //
        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()
    {
	//2011/02/25
        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: 25 Feb 2011

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