需要一种方法从Zune和Windows Media Player使用Python检索当前播放的歌曲

时间:2013-10-18 14:20:19

标签: python windows winapi wmp zune

我的应用程序从众多音乐播放器中检索当前播放的歌曲。但是,我在实现Zune和Windows Media Player方面遇到了很大麻烦。

我已经在这个主题上做了大量的谷歌搜索,不幸的是,这只会让我越来越困惑。

我通常会为其他应用程序做些什么:

  1. 每4秒对所有打开的窗口进行迭代
  2. 获取所有窗口的标题
  3. 检查模式的标题(即" - Spotify "
  4. 如果有,请调整输出标题。
  5. WMP标题中没有当前播放的歌曲。

    Zune确实如此,但它在标题,专辑和艺术家之间每隔几秒钟就会旋转一次。尽管可能,但使用我当前的方法进行跟踪是非常不可靠的。

    Windows Media Player

    我也试过在Windows媒体播放器上使用COM组件。

    import win32com.client
    wmp = win32com.client.gencache.EnsureDispatch('WMPlayer.OCX')
    
    # some function I don't have here, it retrieves the current playing song
    # and other data
    

    最大的问题是它需要你以编程方式启动WMP,这将是非常用户不友好的

    那么,我发现了什么? This SO post重定向到WMP.dll。但据我所知,它与COM有同样的问题,你必须以编程方式启动它。如果没有,我真的想要了解如何在python中使用该DLL的一些指示。

    还有另外一个不太讨厌的解决方案,即为WMP编写插件,让我的用户下载该插件并从该插件中检索数据。我宁愿不去那里,因为我没有任何C语言的经验,也不想深入研究插件文档。

    的Zune

    一种方法是循环通过三个标题状态,确定它当前处于哪个状态并找到其他两个状态。

    IE: 前5秒标题是:Super_song 接下来的5秒标题是:By Power_artist 接下来的5秒标题是:Good_album(日期)

    所以我可以通过制作日期的正则表达式来确定相册标题的时间(总是存在),然后等待几秒钟找到标题和艺术家。

    这显然不是一个很好的解决方案,因为它需要一段时间而且也不太可靠,(如果歌曲名称包含日期,那该怎么办)

    接下来的问题是它也不一致,有时候标题只会持续Zune几分钟。不知道为什么。

    所以,继续下一个方法。

    有一个名为ZuneNowPlaying的应用程序。这种“不知何故”从Zune获取当前播放的歌曲并将其放入注册表中,这件事与我的草率标题方法无关,因为它会在歌曲改变的瞬间更改注册表。立即

    这是我在我的程序的工作版本中使用的解决方案,但许多用户报告说它根本不起作用,没有任何反应。我检查了程序,它不能一直可靠地更改注册表。我不知道为什么,我不知道如何解决它。因此,这个解决方案也被包括 - 。

      

    它是否使用名称“MsnMsgrUIManager”#000000“>   导致zune软件向其发送有关哪首歌的信息   打?有没有办法在没有这种情况下获得这些信息   劈?

    在Zune Now Playing应用程序的讨论中可以找到。遗憾的是,源代码不可用,至少我找不到它。有人对此有更多了解吗?

    我听说过的第三种方法是dll。它被称为ZuneShell.dll。我不记得我在哪里读到它,也不能通过谷歌找到它,因为所有结果都是“ZuneShell.dll是病毒吗?”。

    再一次,我遇到了一个问题,我不知道如何使用它甚至 IF 我有文档,哎呀,如果它甚至是我一直在寻找的。< / p>

    可能会查看的替代方向

    在浏览这个主题时,我看到人们谈论直接从GUI中检索数据。我不确定我的记忆是多么合法,可能甚至是多么正确,但如果有可能有人可以将我重新引导到更多内容上呢?

    还有别的,真的。

2 个答案:

答案 0 :(得分:3)

我在C ++中使用代码来打印当前在WMP中播放的媒体的名称。这是一个简单的控制台应用程序(78行代码)。

步骤:

1)实现了一个实现IUnknown,IOleClientSite,IServiceProvider和IWMPRemoteMediaServices的基本COM对象。使用ATL模板CComObjectRootEx,这很简单(有点,您的里程可能会有所不同)。需要(简单)代码的唯一方法是IServiceProvider :: QueryService和IWMPRemoteMediaServices :: GetServiceType。所有其他方法可能返回E_NOTIMPL

2)实例化“WMPlayer.OCX”COM对象(在我的情况下,通过CoCreateInstance)

3)通过QueryInterface从对象中检索IOleObject接口指针

4)从1)中看到的类中实现对象(我使用CComObject&lt;&gt; :: CreateInstance模板)

5)使用3)中接口的SetClientSite方法,将指针传递给OleClientSite实现。

6)在SetClientSite调用期间,WMP将回调您:fisrt请求IServiceProvider接口指针,第二次调用QueryService方法,请求IWMPRemoteMediaServices接口指针。返回IWMPRemoteMediaServices的实现,第三,将通过GetServiceType再次调用。然后,您必须返回“远程”。您现在已连接到WMP运行实例

7)查询COM对象以获取IWMPMedia接口指针

8)如果7)没有给出NULL,请阅读IWMPMedia :: name属性。

9)完成

以上所有内容均使用VS2010 / Windows Seven进行了测试,并且运行了WMP(如果没有运行Media Player进程,则无需执行任何操作)。

我不知道yoy是否可以/想要在Python中实现COM接口和对象。如果您对我的C ++代码感兴趣,请告诉我。您可以在C ++ DLL中使用该代码,然后从python中调用它。

答案 1 :(得分:1)

我刚刚发现了一个很酷的Python工具,它可以查询任何程序的所有控件。 简单,直接,易于阅读。它在这里:

http://www.brunningonline.net/simon/blog/archives/winGuiAuto.py.html

通过它,您可以从GUI获取信息。

您还可以抓取加载的文件列表。它适用于大多数媒体播放器。 您可以通过以下方式以编程方式获取此信息:

http://www.codeproject.com/Articles/18975/Listing-Used-Files

这是C ++,但此时您可以包装本机代码。 这样您就必须自己提取ID3标签。可能值得一试,因为这将是一个通用的解决方案。

相关问题