2013-10-18 73 views
9

我的應用程序從多個音樂播放器中檢索當前播放歌曲。但是,我在實現Zune和Windows Media Player時遇到了很大的麻煩。需要使用Python從Zune和Windows Media Player檢索當前播放歌曲的方法

我在這個主題上做了大量的搜索,不幸的是它只是讓我越來越困惑。

我通常會爲我的其他應用程序一樣:

  1. 遍歷所有打開的窗口每4秒
  2. 獲得所有窗口
  3. 檢查標題的標題的模式(即," - Spotify "
  4. 如果存在,請調整輸出的標題。

WMP標題中沒有當前正在播放的歌曲。 Zune確實如此,但它在標題,專輯和藝術家之間每隔幾秒鐘就會旋轉一圈。儘管可能,但用我目前的方法進行追蹤是非常不可靠的。

的Windows Media Player

我一直在使用Windows Media Player的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秒的標題是:通過Power_artist 接下來的5秒的標題是:Good_album(日期)

所以,我可以決定什麼時候該專輯的標題是通過爲日期製作一個正則表達式(總是存在),然後等待幾秒鐘找到標題和藝術家。

這顯然不是一個很好的解決方案,因爲它會需要一段時間,它不是很可靠或者,(如果什麼歌曲名稱包含例如日期)

接下來的問題是,它並不一致無論如何,有時候這個標題只會讓Zune停留數分鐘。不知道爲什麼。

因此,繼續下一個方法。

這個應用程序叫做ZuneNowPlaying。這種「不知何故」從Zune獲取當前播放的歌曲,並將其放入註冊表中,這種情況不適用於我的馬虎標題方法,因爲它在歌曲改變的瞬間就會改變註冊表。立即。

這是我在我的程序的工作版本中使用的解決方案,但許多用戶報告說,它根本無法工作,什麼也沒有發生。我檢查了該程序,並且它始終無法可靠地更改註冊表。我不知道爲什麼,我不知道如何解決它。因此,這個解決方案也被放棄了。

是,它是使用名爲「MsnMsgrUIManager」#000000" > 導致Zune軟件來發送哪些歌曲是 播放信息的事實呢?有沒有辦法讓沒有這種信息 破解?

即在Zune正在播放應用程序的討論中發現,來源是不可用遺憾的是,至少我不能找到它。任何人有更多關於這個?

三方法我曾經聽說過再次是dl湖它被稱爲ZuneShell.dll。我不記得我在哪裏讀到它,也不能通過谷歌找到它,因爲所有結果都是「是ZuneShell.dll病毒?」。

再一次,我遇到了問題,我不知道如何處理這個問題,即使我有文檔,如果它甚至是我一直在尋找的。

備選方向,也許考慮

在瀏覽關於這個問題,我看到人們在談論直接從GUI的檢索數據。我不確定我的記憶是多麼的合理,可能甚至正確,但是如果有可能有人可以讓我更多地瞭解這一點?

其他的,真的。

+0

您是否考慮嘗試從zune進程的內存中讀取數據?似乎有一個(過時的)庫在python中執行,名爲[pymem](https://github.com/srounet/Pymem) – goncalopp

+0

@goncalopp我沒有,我會研究它。 – Azeirah

+0

似乎有可能使用dll訪問正在運行的WMP實例,但這並不容易,我認爲,請參見[這裏](http://www.darinhiggins.com/gaining-access-to-a-running-實例的窗口媒體播放器功能於VB網/)。也許你可以從[Pudgin的「CurrentTrack」插件的源代碼獲得一些其他靈感(http://sourceforge.net/p/currenttrack/code/HEAD/tree/trunk/currenttrack/src/wmp.cpp)。公平的警告:它是用C++編寫的,並且有作者的評論:「這個解決方案很糟糕...但是直到我可以弄清楚如何使用COM API ...」 – 2013-10-22 21:28:05

回答

1

我剛剛發現一個很酷的Python工具,它可以查詢任何程序的所有控件。 簡單,直接,易於閱讀。它在這裏:

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

這樣,您可以從GUI的信息。

您也可以抓取已加載的文件列表。它適用於大多數媒體播放器。 您可以通過編程獲取這些信息是這樣的:

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

這是C++,但在這一點上你可以用本機代碼。 這樣你必須自己提取ID3標籤。值得一試,因爲這將是一個通用的解決方案。

+0

檢索所有文件實際上聽起來像一個體面的備份計劃。但是,WMP有很多時間打開兩個文件,所以很難處理。我想我會更多地考慮這一點,如果一切都失敗了。 – Azeirah

+0

它不查詢所有文件,只查詢正在播放的文件。每首歌曲都會顯示在WMP的播放列表中,但只有當前播放的歌曲纔會連續打開。我的第二個建議的解決方案只查找那個打開的文件句柄。順便說一句,你怎麼看pywinauto? – Kobor42

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看到的類的對象)(I使用CComObject <> ::的CreateInstance模板)

5)使用3)中獲取的接口中的SetClientSite方法,將指針傳遞給OleClientSite實現。

6)在SetClientSite調用WMP將回調你:最前一頁要求的IServiceProvider的接口指針,第二調用QueryService的方法,要求的IWMPRemoteMediaServices接口指針。返回您的IWMPRemoteMediaServices實現,第三,您將通過GetServiceType再次調用。您必須然後返回「遠程」。現在您已連接到WMP運行實例

7)查詢一個IWMPMedia接口指針COM對象

8)如果7)未給NULL,閱讀的IWMPMedia ::名屬性。

9) DONE

上述所有與VS2010/Windows 7的測試,並與WMP運行(如果沒有媒體播放器進程在運行,就什麼都不做)。

我不知道如果同意可以/想要在Python中實現COM接口和對象。如果您對我的C++代碼感興趣,請告訴我。您可以在C++ DLL中使用該代碼,然後從python調用它。

+0

這個解釋對我來說太不明確了,我完全不知道第一步該做什麼。關於如何將腳本語言(特別是Python)用於COM,文檔還很少。 編輯:如果你不能幫助我與Python,我會打開一個新的問題,重定向到Python的win32api用戶的問題。 – Azeirah

+0

@Azeirah我無法幫助Python。你剩下2個選擇:1)在C++中構建一個DLL(或一個EXE),它將是一個COM服務器,可以從Python調用。或者2)直接在Python中實現整個事物,* IF *可以在Python中實現一個不會從IDispatch繼承的接口。 – manuell

+0

我知道這已經有一段時間了,但我仍然有這個問題。我現在知道更多關於C++,python和一切。如果你仍然有你在這個答案中提到的C++代碼,你可以把它發送給我的電子郵件嗎? [email protected] – Azeirah

相關問題