游戏开发论坛

 找回密码
 立即注册
搜索
查看: 6844|回复: 10

Dshow里面播放mp3怎么设置循环播放?

[复制链接]

20

主题

94

帖子

103

积分

注册会员

Rank: 2

积分
103
发表于 2006-6-6 13:49:00 | 显示全部楼层 |阅读模式
Dshow里面播放mp3怎么设置循环播放? [em23]

132

主题

1341

帖子

1341

积分

金牌会员

Rank: 6Rank: 6

积分
1341
发表于 2006-6-6 18:51:00 | 显示全部楼层

Re:Dshow里面播放mp3怎么设置循环播放?

原理你是知道的吧(从另一帖看到的)
你把你的有关代码发上来看看,可能是MSG或者HWND设错了

20

主题

94

帖子

103

积分

注册会员

Rank: 2

积分
103
 楼主| 发表于 2006-6-6 19:51:00 | 显示全部楼层

Re:Dshow里面播放mp3怎么设置循环播放?

我也是在网上看的不全的东西
说是有一个WM_PRAGHNOTITY消息队列,当播放完了会发生EC_COMPLETE事件事件。还需要设置SetNotifyWindow(hWnd,WM_PGRAPHNOTIFY,0);

我在winpor里面采集WM_PRAGHNOTITY和EC_COMPLETE都说没有定义,不知道怎么设置?

0

主题

23

帖子

23

积分

注册会员

Rank: 2

积分
23
发表于 2006-6-7 01:51:00 | 显示全部楼层

Re:Dshow里面播放mp3怎么设置循环播放?

循环播放还有两个方法,最简单的方法是Release掉原来的IGraphBuilder接口,然后重构此接口再RenderFile就可以了,这样效率会低一些,但我实施过感觉不到任何效率问题(小于500ms),另一种方法是seek回去原来的起点位置播放;这两种方法都需要截取EC_COMPLETE事件,可以使用SetNotifyWindow的方法(需要窗体)或者直接用GetEvent截取,只要包含了ddshow.h头文件就有EC_COMPLETE事件的定义了

附上GetEvent的使用方法
long evCode, param1, param2;
HRESULT hr;
while (hr = pEvent->GetEvent(&evCode, &param1, &param2, 0), SUCCEEDED(hr))
{
    switch(evCode)
    {
        // Call application-defined functions for each
        // type of event that you want to handle.
    }
    hr = pEvent->FreeEventParams(evCode, param1, param2);
}


SetNotifyWindow的使用方法
#define WM_GRAPHNOTIFY WM_APP + 1   // Private message.
pEvent->SetNotifyWindow((OAHWND)g_hwnd, WM_GRAPHNOTIFY, 0);

LRESULT CALLBACK WindowProc( HWND hwnd, UINT msg, UINT wParam, LONG lParam)
{
    switch (msg)
    {
        case WM_GRAPHNOTIFY:
            HandleEvent();  // Application-defined function.
            break;
        // Handle other Windows messages here too.
    }
    return (DefWindowProc(hwnd, msg, wParam, lParam));
}

20

主题

94

帖子

103

积分

注册会员

Rank: 2

积分
103
 楼主| 发表于 2006-6-7 14:36:00 | 显示全部楼层

Re:Dshow里面播放mp3怎么设置循环播放?

Arcol回答的太详细了!!非常感谢~~一下子知道了两种方法!
SetNotifyWindow()方法是需要通过窗口消息来响应的,请问pEvent->SetNotifyWindow((OAHWND)hWnd, WM_GRAPHNOTIFY, 0);的位置在那里呢?我放在建立窗口以后的地方,运行报错了。
用GetEvent方式是不是可以摆脱窗口消息?这样我直接可以把这个方法放在我得Sound类里面封装起来呢?

42

主题

418

帖子

418

积分

中级会员

Rank: 3Rank: 3

积分
418
发表于 2006-6-7 16:15:00 | 显示全部楼层

Re:Dshow里面播放mp3怎么设置循环播放?

好贴,收藏之^_^

20

主题

398

帖子

398

积分

中级会员

Rank: 3Rank: 3

积分
398
发表于 2006-6-7 16:55:00 | 显示全部楼层

Re:Dshow里面播放mp3怎么设置循环播放?

非常感谢Arcol的回答,受教了~

11

主题

123

帖子

123

积分

注册会员

Rank: 2

积分
123
发表于 2006-6-8 16:30:00 | 显示全部楼层

Re:Dshow里面播放mp3怎么设置循环播放?

  这个问题我也碰到过,小弟的解决方法很丑陋,在制作我的DEMO过程中,我要赶时间,所以没研究,就是研究也不知道到哪弄资料.
  我的方法说出来真丑啊:
         预先得知音乐的长度,在游戏中检测游戏播放音乐的时间,时间到了,就释放原来的接口,再播放一次,就像上面讲的第一种方法,不过连结束事件也不用截取了,真是丑陋吧!
     反正就这样了.

0

主题

23

帖子

23

积分

注册会员

Rank: 2

积分
23
发表于 2006-6-9 05:46:00 | 显示全部楼层

Re:Dshow里面播放mp3怎么设置循环播放?

收到你发来的代码,格式很规范,说明也很详细,呵呵,可惜我没时间帮你改了

粗略看了下,使用方式都正确,出现异常是因为pEvent指针是空值,你应该先初始化pEvent后再调用;另外,如果要用SetNotifyWindow的方法,需要的是IMediaEventEx接口,这个接口获取通过查询取得,例如:
m_pGraph->QueryInterface(IID_IMediaEventEx, (void **)&m_pEventEx);

要注意,,IMediaEventEx接口是从IMediaEvent派生下来的,也就说IMediaEventEx已经包含了IMediaEvent的所有公开方法,不用同时获取两个对象

case WM_GRAPHNOTIFY的处理也有点问题,参考这个例子:
case WM_GRAPH_NOTIFY:
{
     long evCode, param1, param2;
     while (SUCCEEDED(m_pEventEx->GetEvent(&evCode, &param1, &param2, 0)))
     {
         m_pEventEx->FreeEventParams(evCode, param1, param2);
         switch (evCode)
         {
         case EC_COMPLETE:  // Fall through.
         case EC_USERABORT: // Fall through.
         case EC_ERRORABORT:
         ResetMusic();
         }
     }
     break;
}

如果只使用GetEvent的方式就不需要消息窗口了,但最好把它放到一个独立的线程里跑,因为它跟GetMessage API一样,需要循环调用


另外,CoUninitialize函数用法不对,这函数不要经常调,放在程序最后或者析构调一次就够了

暂时只发现这些,文档MSDN里有,DX8的SDK也有(新版的9.0没有),包括一些例子,可以下载,多尝试一下就OK了

20

主题

94

帖子

103

积分

注册会员

Rank: 2

积分
103
 楼主| 发表于 2006-6-9 11:09:00 | 显示全部楼层

Re:Dshow里面播放mp3怎么设置循环播放?

谢谢Arcol~!
你每一次的说明都很详细,每次都能学到很多东西。我现在用的SDK是2006年的那一版,所以没有DSHOW的例子,dx9.0b里面应该有吧,我正在从网站上下载。
很高兴Arcol喜欢我得程序书写方式,我会再接再厉的!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-24 16:51

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表