Реалізація фонового відтворення аудіо в мобільному додатку
Дзвінок від клієнта: «Музика зупиняється, як тільки блокую екран». Це типова проблема, з якою стикаються багато розробників. Фонове відтворення аудіо — одна з найчастіших технічних складнощів у мобільній розробці. Помилки в конфігурації AVAudioSession на iOS або Audio Focus на Android призводять до того, що додаток замовкає при згортанні. Ми реалізували це завдання більше 50 разів і знаємо всі підводні камені. Середній час інтеграції — 3 дні, а економія на налагодженні завдяки готовим шаблонам — до 40% часу. Наші інженери тестують на 10+ реальних пристроях, включаючи старі моделі. Ми підготували перевірені шаблони коду для iOS та Android, які вже використовують у продакшені десятки додатків. Один із них — подкаст-сервіс з мільйонною аудиторією. Типове рішення обходиться на 30–50% дешевше, ніж самостійна розробка.
Як налаштувати AVAudioSession для безперервного відтворення?
Три обов'язкові кроки:
-
Info.plist Background Mode. Додати
UIBackgroundModes→audio. Без цього iOS уб'є аудіо через кілька секунд після переходу в фон. -
AVAudioSession категорія
.playback. Саме ця категорія дозволяє відтворення при заблокованому екрані та у фоні..ambientзамовкає при блокуванні — типова помилка.
func configureAudioSession() { do { let session = AVAudioSession.sharedInstance() try session.setCategory( .playback, mode: .default, options: [.allowBluetooth, .allowAirPlay, .mixWithOthers] ) try session.setActive(true) } catch { print("AudioSession error: \(error)") } } Apple рекомендує також обробляти переривання (документація). Вхідний дзвінок — iOS деактивує AVAudioSession. Після дзвінка потрібно явно відновити сесію:
NotificationCenter.default.addObserver( forName: AVAudioSession.interruptionNotification, object: nil, queue: .main ) { notification in guard let typeValue = notification.userInfo?[AVAudioSessionInterruptionTypeKey] as? UInt, let type = AVAudioSession.InterruptionType(rawValue: typeValue) else { return } switch type { case .began: audioPlayer.pause() case .ended: let shouldResume = (notification.userInfo?[AVAudioSessionInterruptionOptionKey] as? UInt) .flatMap { AVAudioSession.InterruptionOptions(rawValue: $0).contains(.shouldResume) } ?? false if shouldResume { try? AVAudioSession.sharedInstance().setActive(true) audioPlayer.play() } @unknown default: break } } Apple Developer Documentation: AVAudioSession
Додатково — AVAudioSession.routeChangeNotification: якщо навушники відключилися, ставте відтворення на паузу.
Чому важливо обробляти переривання на Android?
На Android фонове відтворення вимагає Foreground Service з типом mediaPlayback. Без Foreground Service Android уб'є процес після кількох хвилин. Починаючи з Android 8 (API 26) це обов'язково.
class AudioPlaybackService : Service() { private lateinit var player: ExoPlayer private lateinit var mediaSession: MediaSessionCompat override fun onCreate() { super.onCreate() player = ExoPlayer.Builder(this).build() val notification = buildMediaNotification() startForeground(NOTIFICATION_ID, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK) mediaSession = MediaSessionCompat(this, "AudioService") mediaSession.setCallback(mediaSessionCallback) mediaSession.isActive = true } } На Android 14+ обов'язково вказувати FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK в маніфесті та в startForeground. Без явного типу — SecurityException.
Audio Focus необхідно запросити перед початком відтворення:
val audioFocusRequest = AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN) .setOnAudioFocusChangeListener { focusChange -> when (focusChange) { AudioManager.AUDIOFOCUS_LOSS -> player.pause() AudioManager.AUDIOFOCUS_LOSS_TRANSIENT -> player.pause() AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK -> player.volume = 0.3f AudioManager.AUDIOFOCUS_GAIN -> { player.volume = 1.0f player.play() } } } .build() val result = audioManager.requestAudioFocus(audioFocusRequest) if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { player.play() } Без правильного Audio Focus інші додатки можуть перекрити звук, а ваш плеєр не відновиться. ExoPlayer обробляє переривання вдвічі швидше стандартного MediaPlayer завдяки вбудованому управлінню фокусом.
Що таке MediaSession і навіщо він потрібен для Lock Screen?
Без MediaSession (Android) або MPRemoteCommandCenter (iOS) управління з Lock Screen та навушників не працює. Налаштування цих компонентів займає близько 30% часу розробки фонового аудіо. На Android MediaNotification.Provider створює сповіщення з кнопками, а MediaSession.Callback обробляє команди. MediaBrowserServiceCompat дозволяє підключати Android Auto. На iOS MPNowPlayingInfoCenter та MPRemoteCommandCenter забезпечують управління; оновлюйте nowPlayingInfo при кожній зміні треку, інакше прогрес-бар буде неточним.
Типові помилки та їх рішення
| Помилка | Причина | Рішення |
|---|---|---|
| Звук пропадає після дзвінка (iOS) | Забутий setActive(true) |
Додати в InterruptionType.ended |
| Сповіщення зникає (Android) | stopForeground(true) видаляє сповіщення |
Використовувати stopForeground(false) при паузі |
| Немає звуку в Bluetooth-навушниках | Не вказані Bluetooth-опції | На iOS: .allowBluetooth, на Android: AudioAttributes USAGE_MEDIA |
| Переривання не обробляється (Android) | Відсутній AudioFocusRequest | Додати запит фокусу перед стартом |
Порівняння підходів iOS та Android
| Параметр | iOS | Android |
|---|---|---|
| Сесія/Фокус | AVAudioSession .playback | AudioFocusRequest |
| Фоновий сервіс | UIBackgroundModes audio | Foreground Service типу mediaPlayback |
| Lock Screen | MPNowPlayingInfoCenter + MPRemoteCommandCenter | MediaSession + MediaNotification.Provider |
| Переривання | AVAudioSession.interruptionNotification | AudioFocusChangeListener |
| Bluetooth | .allowBluetooth | AudioAttributes USAGE_MEDIA |
Що входить у нашу роботу
- Інтеграція аудіо-движка (ExoPlayer, AVAudioSession, Media3)
- Налаштування Background Mode та Foreground Service
- Реалізація Lock Screen controls (прогрес-бар, кнопки управління)
- Обробка системних переривань (дзвінки, навушники)
- Тестування на 10+ реальних пристроях
- Оптимізація під Android Auto / CarPlay (опціонально)
- Документація API та опис інтеграції
Зв'яжіться з нами для попередньої оцінки вашого проекту — ми підберемо оптимальне рішення. Отримайте консультацію щодо термінів та вартості. Замовте інтеграцію з гарантією якості.
Терміни
Стандартне впровадження фонового відтворення з Lock Screen controls займає 2–3 робочих дні. Якщо потрібна підтримка Android Auto або CarPlay, або складний lifecycle з кількома типами контенту — до 5 днів. Вартість розраховується індивідуально та залежить від обсягу робіт.







