Voice
Диктовка в меню-баре macOS на локальном Whisper — речь в текст в любом приложении, на устройстве.
Dev-storyЗадача
Диктовка ОС или облачных приложений отправляет голос за пределы устройства и часто мажет по терминам; хотели быструю приватную диктовку в любом приложении.
Что делали
WebEdge Voice — Swift-приложение в меню-баре macOS, запускающее Whisper локально: выбираешь микрофон и язык, жмёшь горячую клавишу для диктовки, и распознанный текст вставляется туда, где печатаешь — ничего не уходит на сервер.
Результат
Речь в текст где угодно на Mac, на устройстве и приватно, с настройками языка и микрофона прямо из меню-бара.
Dev-story статья
Voice: как создавался проект
Облачная диктовка быстра, но отправляет ваш голос за пределы машины; локальная сохраняет приватность, но обычно настолько медленна, что кажется сломанной. Это приложение выбирает второй путь и отказывается от медлительности: нажимаете сочетание, говорите, и транскрипция появляется в том поле, что сейчас в фокусе, а Whisper выполняет декодирование на том же Mac. Большая часть инженерной работы - не сама транскрипция, а миллисекунды вокруг неё и механизмы macOS, позволяющие вставленному тексту дойти до других приложений.
Разделы
05
Модули
05
Стек
Swift + Whisper
Почему появился проект
Диктовка ОС или облачных приложений отправляет голос за пределы устройства и часто мажет по терминам; хотели быструю приватную диктовку в любом приложении.
Облачная диктовка быстра, но отправляет ваш голос за пределы машины; локальная сохраняет приватность, но обычно настолько медленна, что кажется сломанной. Это приложение выбирает второй путь и отказывается от медлительности: нажимаете сочетание, говорите, и транскрипция появляется в том поле, что сейчас в фокусе, а Whisper выполняет декодирование на том же Mac. Большая часть инженерной работы - не сама транскрипция, а миллисекунды вокруг неё и механизмы macOS, позволяющие вставленному тексту дойти до других приложений.
Что было создано
WebEdge Voice — Swift-приложение в меню-баре macOS, запускающее Whisper локально: выбираешь микрофон и язык, жмёшь горячую клавишу для диктовки, и распознанный текст вставляется туда, где печатаешь — ничего не уходит на сервер.
Приложение диктовки в строке меню для macOS 14+ на Apple Silicon, построенное на whisper.cpp с Metal и вызываемое по Ctrl+Shift+Space. Модель Whisper не входит в комплект - вы выбираете её при первом запуске как отдельную загрузку ~1,6 ГБ - и всё от захвата микрофона до вывода и вставки работает локально. Оно намеренно выпущено только для русского языка, а не притворяется, что обслуживает языки, которые модель транскрибирует плохо.
Основные модули и путь пользователя
Прогревающее декодирование при запуске: первая диктовка стоила 407 мс на построение конвейеров Metal и графа вычислений, поэтому односекундное тихое декодирование в задаче запуска убирает эту цену с первых слов пользователя, снижая первую диктовку до ~104 мс.
Разблокировка пути вставки: insertText дважды засыпал в главном потоке (~56 мс реальной цены); восстановление буфера перенесено в asyncAfter с проверкой changeCount, чтобы вторая диктовка не затёрла первую, и вставка теперь занимает 1-6 мс.
История с подписью и разрешением Accessibility: macOS привязывает разрешение Accessibility к идентификатору подписи кода и cdhash, поэтому ad-hoc-пересборки читались как новое приложение и каждый раз теряли разрешение - решено переподписью с фиксированным идентификатором и стабильным самоподписанным локальным сертификатом, который привязывает требование к сертификату, а не к меняющемуся бинарнику.
Фильтрация галлюцинаций и мёртвого потока: отклонять потоки микрофона, состоящие из сплошной нулевой тишины, до вывода, масштабировать audioCtx и лимиты токенов под длину клипа, чтобы прекратить обрезку длинных клипов и петли повторов, и после декодирования вырезать известные артефакты корпуса субтитров (проверено 53/53 пойманы, ноль ложных срабатываний на 2439 записях).
Опциональный Silero VAD, по умолчанию выключен и честен насчёт этого: бесполезен на коротких клипах, для которых сделано приложение (~2 мс экономии), но при длинной диктовке он убирает тишину, чтобы клип снова уложился в окно Whisper в 30 с и вдвое сократил проходы энкодера - запись на 92 с прошла с двух проходов до одного.
Архитектура и технологические решения
Сделано на Swift, Whisper, macOS.
Swift с вручную воспроизведённым мостом к whisper.cpp (зафиксированному на v1.9.1), работающему на Metal, только Apple Silicon, со вставкой текста через API Accessibility и буфер обмена; run.sh обслуживает путь локальной самоподписи, а скрипты релиза с нотаризованным DMG - для распространения.
Результат и выводы
Речь в текст где угодно на Mac, на устройстве и приватно, с настройками языка и микрофона прямо из меню-бара.
Приватный инструмент диктовки на устройстве, где сам Whisper проходит ~90 мс от начала до конца, а путь от нажатия до вставки ощущается мгновенным - честно одна машина, одна модель, один язык, а не облачный сервис под маской.
Связанные статьи
Читать дальше
Связанные истории проектов
Эти проекты близки по техническим или продуктовым решениям и показывают, как тот же принцип работает в другом контексте.
Dev-storyMac GPU Checker
macOS-бенчмарк GPU в реальных TFLOPS (fp16 GEMM) — и держит ли чип число под нагрузкой.
Dev-storyFableVita
FableVita — AI-фитнес-тренер с лигами, квестами и защищённой от фрода экономикой наград.
Dev-storyCMS
Динамический headless-CMS на webedge-db — типы контента, медиа, роли и публичный read-API, питающий наши сайты и статьи.
Есть похожая идея?
Обсудить проект