Как получить название текущего трека из Winamp и AIMP
Winamp был и остается самым популярным мультимедийным плеером для Windows. Такая популярность не могла остаться незамеченной, поэтому появились программы, использующие информацию из него в своих целях. Например, плагины для интернет-мессенджеров устанавливают название воспроизводимого трека в качестве статуса, а моя программа My Music Web Agent отправляет эту информацию в интернет. Для взаимодействия сторонних приложений с Winamp был разработан интерфейс API со своими командами и синтаксисом. По какой-то причине разработчики Winamp сейчас вообще убрали с сайта информацию об API, но в интернете эти данные остались. Я приложил описание Winamp Application Programming Interface в архиве с примером программы, рекомендую ознакомиться с ним перед прочтением статьи, чтобы не возникало вопросов откуда взялись те или иные значения.
; Сегмент данных
section '.data' data readable writeable
; Название класса окна Winamp/AIMP
wcl db 'Winamp v1.x',0
buff rb 300h ; Буфер для получения текста из заголовка окна
play_now rb 300h ; Буфер для получения названия трека
Плеер Winamp, как и другие приложения для Windows, принимает и обрабатывает сообщения, отправляемые ему через SendMessage. Но для этого сперва надо определить хэндл его окна. Сделать это очень просто, окно Winamp всегда имеет название класса "Winamp v1.x", поэтому воспользуемся функцией
FindWindow. Дальше надо узнать состояние плеера. Для этого надо послать окну Winamp сообщение WM_USER с wParam = 0 и lParam = 104. Как написано в документации про это сообщение: "Returns the status of playback. If 'ret' is 1, Winamp is playing. If 'ret' is 3, Winamp is paused. Otherwise, playback is stopped." То есть, если вернулось значение не равное 1, то Winamp ничего не воспроизводит или находится в режиме паузы.
; Сегмент кода
section '.code' code readable executable
...
; Получить хэндл окна Winamp
invoke FindWindow,wcl,0
or eax,eax
; Окно Winamp не найдено
jz .no_winamp
; Сохранить хэндл окна
mov ebx,eax
; Что-то сейчас воспроизводится?
invoke SendMessage,ebx,WM_USER,NULL,104
cmp eax,1
; Winamp не находится в состоянии "Play"
jne .no_winamp
...
Окно мы нашли, состояние проигрывателя знаем, осталось получить название трека, который сейчас воспроизводится. Казалось бы все просто - надо послать еще одно сообщение, которое также описано в документации, и получить результат. Но не тут-то было. Сообщения для получения информации о воспроизводимом файле и названии трека доступны только из контекста процесса самого Winamp, то есть могут использоваться только в плагинах Winamp. Логика разработчиков тут не совсем ясна, ведь для сторонних приложений доступна информация о битрейте текущего трека, размере плей-листа, текущей позиции воспроизведения и еще куча другой малополезной информации, а простейшего названия трека нет.
Городить огороды с плагинами мы не будем, а повнимательнее присмотримся к найденному окну, то которое "Winamp 1.x". Оказывается, Winamp при воспроизведении устанавливает в его заголовок номер и название текущего трека. А именно это нам и надо! Функция
GetWindowText решает все наши проблемы.
...
; Получить текст из заголовка окна
invoke GetWindowText,ebx,buff,300h
or eax,eax
; Непонятная ошибка - текст пустой
jz .no_winamp
...
Строка с названием трека есть, но она имеет вид наподобие "2. Metallica - Master of Puppets - Winamp". В принципе, можно оставить и так, но мы пойдем до победного финала. Для пущей эстетики приведем строку к нормальному виду, то есть отрежем номер трека в начале и суффикс " - Winamp" в конце.
...
; Удалить из строки ' - Winamp'
mov esi,buff
cmp dword [esi+eax-9],' - W'
jne @f
mov byte [esi+eax-9],0
; Удалить из строки номер трека
@@:
lodsb
cmp al,' '
jne @b
; Скопировать название трека
invoke lstrcpy,play_now,esi
; Теперь в буфере play_now содержится название трека
...
Примечательно, что некоторые другие мультимедийные плееры, например,
AIMP и
Apollo также создают окно с именем класса "Winamp 1.x", и, как вы наверное догадались, с полностью аналогичными свойствами. Так что описанный в этой статье метод получения названия воспроизводимого трека подходит и для них.
В приложении пример программы с исходным текстом, получающей в режиме реального времени название воспроизводимого трека из плеера Winamp и совместимых с ним, а также официальная документация Winamp Application Programming Interface.