5

古い W​​indows の sndPlaySound() 関数に代わる "最新の" 機能はありますか?これは、他のことに集中しているときにバックグラウンドで .wav ファイルを再生する非常に便利な方法でしたか? バックグラウンドで .mp3 ファイルを再生する必要があり、システムが本質的にサポートしている比較的簡単な方法で同じことを達成する方法を考えています。基本的な .mp3 再生を実現するための COM コンポーネントがあるのではないでしょうか?

4

3 に答える 3

2

何年にもわたって、いくつかのオーディオおよびメディア関連の API があり、目標を達成する方法はいくつかあります。

サードパーティのライブラリがないこと、最適な OS バージョン カバレッジ、機能セット、シンプルさの点で最高なのは、DirectShow API です。15 歳の今でもライバルを打ち負かしており、WinRT を除く、現在のすべてのバージョンの Windows と、V​​isual Studio の以前のいくつかのバージョンが対象とする可能性のあるバージョンでサポートされています。

以下のコード スニペットは、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 タグ セクションが含まれていないことが確実であり、コードが 2 倍短くなる可能性があります

于 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 デスクトップ アプリケーションには、任意の WAV ファイルを再生できるPlaySoundがあります。

MP3 の場合、私のチームは DirectSound とWindows Media Format SDKを使用するソリューションを発明しました。後者は、任意の WMA および MP3 ファイルをデコードできます。オーディオ ストリームを直接 DSound バッファに送りました。これは気弱な人向けではありません。

おそらく、より高レベルの代替手段であるWindows Media Player APIを使用できます。

DirectShowは非常に古い代替手段ですが、何かを簡単に起動して動作させることができます。 メディア ファンデーションは、DirectShow に代わるものです。

于 2012-10-14T08:40:52.330 に答える