TGViewer
annFlow annFlow @annsflow · 33 subscribers
Post #86 43
Медиа-контроль как сценарии в 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 и структуру эндпоинтов.


Оглавление темы 📌
Навигация по проектам канала 📍
Все проекты 🎶

#macOSAutomation@annsFlow

💻 annFlow
More from @annsflow
  1. Sep 24, 2026LiveContext в реальном разговоре. На видео я разбираюсь с претензией по недоставленному за…
  2. Sep 21, 2026Как LiveContext разделяет мой голос и голос собеседника Чтобы LiveContext мог понимать раз…
  3. Sep 16, 2026Почему мне оказалось недостаточно просто сохранять разговоры В VoxBase я решал проблему то…
  4. Sep 15, 2026Как я построил LiveContext, или Как связать живой разговор с памятью проекта ● Почему мне…
  5. Sep 14, 2026annFlow pinned a video
  6. Sep 14, 2026Самая неожиданная вакансия, которую нашел мой бот Моя система постоянно сама ищет вакансии…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →