9 из 133 мин

Медиа-контроль как сценарии в Hammerspoon

Хочется иметь “внутренний цифровой микшер”, привязанный к одному устройству управления: чтобы быстро контролировать медиа и звук во всех открытых приложениях. Полного решения под это я пока не нашел: то, что пробовал, даёт задержку и иногда ведёт себя нестабильно.

Через Hammerspoon получилось приблизиться к нужному ощущению хотя бы на уровне практичного минимума: быстро и предсказуемо управлять воспроизведением в конкретных приложениях. Это не микшер в полном смысле, но уже радикально ускоряет работу с медиа.

Принцип

Не “универсальная кнопка паузы”, а сценарии под конкретные приложения:

активировать нужное приложение → дать фокусу “успокоиться” → отправить правильную команду → при необходимости иметь запасной путь.

1) Spotify: play/pause напрямую

Для Spotify используется AppleScript-команда playpause.

Плюс такого подхода: это не эмуляция клавиш, команда уходит прямо в Spotify и не зависит от того, какое окно активно.

2) YouTube / Twitch и похожие плееры: фокус → k

Для YouTube и Twitch сделан одинаковый паттерн:

  • активируется приложение

  • выход из Space-layer перед отправкой k, чтобы слой не перехватил клавишу

  • короткая задержка

  • отправляется k (стандартный play/pause в плеерах)

Важно: выход из слоя здесь не “косметика”, а инженерная деталь. Если оставить слой активным, k может интерпретироваться как команда слоя, а не как команда плеера.

Пример:

spaceLayer:bind({}, "t", function()
  local app = hs.application.find("Twitch")
  if not app then return hs.alert.show("Twitch не запущен") end
  app:activate()
  spaceLayer:exit()
  hs.timer.doAfter(0.05, function() hs.eventtap.keyStroke({}, "k") end)
end)

Разбор:

  • spaceLayer:bind({}, “t”, …) — внутри Space-layer клавиша T запускает сценарий.

  • hs.application.find(“Twitch”) — найти запущенный Twitch (иначе показать alert).

  • app:activate() — сфокусировать Twitch.

  • spaceLayer:exit() — выйти из слоя, чтобы k не перехватился хоткеями слоя.

  • hs.timer.doAfter(0.05, …) — небольшая задержка для переключения фокуса.

  • hs.eventtap.keyStroke({}, “k”) — отправить k (play/pause).

3) Safari: тот же принцип “поймать нужный плеер”

Отдельно заведены сценарии под Safari, с тем же смыслом:

  • сфокусировать браузер

  • небольшая пауза

  • отправить k в активную вкладку/плеер

Это удобно, когда медиа играет в разных местах: команда сначала приводит контекст в порядок, а потом уже нажимает “пауза”.

4) Apple Music и Podcasts: фокус → space + задержка

Для Music и Podcasts используется другой “язык управления”:

  • активируется приложение

  • небольшая задержка (чтобы фокус точно перешёл)

  • отправляется space как play/pause

Задержка тут важна: без неё часть команд уходит “в никуда” или в неправильный элемент интерфейса.

5) Apple Books: UI scripting + fallback (самый надёжный вариант)

Books сделан максимально устойчиво, потому что интерфейс и состояния там бывают капризные:

  • приложение активируется

  • через System Events пробуется нажатие Play/Pause в меню (учтены разные названия меню и RU/EN)

  • если меню не сработало, fallback: отправка space в приложение

Это по сути “двухконтурная система”: сначала самый надёжный путь (меню), затем резервный (клавиша).

В следующем посте покажу базовый код HTTP-сервера в Hammerspoon и структуру эндпоинтов.

Оглавление серии
  1. Клавиатурные слои
  2. Karabiner = набор JSON-правил
  3. 1) Caps Lock = Hyper
  4. 2) Слой на Space: tap = пробел, hold = F18
  5. 3) backtick hold = F17
  6. 4) RU-раскладка: точечные правила только для русского набора
  7. Hammerspoon
  8. Window Manager в Hammerspoon
  9. Медиа-контроль как сценарии в Hammerspoon
  10. Hammerspoon как локальный сервер и “пульт” управления
  11. Мониторы и стабильность рабочего места (Hammerspoon)
  12. MIDI-клавиатура и OBS как аппаратный контроллер (Hammerspoon)
  13. Тема клавиатурных слоев на этом этапе закрыта.