locked
Playing Mp3 files in a Windows Mobile Win32 application RRS feed

  • Question

  • Hello all!

    I am trying to play an MP3 file in a Windows Mobile Win32 application application.

    here is the code:

    BOOL cMP3::InitMP3()

    {

     

    if (cMP3::s_pGraphBuilder)

     

    return TRUE;

    HRESULT h;

     

    // Initialise COM, so that we can use CoCreateInstance.

    ::CoInitialize(NULL);

     

     

    // Create an IGraphBuilder object, through which

     

    // we will create a DirectShow graph.

    h = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (

    void **)&cMP3::s_pGraphBuilder);

     

    if (FAILED(h))

    {

     

    return FALSE;

    }

     

    // Get the IMediaControl Interface

    h = cMP3::s_pGraphBuilder->QueryInterface(IID_IMediaControl, (

    void **)&cMP3::s_pMediaControl);

     

    if (FAILED(h))

    {

     

    return FALSE;

    }

     

    // Get the IMediaSeeking Interface

    h = cMP3::s_pGraphBuilder->QueryInterface(IID_IMediaSeeking, (

    void **)&cMP3::s_pMediaSeeking);

     

    if (FAILED(h))

    {

     

    return FALSE;

    }

     

    // Get the IMediaEventEx Interface

    h = cMP3::s_pGraphBuilder->QueryInterface(IID_IMediaEventEx,(

    void **)&cMP3::s_pMediaEventEx);

     

    if (FAILED(h))

    {

     

    return FALSE;

    }

     

    return TRUE;

    }

    bool

     

    cMP3::Play(bool bLoop)

    {

    IBaseFilter *pSource;

    IPin *pPin = NULL;

    IEnumFilters *pFilterEnum = NULL;

    IBaseFilter **ppFilters;

    IBaseFilter *pFilterTemp = NULL;

     

    int iFiltCount;

     

    int iPos;

     

    bool bInit = pSource == NULL;

     

    if (!InitMP3())

     

    return false;

     

    // Add the new source filter to the graph.

    HRESULT h;

     

    if (bInit)

    {

    h = cMP3::s_pGraphBuilder->AddSourceFilter(m_szSndFileName, m_szSndFileName, &pSource);

     

    if (FAILED(h))

     

    return false;

    }

     

    // Get the first output pin of the new source filter. Audio sources

     

    // typically have only one output pin, so for most audio cases finding

     

    // any output pin is sufficient.

    pSource->FindPin(L

    "Output", &pPin);

     

    // Stop the graph

    cMP3::s_pMediaControl->Stop();

     

    // Break all connections on the filters. You can do this by adding

     

    // and removing each filter in the graph

     

    if (bInit)

    {

    cMP3::s_pGraphBuilder->EnumFilters(&pFilterEnum);

     

     

    // Need to know how many filters. If we add/remove filters during the

     

    // enumeration we'll invalidate the enumerator

     

    for (iFiltCount = 0; pFilterEnum->Skip(1) == S_OK; iFiltCount++)

    ;

     

    // Allocate space, then pull out all of the

    ppFilters = (IBaseFilter **)_alloca(

    sizeof(IBaseFilter *) * iFiltCount);

    pFilterEnum->Reset();

     

    for (iPos = 0; pFilterEnum->Next(1, &ppFilters[iPos], NULL) == S_OK; iPos++)

    ;

     

    pFilterEnum->Release();

     

    for (iPos = 0; iPos < iFiltCount; iPos++)

    {

    cMP3::s_pGraphBuilder->RemoveFilter(ppFilters[iPos]);

     

     

    // Put the filter back

    cMP3::s_pGraphBuilder->AddFilter(ppFilters[iPos], NULL);

    ppFilters[iPos]->Release();

    }

    }

     

    // We have the new output pin. Render it

    h = cMP3::s_pGraphBuilder->Render(pPin);

     

    if (h == VFW_E_CANNOT_CONNECT)

    {

    OutputDebugString(L

    "Error!!!!!!!!!!!");

    }

    pPin->Release();

     

    // Re-seek the graph to the beginning

    LONGLONG llPos = 0;

    cMP3::s_pMediaSeeking->SetPositions(&llPos, AM_SEEKING_AbsolutePositioning, &llPos, AM_SEEKING_NoPositioning);

     

    // Start the graph

    h = cMP3::s_pMediaControl->Run();

     

    return true;

    }

    The problem is thath on the emulator and on most devices (I tried 4 devices and just 1 works and plays the mp3 file properly) the 

    cMP3::s_pGraphBuilder->Render(pPin);

    returns VFW_E_CANNOT_CONNECT.

    What could cause this? Is there any other way to play an mp3 file on Windows Mobile?

    Please advice!

    Thanks!

     

    Saturday, October 17, 2009 10:00 AM

