Разработка мобильного приложения для аудиокниг
Audiobooks-плеер — одно из технически плотных медиа-приложений на мобильном. Здесь сходятся: точное управление воспроизведением, агрессивное кеширование больших файлов, DRM для защиты контента, глава-навигация, таймер сна и синхронизация позиции между устройствами. Каждый пункт — это конкретная реализация, а не «медиаплеер».
Формат файлов и потоковое воспроизведение
Аудиокниги чаще всего в форматах: MP3 (самый широкий), M4B (AAC в контейнере MP4 с chapter markers, стандарт Apple), M4A, OGG/Opus. M4B предпочтителен для новых каталогов — он нативно содержит главы, обложку и метаданные без сайдкара.
Потоковое воспроизведение (не скачивать полностью перед воспроизведением): AVPlayer на iOS открывает HTTP URL и начинает играть без полной загрузки. ExoPlayer (Media3) на Android — аналогично через DefaultDataSource.Factory. Для длинных файлов (15 часов = ~800 МБ) это критично.
Главы из M4B: AVAsset.loadChapterMetadataGroups(bestMatchingPreferredLanguages:) возвращает AVTimedMetadataGroup[] с временными метками и названиями. На Android — MediaMetadataRetriever.extractMetadata + парсинг MP4 box structure для chapter atoms, либо используем ExoPlayer с кастомным MetadataRetriever.
Точное сохранение позиции
Пользователь слушает книгу в машине, закрывает приложение — при следующем открытии должен попасть ровно на то место. С точностью до секунды.
Сохраняем currentTime (Double, секунды) + bookId + timestamp сохранения в UserDefaults/SharedPreferences при каждом фоновом переходе, уходе в background (applicationDidEnterBackground) и через Timer каждые 5 секунд во время воспроизведения. Timer каждые 5 секунд — не каждую секунду, это избыточно.
При восстановлении: player.seek(to: CMTime(seconds: savedPosition, preferredTimescale: 1000)) с .seconds точностью. Не MSEC — для аудио достаточно.
Синхронизация между устройствами: CloudKit CKRecord (iOS) или Firebase Firestore с userId/bookId ключом. При открытии книги на новом устройстве предлагаем «Продолжить с 1:23:45» — пользователь решает.
Таймер сна
Популярная функция: воспроизведение останавливается через N минут. Тривиально — DispatchQueue.main.asyncAfter (iOS) или Handler.postDelayed (Android). Нетривиальный вариант: «остановить в конце текущей главы» — получаем endTime текущей главы из метаданных и планируем остановку на это время.
Плавное затухание перед остановкой: за 30 секунд до конца уменьшаем player.volume линейно до 0 через CADisplayLink / ValueAnimator. Не резкая остановка — это раздражает.
Скорость воспроизведения и pitch correction
player.rate = 1.5 (AVPlayer) ускоряет воспроизведение, но поднимает pitch — голос становится писклявым. iOS автоматически применяет pitch correction для AVPlayer при rate ≠ 1.0 с iOS 16. На более старых — AVAudioUnitTimePitch в AVAudioEngine pipeline.
Android ExoPlayer: playbackParameters = PlaybackParameters(speed = 1.5f) — pitch correction встроен. Flutter just_audio: player.setSpeed(1.5) с pitchCorrectionMethod по умолчанию.
Диапазон полезных скоростей: 0.75x (для сложного технического контента), 1.0x, 1.25x, 1.5x, 2.0x. Больше 2x — разборчивость падает критически.
Офлайн-скачивание и DRM
Скачивание для офлайна — URLSessionDownloadTask + URLSessionConfiguration.background (iOS): работает даже когда приложение не запущено, прогресс сохраняется при крашах. Android: WorkManager + DownloadManager или OkHttp с кастомным прогрессом.
Для платного контента нужен DRM. FairPlay Streaming (iOS) — интегрируется с AVContentKeySession. Widevine L3 (Android) — ExoPlayer с DefaultDrmSessionManager. Ключ шифрования запрашивается у лицензионного сервера при каждом воспроизведении. Без DRM пользователь копирует файл из /Library/Application Support и слушает без подписки.
Альтернатива без full DRM: AES-256 шифрование файла на диске с ключом, привязанным к аккаунту и DeviceID. Дешевле в реализации, но меньше защиты.
Каталог и поиск
Библиотека пользователя: купленные и скачанные книги. Каталог магазина: поиск, жанры, новинки, рекомендации. Пагинация через cursor (Alchemy-style next token или offset/limit). Обложки — через SDWebImage/Coil/cached_network_image с агрессивным disk cache (обложки меняются редко).
| Функция | MVP | Полная версия |
|---|---|---|
| Воспроизведение MP3/M4B | да | да |
| Главы и навигация | нет | да |
| Офлайн-скачивание | нет | да |
| Синхронизация позиции | нет | да |
| DRM | нет | да |
| Таймер сна | да | да |
Сроки: MVP-плеер с каталогом и базовым воспроизведением — 3-4 недели. Полный продукт с DRM, офлайном, синхронизацией и подпиской — 8-12 недель.







