22 KiB
MusicBridge — план проекта
Обновлено: 2026-09-09. Репозиторий находится в MusicBridge.Agent/.
Цель
Личный пульт на нативном iPhone-приложении для музыки на Windows в одной Wi-Fi сети. Звук играет на ПК. Телефон показывает трек, исполнителя, обложку, позицию и позволяет управлять воспроизведением и системной громкостью ПК.
Решения пользователя — не менять без его указания
- Windows + iPhone; своего Mac сейчас нет.
- Не делать Safari, PWA, веб-страницы или веб-приложение. Клиент — Swift/SwiftUI.
- iPhone-часть пока не начинать. Сначала довести Windows-агент и протокол.
- Работать по этапам, самостоятельно редактировать файлы и проверять сборку.
- Основные источники: Яндекс Музыка и SoundCloud в браузере, через текущую системную медиасессию Windows.
- Нужны безопасное сопряжение, автоматическое переподключение, затем поиск ПК.
- В будущем желательны Lock Screen, Dynamic Island и системные команды iOS.
Границы возможностей
- «Любой звук» относится к системной громкости. Метаданные и команды зависят от того, что конкретный плеер передаёт в Windows Media Session.
- Позиция вычисляется из Position + времени после LastUpdatedTime с учётом PlaybackRate. Нельзя считать Position постоянно обновляемым значением.
- Не обещать работу перемотки или переключений без проверки возможностей плеера.
- Для сборки/подписи нативного iOS-приложения потребуется доступ к macOS/Xcode; способ установки на личный iPhone нужно выбрать перед началом iOS-этапа.
- Возможности iOS в фоне, Lock Screen и Dynamic Island исследовать отдельно. Не имитировать воспроизведение беззвучным аудио ради фоновой работы.
- HTTPS/WebSocket внутри агента — транспорт для нативного клиента, не веб-интерфейс.
Архитектура
Windows Media Session → общий MediaService → HTTPS/WSS → будущий SwiftUI-клиент. Windows Core Audio → системная громкость устройства вывода по умолчанию. Консоль и сеть используют одни команды и одни правила расчёта позиции.
Этапы и TODO
1. Windows: чтение и локальное управление
- Название, исполнитель, источник, состояние и длительность.
- Вычисление текущей позиции с учётом времени и скорости.
- Play/pause, следующий/предыдущий трек, перемотка ±10 секунд.
- Системная громкость ±5%, mute.
- Проверки поддержки команд и обработка отказов.
- Сборка исходной консольной версии: 0 ошибок, 0 предупреждений.
- Проверен запуск с реальным плеером и чтение громкости.
- Полная ручная проверка кнопок в Яндекс Музыке и SoundCloud.
2. Windows: общий сервис и сетевой протокол
- Вынести чтение/команды из Program.cs в общий сервис.
- Добавить абсолютную перемотку и установку громкости для ползунков iPhone.
- Версионированное JSON-состояние, возможности плеера, результаты команд.
- HTTPS для команд, WSS для обновлений состояния; без веб-интерфейса.
- Ограниченное по времени сопряжение по коду, аутентификация команд.
- Сертификат агента и отпечаток для будущего закрепления сертификата на iPhone.
- Проверки протокола, ошибочного ввода и доступа без авторизации.
- Обновить этот файл и документацию по фактическим результатам.
3. Довести агент перед iPhone
- Обложка из медиасессии; ограничение размера, кеш и смена трека.
- Системные события Windows для быстрых обновлений; таймер для прогресса.
- Постоянные доверенные устройства, безопасное хранение хешей токенов, отзыв доступа.
- Постоянный сертификат, защищённое хранилище Windows DPAPI, блокировка второго агента.
- Обновление истекающего сертификата с явным повторным сопряжением.
- Локальный QR с адресом, кодом и отпечатком; Windows-окно по клавише I.
- Обновление QR при смене адреса/кода; очистка при закрытии сопряжения.
- Заготовки: payload для QR, проверка адреса/срока, клавиша I.
- Заготовки: DNS-SD descriptor и авторизованный /v1/info; без multicast.
- Объявление Bonjour/mDNS: PTR/SRV/TXT/A, повторные объявления и goodbye.
- Полноценное разрешение конфликтов имён mDNS (сейчас имя по хешу сертификата).
- Проверить подключение со второго устройства в домашней сети.
- Проверить смену плеера/аудиоустройства, отсутствие плеера, сон/пробуждение, отключение Wi-Fi и несколько клиентов.
- Tray-интерфейс, автозапуск, удобная установка; правила брандмауэра только для нужной локальной сети, без открытия доступа в интернет.
- Трей и окно управления (
--tray): медиакнопки, ползунки, QR, доверенные устройства. - Закрытие окна скрывает его; двойной щелчок по значку восстанавливает; отдельный пункт меню завершает агент. Консоль остаётся отдельным режимом.
- Автозапуск текущего пользователя через меню трея; скрытый старт
--minimized. - Самостоятельный Windows x64 пакет со встроенными Runtime, ZIP-установка, ярлык в меню Пуск и скрипт удаления. Это не MSI и не подписанный установщик.
4. Нативное приложение iPhone — отложено пользователем
- Согласовать macOS/Xcode, подпись и установку на личный iPhone.
- SwiftUI: подключение, список компьютеров, сопряжение и сохранение в Keychain.
- Обложка, трек, исполнитель, плавный прогресс, кнопки и ползунки.
- Проверка сертификата ПК, переподключение и восстановление состояния.
- Отключать недоступные команды, отображать ошибки и потерю связи.
- Проверка на физическом iPhone.
5. Дополнительные возможности iOS
- Исследовать и проверить Live Activities / Dynamic Island / App Intents.
- Зафиксировать реальные ограничения системного управления и фона.
Как продолжать работу
- Прочитать этот файл, затем текущие исходники и
git status. - Не переписывать уже работающие функции без необходимости.
- Выполнить конкретный этап, проверить сборку и соответствующие проверки.
- Отдельно указать: что проверено автоматически, что на реальной Windows, а что ещё требует телефона/ручной проверки.
- Обновить чекбоксы, результаты и следующий шаг здесь до завершения работы.
Проверки и следующий шаг
2026-09-09:
-
Последний этап — автозапуск и упаковка: 107 проверок прошло с
-c Packaging --no-build -- --desktop-smoke --qr-window-smoke --mdns-smoke --live-read. Проверены запись/удаление тестовой записи автозапуска и скрытый старт окна. Тестовая конфигурация Packaging использована, потому что Release exe занят работающим агентом; его не останавливали. Сборка тестов без ошибок/предупреждений. -
Собран
dist/MusicBridge-win-x64.zip(~65 МиБ), Release win-x64 self-contained.Packaging/Test-Package.ps1проверил установку в отдельную папку без ярлыка, запуск со встроенным Runtime, повторную установку, запрет обновления занятого exe и удаление. Рабочий автозапуск и хранилище пользователя не менялись. Перезагрузка Windows и реальное срабатывание автозапуска при входе ещё не проверены. Инструкции — вINSTALL.md. -
Последний этап — окно управления и трей: 102 проверки прошли, Release-сборка без ошибок/предупреждений. Прогон с
--desktop-smoke --qr-window-smoke --mdns-smoke --live-read. В скрытом окне проверены включение/отключение кнопок, отправка play/pause и абсолютной громкости тестовому сервису, скрытие по крестику, продолжение работы и остановка UI-потока. Снимок окна просмотрен. Реальную музыку тесты не меняли. Ручное взаимодействие с видимым значком трея пока не проверялось. -
Последний этап — работающие QR и mDNS: 95 проверок прошло, Release-сборка без ошибок и предупреждений. Прогон:
dotnet run --project tests/MusicBridge.Agent.Tests.csproj -c Release --no-build -- --qr-window-smoke --mdns-smoke --live-read. Проверены декодирование QR независимой библиотекой, скрытое окно и очистка просроченного QR, реальные объявления/goodbye mDNS отдельным слушателем на этом же ПК. Снимок окна просмотрен. Реальная обложка: JPEG, 12068 байт. Второе физическое устройство и сканирование телефоном пока не проверялись. Далее — исторические результаты предыдущих этапов. -
Последний этап — заготовки подключения: Release-сборка без ошибок/предупреждений, 82 автоматические проверки прошли (
dotnet run --project tests/MusicBridge.Agent.Tests.csproj -c Release --no-build). Проверены payload, адреса, истёкший код, descriptor и авторизация /v1/info. Debug-сборку удерживал запущенный агент; его не останавливали. Новая сборка в Release. Реальная медиасессия в этом прогоне не проверялась; проверки ниже — с прошлого этапа. -
Сборка агента и тестового проекта: 0 ошибок, 0 предупреждений.
-
dotnet run --project tests/MusicBridge.Agent.Tests.csproj -- --live-read: 74 проверки прошло (71 общая + 3 с реальной медиасессией/обложкой). Проверены расчёт позиции, валидация, срок/одноразовость кода, блокировка после 10 попыток, авторизация HTTPS/WSS, ошибки JSON и размер запроса, доставка абсолютной перемотки тестовому сервису, поток состояния и закрытие WebSocket. Добавлены проверки размера/формата обложки, отмены чтения, очистки старого кеша, авторизации скачивания и 404, доставки событий без ожидания таймера, объединения 1000 уведомлений и снятия подписки сервером при остановке. Проверены сохранение/повторное открытие сертификата и устройств, реальный HTTPS со восстановленным сертификатом/токеном, DPAPI, блокировка второго экземпляра, ошибки записи, отказ от подмены повреждённого хранилища, постоянный отзыв доступа, отключение открытого WSS и запрет HTTP-команд отозванным токеном. -
В тестах добавлена обработка исключений верхнего уровня. Проверен
--test-failure: текстTEST FAILEDи выход 1 вместо необработанного исключения, вызвавшего ранее окно ошибки Windows. Тестовые файлы создаются отдельно от рабочего хранилища и удаляются после проверки. -
Эти проверки не меняют реальную музыку/громкость. Ручная проверка команд конкретных плееров и физического iPhone всё ещё не выполнена.
-
Обновлённый агент запущен в обычном сеансе Windows на loopback-порту 18765: HTTPS-сервер стартовал, реальная медиасессия, состояние Paused, длительность и системная громкость прочитаны. После проверки тестовый запуск остановлен.
-
После добавления обложки в режиме
--live-readпрочитан реальный PNG размером 438760 байт. Повторное чтение состояния сохранило тот же ID кешированной обложки. Подписки WinRT создаются успешно. Доставка событий проверена тестовым сервисом; ручная смена треков/плееров во время работы агента ещё требует проверки. -
В песочнице Windows Media Session может быть недоступна. Не выдавать такую ошибку за отсутствие Windows API на машине пользователя.
Текущие ограничения сетевого этапа:
- Состояние обновляется по событиям Windows и резервному таймеру ~500 мс. Метаданные/обложка перечитываются по событию либо через 10 секунд.
- В кеше только текущая обложка, максимум 2 МиБ; PNG/JPEG/GIF/WebP по сигнатуре, без декодирования на сервере. Скачивание требует авторизации.
- Сертификат и хеши токенов сохраняются в
%LOCALAPPDATA%\MusicBridge\identity.datпод Windows DPAPI текущего пользователя. При обычном перезапуске доверие сохраняется. В консоли1…8отзывают доступ устройства по номеру;Bоткрывает сопряжение. - Сертификат действует 5 лет; автоматическое обновление ещё не реализовано. При повреждении/недоступности хранилища или истечении сертификата агент завершается с ошибкой и не создаёт молча новую идентичность. Восстановление описано в PROTOCOL.md.
- По умолчанию только loopback.
--lanвключает IPv4-сеть; брандмауэр не меняется. - QR и mDNS реализованы на Windows. iPhone UI и интеграции iOS ещё не реализованы.
- Адреса обновляются примерно раз в секунду; mDNS пересоздаётся при смене списка, объявляется на домашних IPv4-адаптерах с multicast. Автоизменения брандмауэра нет.
Следующий шаг: проверка с другого устройства и устойчивости при смене сети,
проверка входа Windows с автозапуском и подготовка правил частного брандмауэра.
Трей, автозапуск и ZIP-упаковка реализованы. iPhone-клиент пока не начинать.
Точные границы реализации и следующие шаги — в CONNECTION-ROADMAP.md.
Начать разработку iOS только после новой команды пользователя.
Карта файлов
Program.cs: запуск, аргументы, консольные клавиши и отображение состояния.Media/MediaService.cs: чтение Windows Media Session и выполнение всех команд.Media/TimelineMath.cs: вычисление позиции и границ перемотки.Media/Contracts.cs: состояние, возможности, команды и их валидация.Media/ArtworkCache.cs: ограниченное чтение обложки, определение типа и кеш по хешу.SystemVolume.cs: Windows Core Audio, громкость устройства вывода по умолчанию.Network/RemoteServer.cs: HTTPS API и обложки, WSS, события/таймер и лимиты.Network/PairingService.cs: код сопряжения, доверенные устройства, проверка/отзыв токенов.Network/IdentityStore.cs: постоянный сертификат и устройства, атомарная запись и блокировка.Network/UserProtection.cs: Windows DPAPI текущего пользователя.Network/AgentCertificate.cs: создание сертификата TLS для первого запуска.PROTOCOL.md: команды запуска и точный контракт будущего iPhone-клиента.CONNECTION-ROADMAP.md: заготовки QR/DNS-SD и шаги будущего подключения.Network/ConnectionInvitation.cs: проверка и формат данных QR.Network/PairingQr.cs: локальная генерация PNG (QRCoder).PairingWindowHost.cs: окно QR на отдельном STA-потоке, выбор адреса и обновления.Desktop/AgentWindow.cs: окно управления, ползунки и доверенные устройства.Desktop/DesktopHost.cs: STA-поток, значок/меню трея и жизненный цикл окна.Desktop/StartupSettings.cs: HKCU Run, экранированная команда автозапуска.Packaging/: сборка standalone ZIP, установка/удаление и изолированный smoke-тест.INSTALL.md: установка, автозапуск, обновление и удаление.Network/LocalAddresses.cs: подходящие домашние IPv4-адреса.Network/DiscoveryDescriptor.cs: публичные поля DNS-SD.Network/MdnsPublisher.cs: объявления mDNS, обновления адресов и goodbye.tests/: исполняемые проверки без дополнительных тестовых NuGet-пакетов.