Интеграция AVPlayer для видеовоспроизведения в iOS-приложении
AVPlayer — нативный плеер iOS с поддержкой HLS, MPEG-4, progressive download, AirPlay, Picture in Picture и субтитров. Прежде чем использовать сторонние плееры (VLCKit, IJKPlayer), стоит разобраться, что умеет AVPlayer — в большинстве случаев этого достаточно.
Базовая интеграция
AVPlayer сам по себе не отображает видео — он управляет воспроизведением. Для отображения нужен AVPlayerLayer, встроенный в UIView.layer, или AVPlayerViewController из AVKit — готовый контроллер с системными элементами управления.
let player = AVPlayer(url: videoURL)
let playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = containerView.bounds
playerLayer.videoGravity = .resizeAspect
containerView.layer.addSublayer(playerLayer)
player.play()
Для SwiftUI — VideoPlayer из AVKit, обёртка над AVPlayerViewController.
Где появляются проблемы
Буферизация и состояние. player.currentItem?.status не отражает готовность к воспроизведению в реальном времени. Правильный путь — KVO на player.currentItem и timeControlStatus:
player.publisher(for: \.timeControlStatus)
.receive(on: DispatchQueue.main)
.sink { status in
switch status {
case .playing: hideLoader()
case .waitingToPlayAtSpecifiedRate: showLoader()
case .paused: break
}
}
HLS и качество. Для HLS (m3u8) AVPlayer автоматически выбирает поток по пропускной способности. Управлять выбором можно через AVPlayerItem.preferredPeakBitRate (ограничение) или AVPlayerItem.preferredMaximumResolution. Ручной выбор качества — через AVMediaSelectionGroup с AVAssetVariant.
Background playback. Аудиопоток при уходе в фон требует: включённую capability «Background Modes → Audio, AirPlay» в Xcode и AVAudioSession.shared.setCategory(.playback) перед player.play(). Без setCategory аудио обрезается сразу при уходе в фон.
Picture in Picture. AVPictureInPictureController требует AVPlayerLayer или AVPlayerViewController. Добавляем AVPictureInPictureControllerDelegate, в Info.plist — UIBackgroundModes: audio. Включаем pictureInPictureController.startPictureInPicture() по нажатию кнопки. PiP работает только на физических устройствах, не в симуляторе.
Кастомные элементы управления
Если AVPlayerViewController не подходит по дизайну, строим кастомный плеер поверх AVPlayer + AVPlayerLayer:
- Прогресс-бар:
player.addPeriodicTimeObserver(forInterval: CMTime(seconds: 0.5), queue: .main)для обновления позиции - Перемотка:
player.seek(to: CMTime(seconds: targetSeconds, preferredTimescale: 600), toleranceBefore: .zero, toleranceAfter: .zero)—toleranceBefore/After: .zeroдаёт точную позицию, но медленнее - Субтитры:
AVMediaCharacteristic.legible+AVPlayerItem.select(_:in:)для переключения дорожек
Что входит в работу
- Интеграция
AVPlayerсAVPlayerLayerилиAVPlayerViewController - Кастомный UI управления (play/pause, seek bar, fullscreen)
- Background playback и AirPlay
- Picture in Picture (если требуется iOS 14+)
- HLS с возможностью выбора качества
- Обработка ошибок сети и буферизации с retry-логикой
Сроки
Базовый плеер с системными контролами: половина дня. Полностью кастомный плеер с субтитрами, PiP и HLS quality selector: 2–3 дня. Стоимость рассчитывается индивидуально.