Answers

  • I can bet that the one device which ran this, had a mp3 direct show filter implemented :).
    Normally OEMs doesn't give this filter because WM has WMP to play mp3 files.

    So DS won't do any good here. You must use WMP.
    Download WMP SDK (for standard Windows - there are compatible).
    Get Your hands on proper header files (wmp.h) and use it like this (it's only an example):

    IWMPPlayer *player = NULL;
    IWMPControls *controls = NULL;
    IWMPSettings *settings = NULL;

    CoInitializeEx(NULL, COINIT_MULTITHREADED);
    if(CoCreateInstance(__uuidof(WindowsMediaPlayer), 0, CLSCTX_INPROC_SERVER, __uuidof(IWMPPlayer), (void **)&player) == S_OK)
    {
    player->get_controls(&controls);
    player->get_settings(&settings);

    player->put_URL(path);
    controls->play();
    }

    player->close();
    controls->Release();
    settings->Release();
    player->Release();
    player = NULL;

    CoUninitialize();

    Have fun!

    If You'll find my answer satisfactory or helpful - mark it as answered or vote for it! Thank You.
    "If You think You know better then me, why is Your code not working, then don't waste my time at this forum. Otherwise - do as I'm suggesting."
    • Proposed as answer by Mal Loth Saturday, October 17, 2009 4:39 PM
    • Marked as answer by bogdand84 Saturday, October 17, 2009 7:31 PM
    • Unmarked as answer by bogdand84 Saturday, October 17, 2009 9:15 PM
    • Marked as answer by bogdand84 Sunday, October 18, 2009 11:40 AM
    Saturday, October 17, 2009 4:38 PM
  • Have You tried to add a NULL or any other file? :)

    DS is so smart that it should generate the whole graph only if You just use Render() and Run().
    Unfortunately the problem is with WM: DS can't connect to the filters for extentions which are already being used (mp3 and others are already used by WMP).

    You can run WAV files directly or make filters to other extentions, but not an mp3 or other commonly used files.

    If You'll find my answer satisfactory or helpful - mark it as answered or vote for it! Thank You.
    "If You think You know better then me, why is Your code not working, then don't waste my time at this forum. Otherwise - do as I'm suggesting."
    • Proposed as answer by Mal Loth Sunday, October 18, 2009 11:06 AM
    • Marked as answer by bogdand84 Sunday, October 18, 2009 11:40 AM
    Sunday, October 18, 2009 11:05 AM

All replies

  • I can bet that the one device which ran this, had a mp3 direct show filter implemented :).
    Normally OEMs doesn't give this filter because WM has WMP to play mp3 files.

    So DS won't do any good here. You must use WMP.
    Download WMP SDK (for standard Windows - there are compatible).
    Get Your hands on proper header files (wmp.h) and use it like this (it's only an example):

    IWMPPlayer *player = NULL;
    IWMPControls *controls = NULL;
    IWMPSettings *settings = NULL;

    CoInitializeEx(NULL, COINIT_MULTITHREADED);
    if(CoCreateInstance(__uuidof(WindowsMediaPlayer), 0, CLSCTX_INPROC_SERVER, __uuidof(IWMPPlayer), (void **)&player) == S_OK)
    {
    player->get_controls(&controls);
    player->get_settings(&settings);

    player->put_URL(path);
    controls->play();
    }

    player->close();
    controls->Release();
    settings->Release();
    player->Release();
    player = NULL;

    CoUninitialize();

    Have fun!

    If You'll find my answer satisfactory or helpful - mark it as answered or vote for it! Thank You.
    "If You think You know better then me, why is Your code not working, then don't waste my time at this forum. Otherwise - do as I'm suggesting."
    • Proposed as answer by Mal Loth Saturday, October 17, 2009 4:39 PM
    • Marked as answer by bogdand84 Saturday, October 17, 2009 7:31 PM
    • Unmarked as answer by bogdand84 Saturday, October 17, 2009 9:15 PM
    • Marked as answer by bogdand84 Sunday, October 18, 2009 11:40 AM
    Saturday, October 17, 2009 4:38 PM
  • It works. Thanks a lot!

    Saturday, October 17, 2009 7:36 PM
  • I have another question concernig DS. If the other devices doesn't have a mp3 direct show filter implemented why the

    h = cMP3::s_pGraphBuilder->AddSourceFilter(m_szSndFileName, m_szSndFileName, &pSource);

    returns S_OK. Returning S_OK doesn't mean that a filter that can read the file is found? Or is a difference between reading a file and rendering/playing the file?


    Thanks!

    Saturday, October 17, 2009 9:11 PM
  • Have You tried to add a NULL or any other file? :)

    DS is so smart that it should generate the whole graph only if You just use Render() and Run().
    Unfortunately the problem is with WM: DS can't connect to the filters for extentions which are already being used (mp3 and others are already used by WMP).

    You can run WAV files directly or make filters to other extentions, but not an mp3 or other commonly used files.

    If You'll find my answer satisfactory or helpful - mark it as answered or vote for it! Thank You.
    "If You think You know better then me, why is Your code not working, then don't waste my time at this forum. Otherwise - do as I'm suggesting."
    • Proposed as answer by Mal Loth Sunday, October 18, 2009 11:06 AM
    • Marked as answer by bogdand84 Sunday, October 18, 2009 11:40 AM
    Sunday, October 18, 2009 11:05 AM
  • Thanks for explanations!
    Sunday, October 18, 2009 11:42 AM
  • Could you share about what you mean by "extensions are known to be already in use by WMP"? Is there a way to retrieve all those "extensions" that are used by WMP? Does WMP itself uses DS and connect to the filters for those extensions on system startup hence locking it thereafter? I'd like to understand this in more details and do not seem to be able to find such information on MSDN or Web at all. Essentially I need to know how to reliably determine a device's support for audio formats or streams, be it to be played with WMP or DS. Thanks.
    Friday, January 15, 2010 11:26 AM