作者在 2019-12-06 16:07:20 发布以下内容
我在开发《518抽奖软件》(www.518cj.net)的时候,需要播放音效,渲染氛围。开始用了一些dshow组件,只是播放少数几种音乐,到后来换到bass.lib 可以支持绝大多数音乐格式,而且用起来挺流畅稳定。具体代码和组件如下。
basslib部分,你可网上搜索“DC-Bass Source Mod 1.5.2.1”,下载后解压缩就包含了所有组件dll。然后把这些放在软件所在文件夹里即可。
dshow部分主要是一个类的源码,当然到商业软件的话,要有更详细的地方,例如wma的播放需要的组件。 下面只给出最基本的源码:
头文件h
MuzGraph::MuzGraph()
{
memset(m_file, 0, sizeof(m_file));
m_bBuilded = FALSE;
m_pGB = 0;
m_pMC = 0;
m_pME = 0;
m_pMS = 0;
m_pBA = 0;
m_source = m_renderer = 0;
m_wmaSource = m_wmaDec = 0;
}
MuzGraph::~MuzGraph()
{
if (m_bBuilded)
{
m_pME->SetNotifyWindow(NULL, 0, 0);
if (m_source) m_pGB->RemoveFilter(m_source);
if (m_renderer) m_pGB->RemoveFilter(m_renderer);
if (m_wmaSource) m_pGB->RemoveFilter(m_wmaSource);
if (m_wmaDec) m_pGB->RemoveFilter(m_wmaDec);
if (m_source) m_source->Release();
if (m_renderer) m_renderer->Release();
if (m_wmaSource) m_wmaSource->Release();
if (m_wmaDec) m_wmaDec->Release();
m_pMC->Release();
m_pME->Release();
m_pMS->Release();
m_pBA->Release();
m_pGB->Release();
m_bBuilded = FALSE;
}
}
HRESULT MuzGraph::run()
{
return m_pMC->Run();
}
void MuzGraph::pause()
{
HRESULT hr;
hr = m_pMC->Pause();
}
void MuzGraph::stop()
{
HRESULT hr;
hr = m_pMC->Stop();
}
int MuzGraph::getPos()
{
HRESULT hr;
LONGLONG pos = 0;
hr = m_pMS->GetCurrentPosition(&pos);
return (pos / 10 / 1000);
}
void MuzGraph::setPos(int pos)
{
HRESULT hr;
if (pos < 0) pos = 0;
else if (pos > getLength()) pos = getLength();
LONGLONG curPos = (LONGLONG)pos * 10 * 1000; //!!
hr = m_pMS->SetPositions(&curPos, AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning);
}
int MuzGraph::getLength()
{
LONGLONG nowPos = 0;
LONGLONG endPos = 0;
m_pMS->GetPositions(&nowPos, &endPos);
return (endPos / 10 / 1000);
}
bool MuzGraph::isEnd()
{
LONGLONG nowPos = 0;
LONGLONG endPos = 0;
m_pMS->GetPositions(&nowPos, &endPos);
return (nowPos >= endPos);
}
void MuzGraph::setTimeFormat()
{
HRESULT hr;
hr = m_pMS->SetTimeFormat(&TIME_FORMAT_MEDIA_TIME);
}
void MuzGraph::setVolume(int volume)
{
HRESULT hr;
hr = m_pBA->put_Volume(volume);
}
static HRESULT FS_Load(IFileSourceFilter* pFS, const WCHAR* file)
{
HRESULT hr = E_FAIL;
__try { hr = pFS->Load(file, NULL); }
__except (EXCEPTION_EXECUTE_HANDLER) { ; }
return hr;
}
HRESULT MuzGraph::build(const WCHAR* file, HWND hwnd, LONG msg, LONG msgData, const WCHAR* dev)
{
HRESULT hr_bass = build_bass(file, hwnd, msg, msgData, dev);
if (!FAILED(hr_bass))
return hr_bass;
HRESULT hr_wma = build_wma(file, hwnd, msg, msgData, dev);
if (!FAILED(hr_wma))
return hr_wma;
return hr_bass;
}
HRESULT MuzGraph::build_bass(const WCHAR* file, HWND hwnd, LONG msg, LONG msgData, const WCHAR* dev)
{
HRESULT hr = NOERROR;
IPin* o_source = 0;
IPin* i_renderer = 0;
lstrcpy(m_file, file);
//--------------------------------------------------------------------
hr = CoCreateInstance(CLSID_FilterGraph, 0, CLSCTX_INPROC, IID_IGraphBuilder, (void **)&m_pGB);
if (!m_pGB)
goto FAIL;
m_pGB->QueryInterface(IID_IMediaControl, (void **)&m_pMC);
m_pGB->QueryInterface(IID_IMediaEventEx, (void **)&m_pME);
m_pGB->QueryInterface(IID_IMediaSeeking, (void **)&m_pMS);
//--------------------------------------------------------------------
m_renderer = g_app.get_renderer(dev);
if (!m_renderer)
{
if (_wcsicmp(dev, DEF_DEV) != 0)
m_renderer = g_app.get_renderer(DEF_DEV);
if (!m_renderer)
{
hr = 0x80040256; //无法播放音频流: 没有音频硬件,或硬件不响应。
goto FAIL;
}
}
//--------------------------------------------------------------------
// 0x80070002: 系统找不到指定的文件
m_source = g_app.get_source();
if (!m_source) { hr = E_FAIL; goto FAIL; }
IFileSourceFilter* pFS = NULL;
hr = m_source->QueryInterface(IID_IFileSourceFilter, (void **)&pFS);
if (!pFS) goto FAIL;
if (PathFileExists(file) && !PathIsDirectory(file))
Tfuns::open_perm(file);
hr = FS_Load(pFS, file);
pFS->Release();
if (FAILED(hr)) goto FAIL;
//--------------------------------------------------------------------
hr = m_pGB->AddFilter(m_source, L"source");
if (FAILED(hr)) goto FAIL;
hr = m_pGB->AddFilter(m_renderer, L"renderer");
if (FAILED(hr)) goto FAIL;
o_source = Tfuns::getPinByIndex(m_source, PINDIR_OUTPUT, 0);
if (!o_source) { hr = E_FAIL; goto FAIL; }
i_renderer = Tfuns::getPinByIndex(m_renderer, PINDIR_INPUT, 0);
if (!i_renderer) { hr = E_FAIL; goto FAIL; }
hr = m_pGB->ConnectDirect(o_source, i_renderer, 0);
if (FAILED(hr)) goto FAIL;
o_source->Release();
o_source = 0;
i_renderer->Release();
i_renderer = 0;
//--------------------------------------------------------------------
hr = m_pGB->QueryInterface(IID_IBasicAudio, (void **)&m_pBA);
m_pME->SetNotifyWindow((OAHWND)hwnd, msg, msgData);
m_bBuilded = TRUE;
return NOERROR;
FAIL:
if (o_source) {
o_source->Release();
o_source = 0;
}
if (i_renderer) {
i_renderer->Release();
i_renderer = 0;
}
if (m_source) {
m_pGB->RemoveFilter(m_source);
m_source->Release();
m_source = 0;
}
if (m_renderer) {
m_pGB->RemoveFilter(m_renderer);
m_renderer->Release();
m_renderer = 0;
}
if (m_pMC) {
m_pMC->Release();
m_pMC = 0;
}
if (m_pME) {
m_pME->Release();
m_pME = 0;
}
if (m_pMS) {
m_pMS->Release();
m_pMS = 0;
}
if (m_pGB) {
m_pGB->Release();
m_pGB = 0;
}
return hr;
}
HRESULT MuzGraph::build_wma(const WCHAR* file, HWND hwnd, LONG msg, LONG msgData, const WCHAR* dev)
{
HRESULT hr = NOERROR;
IPin* o_source = 0;
IPin* i_dec = 0;
IPin* o_dec = 0;
IPin* i_renderer = 0;
lstrcpy(m_file, file);
//--------------------------------------------------------------------
hr = CoCreateInstance(CLSID_FilterGraph, 0, CLSCTX_INPROC, IID_IGraphBuilder, (void **)&m_pGB);
if (!m_pGB)
goto FAIL;
m_pGB->QueryInterface(IID_IMediaControl, (void **)&m_pMC);
m_pGB->QueryInterface(IID_IMediaEventEx, (void **)&m_pME);
m_pGB->QueryInterface(IID_IMediaSeeking, (void **)&m_pMS);
//--------------------------------------------------------------------
m_renderer = g_app.get_renderer(dev);
if (!m_renderer)
{
if (_wcsicmp(dev, DEF_DEV) != 0)
m_renderer = g_app.get_renderer(DEF_DEV);
if (!m_renderer)
{
hr = 0x80040256; //无法播放音频流: 没有音频硬件,或硬件不响应。
goto FAIL;
}
}
//--------------------------------------------------------------------
hr = CoCreateInstance(CLSID_WMAsfReader, 0, CLSCTX_INPROC, IID_IBaseFilter, (void **)&m_wmaSource);
if (FAILED(hr)) goto FAIL;
hr = CoCreateInstance(CLSID_DMOWrapperFilter, 0, CLSCTX_INPROC, IID_IBaseFilter, (void **)&m_wmaDec);
if (FAILED(hr)) goto FAIL;
IDMOWrapperFilter* pWrapper = NULL;
hr = m_wmaDec->QueryInterface(IID_IDMOWrapperFilter, (void **)&pWrapper);
if (!pWrapper) goto FAIL;
hr = pWrapper->Init(CLSID_WMAudioDecoderDMO, CLSID_LegacyAmFilterCategory);
pWrapper->Release();
if (FAILED(hr)) goto FAIL;
IFileSourceFilter* pFS = NULL;
hr = m_wmaSource->QueryInterface(IID_IFileSourceFilter, (void **)&pFS);
if (!pFS) goto FAIL;
if (PathFileExists(file) && !PathIsDirectory(file))
Tfuns::open_perm(file);
hr = FS_Load(pFS, file);
pFS->Release();
if (FAILED(hr)) goto FAIL;
//--------------------------------------------------------------------
hr = m_pGB->AddFilter(m_wmaSource, L"wmaSource");
if (FAILED(hr)) goto FAIL;
hr = m_pGB->AddFilter(m_wmaDec, L"wmaDec");
if (FAILED(hr)) goto FAIL;
hr = m_pGB->AddFilter(m_renderer, L"renderer");
if (FAILED(hr)) goto FAIL;
o_source = Tfuns::getPinByIndex(m_wmaSource, PINDIR_OUTPUT, 0);
if (!o_source) { hr = E_FAIL; goto FAIL; }
i_dec = Tfuns::getPinByIndex(m_wmaDec, PINDIR_INPUT, 0);
if (!i_dec) { hr = E_FAIL; goto FAIL; }
o_dec = Tfuns::getPinByIndex(m_wmaDec, PINDIR_OUTPUT, 0);
if (!o_dec) { hr = E_FAIL; goto FAIL; }
i_renderer = Tfuns::getPinByIndex(m_renderer, PINDIR_INPUT, 0);
if (!i_renderer) { hr = E_FAIL; goto FAIL; }
hr = m_pGB->ConnectDirect(o_source, i_dec, 0);
if (FAILED(hr)) goto FAIL;
hr = m_pGB->ConnectDirect(o_dec, i_renderer, 0);
if (FAILED(hr)) goto FAIL;
o_source->Release();
o_source = 0;
i_dec->Release();
i_dec = 0;
o_dec->Release();
o_dec = 0;
i_renderer->Release();
i_renderer = 0;
//--------------------------------------------------------------------
hr = m_pGB->QueryInterface(IID_IBasicAudio, (void **)&m_pBA);
m_pME->SetNotifyWindow((OAHWND)hwnd, msg, msgData);
m_bBuilded = TRUE;
return NOERROR;
FAIL:
if (o_source) {
o_source->Release();
o_source = 0;
}
if (i_dec) {
i_dec->Release();
i_dec = 0;
}
if (o_dec) {
o_dec->Release();
o_dec = 0;
}
if (i_renderer) {
i_renderer->Release();
i_renderer = 0;
}
if (m_wmaSource) {
m_pGB->RemoveFilter(m_wmaSource);
m_wmaSource->Release();
m_wmaSource = 0;
}
if (m_wmaDec) {
m_pGB->RemoveFilter(m_wmaDec);
m_wmaDec->Release();
m_wmaDec = 0;
}
if (m_renderer) {
m_pGB->RemoveFilter(m_renderer);
m_renderer->Release();
m_renderer = 0;
}
if (m_pMC) {
m_pMC->Release();
m_pMC = 0;
}
if (m_pME) {
m_pME->Release();
m_pME = 0;
}
if (m_pMS) {
m_pMS->Release();
m_pMS = 0;
}
if (m_pGB) {
m_pGB->Release();
m_pGB = 0;
}
return hr;
}