[python] WinAMP besturen

Pagina: 1
Acties:
  • 139 views sinds 30-01-2008
  • Reageer

  • The Collector
  • Registratie: Januari 2000
  • Laatst online: 23-03 12:59
Ik ben momenteel bezig om in python een HTPC-front-end te bouwen voor mplayer en winamp, het werkt bijna allemaal precies zoals ik wil en python is een ontzettend makkelijke taal om snel ergens te komen.

Het probleem zit hem bij WinAMP. Zover mij bekend zijn er drie manieren om codes aan WinAMP doortesturen voor de besturing. WM_COMMAND, WM_USER, WM_COPYDATA.

WM_USER werkt zonder problemen:
Python:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import win32gui
import win32api
import win32con

WM_USER     = 0x400

def usercommand(id, data=0):
    return win32api.SendMessage(hWinamp, WM_USER, data, id)
            
def getNumTracks():
    "returns number of tracks in current playlist"
    return usercommand(124)

hWinamp = win32gui.FindWindow('Winamp v1.x', None)
print "Aantal nummers in playlist", getNumTracks()


Het probleem zit hem bij de WM_COPYDATA, stukkie code dat niet werkt (komt grootendeels van internet):
Python:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import win32gui
import win32api
import win32con
import struct
import array

WM_COPYDATA = 0x004A

def usercommand(id, data=0):
    return win32api.SendMessage(hWinamp, WM_USER, data, id)
            
def pack(id, data):
    global cds
    copyDataStruct="IIP"

    # Add zero to the data-string
    data = data + '\00'
    
    # Search the adress and the length of the string
    r_data = array.array('c', data)
    i_data = r_data.buffer_info()

    # create the cds-structure
    s_cds = struct.pack(copyDataStruct, id, i_data[1], i_data[0] )

    # search the adress of the cds-structure
    cds = array.array('c', s_cds)
    i_cds = cds.buffer_info()
    return i_cds[0]
    
hWinamp = win32gui.FindWindow('Winamp v1.x', None)

iFile = "C:\Muziek\MP3 (Nog Uitzoeken)\Losse Nummers\Party Animals - Atomic.mp3"
win32api.SendMessage(hWinamp, win32con.WM_COPYDATA, 0, pack(100, iFile))

WinAMP voegt nu iets aan de playlist toe, maar 't klopt voor geen meter, ik zie niks van de originele filenaam terug!

Ik heb wat andere informatie van internet erin verwerkt om het werkende te krijgen, maar 't lukt me nog niet:
Python:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import win32gui
import win32api
import win32con
import struct
import array

WM_COPYDATA = 0x004A

def usercommand(id, data=0):
    return win32api.SendMessage(hWinamp, WM_USER, data, id)
            
def pack(id, data):
    global cds
    copyDataStruct="II"+str(len(data)+1)+"s"

    # create the cds-structure
    s_cds = struct.pack(copyDataStruct, id, len(data)+1, data )

    # search the adress of the cds-structure
    cds = array.array('c', s_cds)
    i_cds = cds.buffer_info()
    return i_cds[0]
    
hWinamp = win32gui.FindWindow('Winamp v1.x', None)

iFile = "C:\Muziek\MP3 (Nog Uitzoeken)\Losse Nummers\Party Animals - Atomic.mp3"
win32api.SendMessage(hWinamp, win32con.WM_COPYDATA, 0, pack(100, iFile))

In dit voorbeeld gebeurt er helemaal niets, ook geen foutmelding en in WinAMP veranderd er net zo min iets.

Hieronder een stuk uit de WinAMP SDK...
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#define IPC_PLAYFILE 100  // dont be fooled, this is really the same as enqueufile
#define IPC_ENQUEUEFILE 100 
/* sent as a WM_COPYDATA, with IPC_PLAYFILE as the dwData, and the string to play
** as the lpData. Just enqueues, does not clear the playlist or change the playback
** state.
*/


#define IPC_DELETE 101
#define IPC_DELETE_INT 1101 // don't use this, it's used internally by winamp when 
                            // dealing with some lame explorer issues.
/* SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_DELETE);
** Use IPC_DELETE to clear Winamp's internal playlist.
*/


#define IPC_STARTPLAY 102   // starts playback. almost like hitting play in Winamp.
#define IPC_STARTPLAY_INT 1102 // used internally, don't bother using it (won't be any fun)


Het probleem zit hem volgens mij in de samengepakte data van de struct.pack, allen heb ik geen flauw idee meer hoe ik dit nog anders moet doen aangezien ik al diverse gegevens typen heb gebruikt:

