Хочется иметь “внутренний цифровой микшер”, привязанный к одному устройству управления: чтобы быстро контролировать медиа и звук во всех открытых приложениях. Полного решения под это я пока не нашел: то, что пробовал, даёт задержку и иногда ведёт себя нестабильно.
Через 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 и структуру эндпоинтов.
Оглавление темы 📌
Навигация по проектам канала 📍
Все проекты 🎶
#macOSAutomation@annsFlow
💻 annFlow