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.
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
.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With