copyDataStruct als "IIP", "IIs","iip", zoals ook in dit tabeletje van deze python pagina.


Dus, de vraag, hoe krijg ik het werkende op WM_COPYDATA te grbruiken / om dingen aan de winamp playlist toe te voegen vanuit python... bedankt.

  • PommeFritz
  • Registratie: Augustus 2001
  • Laatst online: 24-11-2025

PommeFritz

...geen friet

Geen idee hoor, verder niet geprobeerd, maar probeer wat je hebt:
code:
1
iFile = "C:\Muziek\MP3 (Nog Uitzoeken)\Losse Nummers\Party Animals - Atomic.mp3"


eens juist te escapen (de backslashes dus!):

code:
1
iFile = "C:\\Muziek\\MP3 (Nog Uitzoeken)\\Losse Nummers\\Party Animals - Atomic.mp3"

of natuurlijk makkelijker met een raw string
code:
1
iFile = r"C:\Muziek\MP3 (Nog Uitzoeken)\Losse Nummers\Party Animals - Atomic.mp3"

FireFox - neem het web in eigen hand


  • The Collector
  • Registratie: Januari 2000
  • Laatst online: 23-03 12:59
goed idee, had ik nog niet aan gedacht (soms ben je zo verdiept in iets dat je hier niet meer aan denkt...) helaas zit er geen verschil in de werking van beide stukken code. maar ik laat hem er zoizo wel instaan ;)

  • The Collector
  • Registratie: Januari 2000
  • Laatst online: 23-03 12:59
Heb m'n code momenteel wat opgeschoond, alleen is het resultaat nog steeds nul, geen fouten, maar verder ook helemaal niks :? Lijkt er dus op alsof het goed verstuurd wordt, maar de inhoud dus niet goed is en WinAMP het verder maar negeert...

Python:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
from win32gui import FindWindow 
from win32api import SendMessage 
import struct
import array 

WM_USER         = 0x400                                     # WM-ID for a WinAMP user command
WM_COPYDATA     = 0x004A                                    # WM-ID for a WinAMP copyData command
IPC_PLAYFILE    = 100                                       # WM-ID for WinAMP to add item to WinAMP playlist

hWnd = FindWindow('Winamp v1.x', None)                      # Find the WinAMP window-handle (receiver)

def packData( dwData, lpData ):
    lpData_ad = array.array('c', lpData).buffer_info()[0]   # calculate the pointer address for the lpData
    cbData = array.array('c', lpData).buffer_info()[1]      # calculate the length of the lpData (=cbData)
    cds = struct.pack("IIP", dwData, cbData, lpData_ad)     # pack dwData, cbData and lpData into a copyDataStruct
    cds_ad = array.array('c', cds).buffer_info()[0]         # find the pointer address of the copyDataStruct
    return cds_ad                                           # return the copyDataStruct pointer-address
    
def addItemToPlaylist( item ):
    uInt    = IPC_PLAYFILE                                  # ID for adding an item to the WinAMP playlist
    wParam  = 0                                             # Not defined (leave at zero)
    lParam  = packData( uInt, item )                        # create the copyDataStruct-pointer
    SendMessage( hWnd, uInt, wParam, lParam )               # Send the data to the WinAMP window
    
file = r"C:\Party Animals - Atomic.mp3"
addItemToPlaylist( file )

  • The Collector
  • Registratie: Januari 2000
  • Laatst online: 23-03 12:59
En de oplossing is:

Python:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from win32gui import FindWindow 
from win32api import SendMessage 
import struct
import array 

hWnd = FindWindow('Winamp v1.x', None)

def packData( dwData, item ):
    global cds, lpData
    lpData = array.array('c', item)
    lpData_ad = lpData.buffer_info()[0]
    cbData = lpData.buffer_info()[1]
    cds = array.array('c', struct.pack("IIP", dwData, cbData, lpData_ad) )
    cds_ad = cds.buffer_info()[0]
    return cds_ad  
    
def addItemToPlaylist( item ):
    SendMessage( hWnd, 0x004A, 0, packData( 100, item ) )
    
file = r"C:\Party Animals - Atomic.mp3"
addItemToPlaylist( file )


Het probleem zat hem erin dat je pointers naar data moet geven, op het moment dat packData() klaar is, worden de variabelen verwijderd en wijzen de pointers in 't niets... de variabelen opgeven in een global bracht de uitkomst :)

  • PommeFritz
  • Registratie: Augustus 2001
  • Laatst online: 24-11-2025

PommeFritz

...geen friet

Fijn dat het nu werkt!

FireFox - neem het web in eigen hand

Pagina: 1