5

是否有旧的 Windows sndPlaySound() 函数的“现代”替代品,这是在您专注于其他事务时在后台播放 .wav 文件的一种非常方便的方法?我现在发现自己需要在后台播放一个 .mp3 文件,并且想知道如何以系统本身支持的相对简单的方式完成同样的事情。也许有一个 COM 组件来完成基本的 .mp3 播放?

4

3 回答 3

2

多年来,已经出现了一些与音频和媒体相关的 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 标记部分,代码可能会短两倍

于 2012-10-14T09:12:57.350 回答
1

像这样的许多问题的一个简单答案是简单地调用带有 system("play.exe soundfile.mp3") 或等效的命令行程序。只需将命令行视为另一个 API,一个功能广泛且标准、可移植、灵活、易于调试和易于修改的 API。它可能没有调用库函数那么有效,但这通常并不重要,特别是如果被调用的程序已经在磁盘缓存中。顺便说一句,避免软件复杂性只是因为它是“现代的”;这通常是建筑宇航员和糟糕的编程实践的证据。

于 2012-10-14T09:01:35.440 回答
0

当您说“现代”时,您是指 Windows 8 WinRT API 吗?或者您的意思是“比为 Windows 3.1 发明的 API 稍新的 API”?

可以在这里找到音频和视频 api 的调查

对于经典的 Windows 桌面应用程序,有PlaySound,它可以播放任何 WAV 文件。

对于 MP3,我的团队发明了一种使用 DirectSound 和Windows Media Format SDK的解决方案。后者可以解码任何 WMA 和 MP3 文件。我们将音频流直接馈入 DSound 缓冲区。这不适合胆小的人。

您可能会使用更高级别的替代方案,即Windows Media Player API

DirectShow是一个非常传统的替代方案,但很容易启动和工作。 Media Foundation是 DirectShow 的替代品。

于 2012-10-14T08:40:52.330 回答