当前位置:首页 > 新闻动态 > 网站文章

518抽奖软件开发日志之:通过directshow+basslib 播放音乐源码

来源: 浏览:117 时间:2023-08-10

我在开发《518抽奖软件》的时候,需要播放音效,渲染氛围。开始用了一些dshow组件,只是播放少数几种音乐,到后来换到bass.lib 可以支持绝大多数音乐格式,而且用起来挺流畅稳定。具体代码和组件如下。

basslib部分,你可网上搜索“DC-Bass Source Mod 1.5.2.1”,下载后解压缩就包含了所有组件dll。然后把这些放在软件所在文件夹里即可。

dshow部分主要是一个类的源码,当然到商业软件的话,要有更详细的地方,例如wma的播放需要的组件。 下面只给出最基本的源码:

头文件h

class MuzGraph

{

public:

MuzGraph();

~MuzGraph();

HRESULT build(const WCHAR* file, HWND hwnd, LONG msg, LONG msgData, const WCHAR* dev);

private:

HRESULT build_bass(const WCHAR* file, HWND hwnd, LONG msg, LONG msgData, const WCHAR* dev);

HRESULT build_wma(const WCHAR* file, HWND hwnd, LONG msg, LONG msgData, const WCHAR* dev);

public:

HRESULT run();

void pause();

void stop();

int getLength();

int getPos();

void setPos(int pos);

bool isEnd();

void setTimeFormat();

void setVolume(int volume);

public:

WCHAR m_file[MAX_PATH];

IMediaEventEx* m_pME;

IGraphBuilder* m_pGB;

IMediaControl* m_pMC;

IMediaSeeking* m_pMS;

private:

BOOL m_bBuilded;

IBasicAudio* m_pBA;

//DCBassSourceMod.ax

IBaseFilter* m_source;

IBaseFilter* m_renderer;

//CLSID_WMAsfReader CLSID_CWMADecMediaObject

IBaseFilter* m_wmaSource;

IBaseFilter* m_wmaDec;

};

CPP文件

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;

}

地址 · ADDRESS

地址:建邺区新城科技园嘉陵江东街18号2层

邮箱:309474043@qq.Com

点击查看更多案例

联系 · CALL TEL

400-8793-956

售后专线:025-65016872

业务QQ:309474043    售后QQ:1850555641

©南京安优网络科技有限公司 版权所有   苏ICP备12071769号-4  网站地图