在 Windows 中简单的 .wav 或 .mp3 播放 - 它去哪儿了?

Posted

技术标签:

【中文标题】在 Windows 中简单的 .wav 或 .mp3 播放 - 它去哪儿了?【英文标题】:simple .wav or .mp3 playbck in Windows - where has it gone? 【发布时间】:2012-10-14 02:27:32 【问题描述】:

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

【问题讨论】:

Couple of suggestions here. 【参考方案1】:

多年来,已经出现了一些与音频和媒体相关的 API,并且有几种方法可以实现这一目标。

在没有第三方库、最佳操作系统版本覆盖、功能集和简单性方面最好的是 DirectShow API。 15 岁,仍然击败竞争对手,在当前和一些以前版本的 Visual Studio 可以定位的所有 Windows 版本中都受支持,WinRT 除外。

下面的代码 sn-p 播放 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 标签部分,the code might be twice as short。

【讨论】:

【参考方案2】:

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

【讨论】:

【参考方案3】:

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

音视频api调查可查here

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

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

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

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

【讨论】:

PlaySound 是一种古老但足够的解决方案,尤其是当无法证明实施更复杂的事情的时间时。我只是希望有与 ios AVAudioPlayer 等效的东西,您可以在其中使用大约五行代码来完成此操作。不过这是Win32。叹息...

以上是关于在 Windows 中简单的 .wav 或 .mp3 播放 - 它去哪儿了?的主要内容,如果未能解决你的问题,请参考以下文章

Windows Phone 8 可以播放 WAV 文件但不能播放 MP3

如何在 asp.net mvc 项目中添加 .mp3 或 .wav 文件?

在播放 mp3 或 wav 时结合 NAudio Pan 和 JSNet SuperPitch

ffmpeg sox 音频转换 MP3 转 wav

编写一个简单的 python 脚本,使用 lame 将特定文件夹中的所有 .wav 文件转换为 .mp3

如何将wav转换成mp3格式