Windows Media Player COM自动化在VBS中正常但在Python中不行

3 投票
1 回答
1467 浏览
提问于 2025-04-18 16:12

我尝试通过COM接口用Windows Media Player播放音频文件。以下代码在VBS中运行得很好:

Set wmp = CreateObject("WMPlayer.OCX")
wmp.settings.autoStart = True
wmp.settings.volume = 50
wmp.URL = "C:\Windows\Media\tada.wav"
while wmp.Playstate <> 1
WSH.Sleep 100
wend

可惜的是,完全相同的代码在Python中却没有声音:

import win32com.client
import time

wmp = win32com.client.dynamic.Dispatch("WMPlayer.OCX")
wmp.settings.autoStart = True
wmp.settings.volume = 50
wmp.URL = r"C:\Windows\Media\tada.wav"
while wmp.Playstate != 1:
    time.sleep(0.1)

虽然COM的交互似乎是正常的,因为我可以创建新的媒体对象并查询它们的信息。但就是听不到任何声音。

>>> media = wmp.newMedia(r"C:\Windows\Media\tada.wav")
>>> media.durationString
'00:01'
>>> wmp.currentMedia = media
>>> wmp.play()                 # No sound audible.
>>> wmp.PlayState
9                              # wmppsTransitioning

PlayState总是显示为wmppsTransitioning,无论我怎么操作。

这个问题出现在Python2.7、3.2和3.3上,使用的是最后两个版本的PyWin32(218和219)。操作系统是Windows 7 x64,所有的Python解释器都是32位的。我可以成功加载WMPlayer.OCX,而且COM也能正常工作,所以我觉得这不是32位和64位DLL的问题。

有没有人知道为什么在VBS中可以工作,而在Python中却不行?我该如何进一步调试这个问题呢?

1 个回答

4

看起来问题出在 time.sleep 这个函数上,它不会处理窗口消息。你可以换用其他的超时函数,这些函数可以处理窗口消息。

原因是 Windows 媒体播放器是一个单线程单元(STA)组件,可能是因为它通常作为图形组件使用。它内部的一些功能依赖于定期处理消息,可能是一个高精度的多媒体定时器线程,它会发送窗口消息来进行通信,或者它可能依赖于实际的 WM_TIMER 消息。

撰写回答