Files
windows/PLAN.md
T
ros d5e827112a Add MusicBridge protocol documentation and implement system volume control
- Created PROTOCOL.md to outline the MusicBridge protocol v1, detailing setup, TLS, pairing, state management, and command structure.
- Implemented SystemVolume class for managing system audio levels, including methods for setting, reading, changing, and muting volume.
- Added unit tests for the MusicBridge agent, covering pairing, identity storage, command validation, and media state management.
- Included tests for real-time media reading from Windows and ensured proper handling of artwork caching and retrieval.
2026-09-09 01:05:52 +03:00

17 KiB
Raw Blame History

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-сопряжение с адресом и отпечатком сертификата.
  • Заготовки: payload для QR, проверка адреса/срока, клавиша I.
  • Заготовки: DNS-SD descriptor и авторизованный /v1/info; без multicast.
  • Bonjour/mDNS для поиска из нативного приложения.
  • Проверить подключение со второго устройства в домашней сети.
  • Проверить смену плеера/аудиоустройства, отсутствие плеера, сон/пробуждение, отключение Wi-Fi и несколько клиентов.
  • Tray-интерфейс, автозапуск, удобная установка; правила брандмауэра только для нужной локальной сети, без открытия доступа в интернет.

4. Нативное приложение iPhone — отложено пользователем

  • Согласовать macOS/Xcode, подпись и установку на личный iPhone.
  • SwiftUI: подключение, список компьютеров, сопряжение и сохранение в Keychain.
  • Обложка, трек, исполнитель, плавный прогресс, кнопки и ползунки.
  • Проверка сертификата ПК, переподключение и восстановление состояния.
  • Отключать недоступные команды, отображать ошибки и потерю связи.
  • Проверка на физическом iPhone.

5. Дополнительные возможности iOS

  • Исследовать и проверить Live Activities / Dynamic Island / App Intents.
  • Зафиксировать реальные ограничения системного управления и фона.

Как продолжать работу

  1. Прочитать этот файл, затем текущие исходники и git status.
  2. Не переписывать уже работающие функции без необходимости.
  3. Выполнить конкретный этап, проверить сборку и соответствующие проверки.
  4. Отдельно указать: что проверено автоматически, что на реальной Windows, а что ещё требует телефона/ручной проверки.
  5. Обновить чекбоксы, результаты и следующий шаг здесь до завершения работы.

Проверки и следующий шаг

2026-09-09:

  • Последний этап — заготовки подключения: 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, iPhone UI и интеграции iOS ещё не реализованы.

Следующий шаг: этап 3 — QR-сопряжение (адрес, код, закрепляемый отпечаток), затем Bonjour/mDNS и проверка с другого устройства. 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/DiscoveryDescriptor.cs: описание DNS-SD, без сетевой рассылки.
  • tests/: исполняемые проверки без дополнительных тестовых NuGet-пакетов.