Use Windows built in MP3 decoder to play audio?

心不动则不痛 提交于 2019-12-18 03:44:57

问题


How do I from C or C++ use the MP3 decoder supposedly built in with Windows since Windows Media Player 6.1?

I want to play an mp3 file without having to depend on any other third party library such as for instance LAME.DLL.

I updated the question to better fit the answers I got, since I liked them a lot. Related question.


回答1:


You can control an audio channel (in order to make it play anything, including MP3) with mciSendString http://msdn.microsoft.com/en-us/library/ms709492%28VS.85%29.aspx

Here's an example (it's in C#, but it's basically the same principle):

http://social.msdn.microsoft.com/forums/en-US/Vsexpressvcs/thread/152f0149-a62a-446d-a205-91256da7845d

Here is the same principle in C:

http://www.daniweb.com/software-development/c/code/268167




回答2:


Sure. Like lots of other things in the Windows API, there's more than one way to go about playing .mp3 files. The "easiest" way to do this programmatically is using DirectShow. The MSDN docs even include a minimal code example on a page aptly called "How To Play a File" to get you started:

// Visual C++ example
#include <dshow.h>
#include <cstdio>
// For IID_IGraphBuilder, IID_IMediaControl, IID_IMediaEvent
#pragma comment(lib, "strmiids.lib") 

// Obviously change this to point to a valid mp3 file.
const wchar_t* filePath = L"C:/example.mp3"; 

int main()
{
    IGraphBuilder *pGraph = NULL;
    IMediaControl *pControl = NULL;
    IMediaEvent   *pEvent = NULL;

    // Initialize the COM library.
    HRESULT hr = ::CoInitialize(NULL);
    if (FAILED(hr))
    {
        ::printf("ERROR - Could not initialize COM library");
        return 0;
    }

    // Create the filter graph manager and query for interfaces.
    hr = ::CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, 
                        IID_IGraphBuilder, (void **)&pGraph);
    if (FAILED(hr))
    {
        ::printf("ERROR - Could not create the Filter Graph Manager.");
        return 0;
    }

    hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
    hr = pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);

    // Build the graph.
    hr = pGraph->RenderFile(filePath, NULL);
    if (SUCCEEDED(hr))
    {
        // Run the graph.
        hr = pControl->Run();
        if (SUCCEEDED(hr))
        {
            // Wait for completion.
            long evCode;
            pEvent->WaitForCompletion(INFINITE, &evCode);

            // Note: Do not use INFINITE in a real application, because it
            // can block indefinitely.
        }
    }
    // Clean up in reverse order.
    pEvent->Release();
    pControl->Release();
    pGraph->Release();
    ::CoUninitialize();
}

Make sure you read through the DirectShow documentation to get an idea of what's supposed to happen in a proper DirectShow application.


To "feed" media data into a graph, you need to implement a IAsyncReader. Fortunately, the Windows SDK includes a sample that implements an IAsyncReader called CAsyncReader. The sample reads a media file into a memory buffer then uses CAsyncReader to stream the data into the graph. This may be what you want. On my machine the sample is located in the folder C:\Program Files\Microsoft SDKs\Windows\v7.0\Samples\multimedia\directshow\filters\async.



来源:https://stackoverflow.com/questions/8121570/use-windows-built-in-mp3-decoder-to-play-audio

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!