Розробка мобільного додатку для стримінгу музики
Стримінг музики технічно складніше відео в одному ключовому аспекті — користувач швидко переключається між треками, очікує миттєвого старту наступного, слухає в фоні годинами, керує воспроизведенням з Lock Screen, AirPods та Apple Watch. Все це потребує глибокої інтеграції з системним аудіо-шаром, а не просто «AVPlayer грає mp3».
AVAudioSession та Audio Focus
iOS. Правильна налаштування AVAudioSession — перше:
do {
try AVAudioSession.sharedInstance().setCategory(
.playback,
mode: .default,
options: [.allowBluetooth, .allowAirPlay]
)
try AVAudioSession.sharedInstance().setActive(true)
} catch {
// обробити — без цього звуку в фоні не буде
}
Категорія .playback — єдина, яка продовжує воспроизведення при заблокованому екрані та у фоні. .allowBluetooth потрібен для Bluetooth-наушників з кодеком нижче A2DP. При вхідному дзвінку система автоматично перериває — слухати AVAudioSession.interruptionNotification та правильно возобновити після дзвінка.
Android. AudioManager.requestAudioFocus заміщена на AudioFocusRequest (API 26+). Музичний плеєр має обробляти три сценарії: повна втрата фокусу (вхідний дзвінок → пауза), тимчасова (навігаційний голос → зменшити гучність), повернення фокусу (возобновити). AudioFocusRequest.Builder з OnAudioFocusChangeListener — без цього додаток продовжує грати поверх дзвінка.
MediaSession та Lock Screen Controls
Керування з Lock Screen та наушників — через MPNowPlayingInfoCenter (iOS) та MediaSession (Android).
iOS: MPRemoteCommandCenter — реєструємо обробники для play, pause, next, previous, seek. MPNowPlayingInfoCenter.default().nowPlayingInfo — метаданні: назва, виконавець, обкладинка (як MPMediaItemArtwork), довжина, поточна позиція. Обкладинка завантажується асинхронно, оновлювати через MPNowPlayingInfoCenter після завантаження.
Android: MediaSessionCompat (чи MediaSession з Jetpack Media3) + MediaNotification з кастомним NotificationCompat.MediaStyle. Кнопки попередній/гра/пауза — через PendingIntent чи MediaSession.Callback.
Черга, плейлисти та shuffle
Черга воспроизведення — не просто список URL. Урахувати: shuffle без повторів (Fisher-Yates), історія для кнопки «назад», crossfade між треками.
Crossfade. iOS — два AVPlayer чи AVQueuePlayer. AVQueuePlayer.insert(_:after:) дозволяє вставити наступний в чергу; для crossfade — AVAudioMixInputParameters з volume ramping. Альтернатива: два паралельних AVAudioPlayer з envelope на кожному.
Android: ExoPlayer Media3 підтримує MediaItem.ClippingConfiguration для налаштування точок fade. Для crossfade — ConcatenatingMediaSource з кастомним TransitionListener.
Gapless playback. Між треками не має бути паузи. AVQueuePlayer на iOS робить gapless нативно при правильно прикріплених items. ExoPlayer: ConcatenatingMediaSource теж gapless при умові однакового sample rate. Якщо треки різних форматів чи sample rate — можливий невеликий gap при resampling.
Стриміинг та offline
Формати. AAC 256 кбіт/с — стандартний формат для високої якості. MP3 320 кбіт/с — сумісність. Lossless: ALAC (iOS, нативно) чи FLAC (Android, ExoPlayer). HLS для адаптивного бітрейту — корисний при нестабільній мережі.
Progressive download. Почати воспроизведення до повного завантаження. AVPlayer робить це автоматично з HTTP URL. ExoPlayer: DefaultDataSource.Factory з кешуванням через SimpleCache. Кешована трек воспроизводиться з кешу при offline.
Offline-бібліотека. Завантаження треків для offline: URLSessionDownloadTask (iOS) з BackgroundURLSession — завантаження продовжується у фоні. Android: DownloadManager чи ExoPlayer DownloadService. DRM-захищений контент — offline ліцензія (FairPlay / Widevine), як у відео.
Структура зберігання: треки у FileManager.default.urls(for: .documentDirectory) на iOS — не cachesDirectory, операційна система може видалити при нехватці місця. Метаданні в CoreData/Room: trackId, localFilePath, downloadDate, expiresAt (для ліцензій з TTL).
Visualizer та еквалайзер
Audio visualizer (аналізатор частот) — AVAudioEngine + AVAudioNode на iOS для tap на output node, FFT через vDSP_fft_zrip з Accelerate framework. На Android: Visualizer клас з android.media.audiofx, але потребує дозволу RECORD_AUDIO на деяких пристроях — неочевидна залежність.
Еквалайзер: AVAudioUnitEQ (iOS) чи Equalizer з android.media.audiofx (Android). Presets: Bass Boost, Vocal, Electronic — набір фільтрів з передустановленими коефіцієнтами. Кастомний еквалайзер — параметричні EQ з користувацькими band gains.
Каталог та рекомендації
Пошук треків: Elasticsearch з multi_match по title, artist, album. Рекомендації по схожим виконавцям — collaborative filtering на бекенді (історія прослухування користувачів) чи content-based (audio features: tempo, key, energy через Essentia чи AcousticBrainz).
Last.fm API для метаданих виконавців (біографія, схожі артисти). MusicBrainz для ID та альтернативних метаданих.
Графіки
MVP з плеєром, бібліотекою та Lock Screen Controls: 4–6 тижнів. Повнофункціональний стріміинг-сервіс з offline, еквалайзером, рекомендаціями та ліцензійним DRM: 3–5 місяців. Вартість розраховується індивідуально після аналізу вимог.







