是否有旧的 Windows sndPlaySound() 函数的“现代”替代品,这是在您专注于其他事务时在后台播放 .wav 文件的一种非常方便的方法?我现在发现自己需要在后台播放一个 .mp3 文件,并且想知道如何以系统本身支持的相对简单的方式完成同样的事情。也许有一个 COM 组件来完成基本的 .mp3 播放?
3 回答
多年来,已经出现了一些与音频和媒体相关的 API,并且有几种方法可以实现这一目标。
在没有第三方库、最佳操作系统版本覆盖、功能集和简单性方面最好的是 DirectShow API。15 岁,仍然击败竞争对手,在当前和一些以前版本的 Visual Studio 可以针对的所有 Windows 版本中都支持,除了 WinRT。
下面的代码片段播放 MP3 和 WMA 文件。然而,由于它C++
都是 COM,因此可以很好地跨语言移植。
#include "stdafx.h"
#include <dshow.h>
#include <dshowasf.h>
#include <atlcom.h>
#pragma comment(lib, "strmiids.lib")
#define V(x) ATLVERIFY(SUCCEEDED(x))
int _tmain(int argc, _TCHAR* argv[])
{
static LPCTSTR g_pszPath = _T("F:\\Music\\Cher - Walking In Memphis.mp3");
V(CoInitialize(NULL));
{
CComPtr<IGraphBuilder> pGraphBuilder;
V(pGraphBuilder.CoCreateInstance(CLSID_FilterGraph));
CComPtr<IBaseFilter> pBaseFilter;
V(pBaseFilter.CoCreateInstance(CLSID_WMAsfReader));
CComQIPtr<IFileSourceFilter> pFileSourceFilter = pBaseFilter;
ATLASSERT(pFileSourceFilter);
V(pFileSourceFilter->Load(CT2COLE(g_pszPath), NULL));
V(pGraphBuilder->AddFilter(pBaseFilter, NULL));
CComPtr<IEnumPins> pEnumPins;
V(pBaseFilter->EnumPins(&pEnumPins));
CComPtr<IPin> pPin;
ATLVERIFY(pEnumPins->Next(1, &pPin, NULL) == S_OK);
V(pGraphBuilder->Render(pPin));
CComQIPtr<IMediaControl> pMediaControl = pGraphBuilder;
CComQIPtr<IMediaEvent> pMediaEvent = pGraphBuilder;
ATLASSERT(pMediaControl && pMediaEvent);
V(pMediaControl->Run());
LONG nEventCode = 0;
V(pMediaEvent->WaitForCompletion(INFINITE, &nEventCode));
}
CoUninitialize();
return 0;
}
如果您正在播放自己的文件,您肯定不会包含大的 ID3 标记部分,代码可能会短两倍。
像这样的许多问题的一个简单答案是简单地调用带有 system("play.exe soundfile.mp3") 或等效的命令行程序。只需将命令行视为另一个 API,一个功能广泛且标准、可移植、灵活、易于调试和易于修改的 API。它可能没有调用库函数那么有效,但这通常并不重要,特别是如果被调用的程序已经在磁盘缓存中。顺便说一句,避免软件复杂性只是因为它是“现代的”;这通常是建筑宇航员和糟糕的编程实践的证据。
当您说“现代”时,您是指 Windows 8 WinRT API 吗?或者您的意思是“比为 Windows 3.1 发明的 API 稍新的 API”?
对于经典的 Windows 桌面应用程序,有PlaySound,它可以播放任何 WAV 文件。
对于 MP3,我的团队发明了一种使用 DirectSound 和Windows Media Format SDK的解决方案。后者可以解码任何 WMA 和 MP3 文件。我们将音频流直接馈入 DSound 缓冲区。这不适合胆小的人。
您可能会使用更高级别的替代方案,即Windows Media Player API。
DirectShow是一个非常传统的替代方案,但很容易启动和工作。 Media Foundation是 DirectShow 的替代品。