Blog. Just Blog

Как получить название текущего трека из Winamp и AIMP

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: Assembler | Автор: ManHunter
Winamp был и остается самым популярным мультимедийным плеером для Windows. Такая популярность не могла остаться незамеченной, поэтому появились программы, использующие информацию из него в своих целях. Например, плагины для интернет-мессенджеров устанавливают название воспроизводимого трека в качестве статуса, а моя программа My Music Web Agent отправляет эту информацию в интернет. Для взаимодействия сторонних приложений с Winamp был разработан интерфейс API со своими командами и синтаксисом. По какой-то причине разработчики Winamp сейчас вообще убрали с сайта информацию об API, но в интернете эти данные остались. Я приложил описание Winamp Application Programming Interface в архиве с примером программы, рекомендую ознакомиться с ним перед прочтением статьи, чтобы не возникало вопросов откуда взялись те или иные значения.
  1. ; Сегмент данных
  2. section '.data' data readable writeable
  3.  
  4. ; Название класса окна Winamp/AIMP
  5. wcl      db      'Winamp v1.x',0
  6.  
  7. buff     rb 300h  ; Буфер для получения текста из заголовка окна
  8. 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 ничего не воспроизводит или находится в режиме паузы.
  1. ; Сегмент кода
  2. section '.code' code readable executable
  3.         ...
  4.         ; Получить хэндл окна Winamp
  5.         invoke  FindWindow,wcl,0
  6.         or      eax,eax
  7.         ; Окно Winamp не найдено
  8.         jz      .no_winamp
  9.  
  10.         ; Сохранить хэндл окна
  11.         mov     ebx,eax
  12.  
  13.         ; Что-то сейчас воспроизводится?
  14.         invoke  SendMessage,ebx,WM_USER,NULL,104
  15.         cmp     eax,1
  16.         ; Winamp не находится в состоянии "Play"
  17.         jne     .no_winamp
  18.         ...
Окно мы нашли, состояние проигрывателя знаем, осталось получить название трека, который сейчас воспроизводится. Казалось бы все просто - надо послать еще одно сообщение, которое также описано в документации, и получить результат. Но не тут-то было. Сообщения для получения информации о воспроизводимом файле и названии трека доступны только из контекста процесса самого Winamp, то есть могут использоваться только в плагинах Winamp. Логика разработчиков тут не совсем ясна, ведь для сторонних приложений доступна информация о битрейте текущего трека, размере плей-листа, текущей позиции воспроизведения и еще куча другой малополезной информации, а простейшего названия трека нет.

Городить огороды с плагинами мы не будем, а повнимательнее присмотримся к найденному окну, то которое "Winamp 1.x". Оказывается, Winamp при воспроизведении устанавливает в его заголовок номер и название текущего трека. А именно это нам и надо! Функция GetWindowText решает все наши проблемы.
  1.         ...
  2.         ; Получить текст из заголовка окна
  3.         invoke  GetWindowText,ebx,buff,300h
  4.         or      eax,eax
  5.         ; Непонятная ошибка - текст пустой
  6.         jz      .no_winamp
  7.         ...
Строка с названием трека есть, но она имеет вид наподобие "2. Metallica - Master of Puppets - Winamp". В принципе, можно оставить и так, но мы пойдем до победного финала. Для пущей эстетики приведем строку к нормальному виду, то есть отрежем номер трека в начале и суффикс " - Winamp" в конце.
  1.         ...
  2.         ; Удалить из строки ' - Winamp'
  3.         mov     esi,buff
  4.         cmp     dword [esi+eax-9],' - W'
  5.         jne     @f
  6.         mov     byte [esi+eax-9],0
  7.  
  8.         ; Удалить из строки номер трека
  9. @@:
  10.         lodsb
  11.         cmp     al,' '
  12.         jne     @b
  13.  
  14.         ; Скопировать название трека
  15.         invoke  lstrcpy,play_now,esi
  16.  
  17.         ; Теперь в буфере play_now содержится название трека
  18.         ...
Примечательно, что некоторые другие мультимедийные плееры, например, AIMP и Apollo также создают окно с именем класса "Winamp 1.x", и, как вы наверное догадались, с полностью аналогичными свойствами. Так что описанный в этой статье метод получения названия воспроизводимого трека подходит и для них.

В приложении пример программы с исходным текстом, получающей в режиме реального времени название воспроизводимого трека из плеера Winamp и совместимых с ним, а также официальная документация Winamp Application Programming Interface.

Get Winamp Track DemoGet Winamp Track Demo

Get.Winamp.Track.Demo.zip (7,547 bytes)


Поделиться ссылкой ВКонтакте
Просмотров: 7756 | Комментариев: 9

Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
ManHunter (05.05.2015 в 08:27):
В новой версии будет JA. Я сделал через нормальные API этого плеера.
Прол Смит (05.05.2015 в 07:42):
название класса окна Jet-Audio - "COWON Jet-Audio MainWnd Class"
остальные действия такие-же
Dolsha (09.02.2015 в 09:13):
Большое спасибо, я нашел решение поставленной задачи более грамотно, но просто интерес все равно остался и вот сижу и понимаю, что мои знания ассемблера очень скудны и на самом деле он не знает преград)
ManHunter (09.02.2015 в 09:00):
Заменить вывод строки на запись ее в файл. По ключевым словам _lopen, _lwrite все примеры элементарно гуглятся. Исходник открытый, заменить не проблема.
Dolsha (09.02.2015 в 06:02):
ManHunter, а как сделать так, чтобы информация сохранялась в файл .txt, а не выводилась в окне?
Заранее спасибо
З.Ы. уже замучился искать готовое решение для АИМПА.
ManHunter (21.11.2013 в 13:26):
Корпорация AOL закрыла проект Winamp. Американская IT-корпорация AOL приняла решение закрыть проект Winamp, который включал в себя медиаплеер и ряд музыкальных сервисов. Плеер станет недоступен с 20 декабря, тогда же прекратит работу и сайт winamp.com. Об этом говорится в объявлении, размещенном на сайте проекта.
AyTkACT (01.12.2011 в 12:20):
ManHunter, вирмейкерство олдскульное - это и уму и сердцу, а вот теперешнее... (Далее следует непереводимая игра слов с использованием местных идиоматических выражений)
ManHunter (01.12.2011 в 11:04):
Ну почему же ни уму ни сердцу? ЛЮБОЕ программирование - это в первую очередь практика, изучение нового. Я, например, учил Ассемблер на написании вирусов. Тоже, казалось бы, бесполезная вещь, но с другой стороны это работа с файловой системой, памятью, оптимизация кода, изучение различных форматов файлов, множество нестандартных решений и еще куча всего полезного.
AyTkACT (01.12.2011 в 10:28):
Имхо, познавательно, но прикладного значения не имеет. Все эти информеры, рюшечки, соц. сети и прочая тратата на букву "х", не даёт ни уму ни сердцу.
Куда полезней было бы заиметь на asm'e HashCheck ( hxxp://code.kliu.org/hashcheck/ ), переработанный, оптимизированный, с добавлением/удалением актуальных алго хеширования, etc.
Хотя сабж и так достаточно быстрый, но оптимизация - она весчь такая, совершенства не имеющая))

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 2 (0.0053 сек.) / Память: 4.5 Mb
Наверх