Содержание статьи +
- Кратко
- Зачем это вам
- Одно правило, которое надо принять сразу
- Три поверхности воспроизведения
- Поверхность 1 – нативный HLS в мобильном Safari
- Поверхность 2 – Managed Media Source для элемента `<video>`
- Поверхность 3 – AVPlayer в нативном iOS-приложении
- Матрица форматов и DRM в 2026 году
- Распространённая ошибка – относиться к iOS как к «цели полифилла»
- Где это пересекается с Фора Софт
- Ключевые выводы
- Что читать дальше
Кратко
На любой платформе, кроме iOS, вы можете подключить собственный движок воспроизведения видео – на iOS нельзя, потому что Apple требует, чтобы декодирование шло через системные фреймворки независимо от того, выполняется ли ваш код в Safari, в WKWebView внутри стороннего приложения или в нативном приложении на AVFoundation. «Родной» плеер на iOS – это не одна, а три уровневых поверхности: AVPlayer внутри нативного приложения (полный контроль, полный FairPlay, полный набор «телевизорных» возможностей), элемент <video> в мобильном Safari (нативный HTTP Live Streaming, сокращённо HLS, с несколькими болезненными нюансами атрибутов) и сравнительно молодой Managed Media Source API, который Apple выпустила в Safari 17.1 в ноябре 2023 года, чтобы дать библиотекам вроде hls.js путь к воспроизведению не-HLS источников на iPhone. Статья последовательно разбирает все три поверхности, что они умеют и чего не умеют в 2026 году, в чём они расходятся с остальной веб-платформой (autoplay, inline-воспроизведение, Low-Latency HLS, MPEG-DASH, Widevine) и какую из них на самом деле стоит выбрать вашему продукту. К статье прилагается одностраничный чек-лист подводных камней.
Зачем это вам
Если ваш продукт отдаёт видео на телефон, планшет, MacBook, Apple TV или экран CarPlay, обойти медиастек Apple не получится – каждый байт декодированного видео на современном устройстве Apple проходит через системные фреймворки, и задача вашего приложения – выбрать, какая из трёх публичных поверхностей будет разговаривать с этими фреймворками от вашего имени. Неправильный выбор делает всю остальную потоковую архитектуру тяжелее, чем нужно: вы отдаёте манифесты MPEG-DASH, которые ни один пользователь iPhone Safari не может воспроизвести; тратите спринт на баг автовоспроизведения, который оказывается отсутствующим HTML-атрибутом; реализуете Widevine DRM и обнаруживаете, что ни один клиент с iPad не может посмотреть ни одного защищённого тайтла; ставите цель «пол-секунды задержки в прямом эфире» и видите, что iOS Safari отказывается её обеспечивать без авторского Apple-профиля Low-Latency HLS. Эта статья даёт вам структурную картину – что работает на какой поверхности, что поверхность разрешает, что запрещает – чтобы продуктовое и архитектурное решения принимались одновременно, с первого захода, без дорогой переделки специально под iOS за два релиза до запуска.
Одно правило, которое надо принять сразу
Прежде чем двигаться дальше, примите одно правило: на iOS и iPadOS декодированием видео занимается система, а не ваше приложение. Требование App Store и правила Web Content Filter в WebKit это закрепляют – каждый браузер, поставляемый в App Store, кто бы его ни сделал, исторически использовал внутри WebKit. Это значит, что Chrome для iOS, Firefox для iOS, Edge для iOS и каждый другой «браузер», который вы можете установить из App Store, – это WebKit-на-iOS в чужой обёртке. Закон ЕС Digital Markets Act, сокращённо DMA, в iOS 17.4 приоткрыл узкую дверь альтернативным движкам внутри Евросоюза, но к концу 2025 года ни один коммерческий браузер на iOS не вышел с движком, отличным от WebKit (Open Web Advocacy, Apple's Browser Engine Ban Persists Even Under the DMA, 2025). На практике в 2026 году планировать стоит так: WebKit на iOS – везде.
Архитектурное следствие большое. Вы не сможете поставить libwebrtc в iOS Safari. Вы не сможете декодировать AV1 на любом iPhone, просто поставив JavaScript-декодер AV1 – вы получите то, что поддерживает железо перед вами. Вы не сможете комбинировать декодеры так, как на Linux на десктопе. У вас есть три публичных способа попросить систему воспроизвести видео – и оставшаяся часть статьи каталогизирует их.
Три поверхности воспроизведения
Эти три поверхности соответствуют трём программным слоям, которые устройство Apple предоставляет вашему коду. Первая поверхность – HTML-элемент <video> в мобильном Safari. Вторая поверхность – Managed Media Source API, доступный из того же <video>-элемента, но только на iOS 17.1 и новее, который позволяет JavaScript-библиотеке кормить сегменты побайтно вместо указания на URL. Третья поверхность – AVPlayer внутри нативного приложения для iOS / iPadOS / tvOS, написанного на Swift или Objective-C; это единственная поверхность, которая раскрывает полную системную функциональность – picture-in-picture от ОС, FairPlay DRM с аппаратно-защищённым ключевым путём, Spatial Audio, интеграцию с экраном блокировки и с AirPlay. Выберите одну до того, как сядете писать архитектурный документ.
Дальше статья последовательно идёт по трём поверхностям, а в конце собирает их обратно в решающее правило.
Поверхность 1 – нативный HLS в мобильном Safari
Первая поверхность – та, которую Apple ожидает увидеть на большинстве сайтов, и одновременно самая простая в реализации: напишите стандартный HTML-элемент <video>, укажите в атрибуте src URL манифеста HTTP Live Streaming (маленький текстовый файл с расширением .m3u8, перечисляющий доступные качества и сегменты), и пусть Safari делает остальное. Это путь, под который Apple оптимизировала браузер шестнадцать лет назад, выпустив в 2009 году первую версию HLS; путь, описанный в HLS Authoring Specification for Apple Devices (регулярно обновляется; на момент написания актуальна редакция от сентября 2025 года); и путь с самым низким расходом батареи из трёх, потому что конвейер воспроизведения не выходит за пределы декодера, демультиплексора и контроллера адаптивного битрейта самой Apple.
Механизм виден JavaScript через метод canPlayType на video-элементе. Вызов video.canPlayType('application/vnd.apple.mpegurl') в современном мобильном Safari возвращает "maybe" или "probably" – стандартный межбраузерный сигнал, что движок примет формат. Внутри собственных приложений Apple путь тот же: HLS-URL передаётся AVPlayer; декодер под капотом один и тот же.
Цена за «Safari всё делает сам» – отказ от четырёх вещей, к которым веб-разработчики привыкли на любой другой платформе. Первая – алгоритм выбора варианта качества: Safari запускает фирменную Apple-логику адаптивного битрейта, переопределить её нельзя, и выбор следующего рендишена делает код внутри ОС, на который вы можете повлиять только подсказками уровня плейлиста – атрибутами VIDEO-RANGE, RESOLUTION и BANDWIDTH в мастер-плейлисте. Вторая – тонкая телеметрия: вы получаете стандартные HTML5 media-события (loadedmetadata, playing, waiting, stalled, ended, error) и AirPlay-событие webkit-playback-target-availability-changed, но не получаете хук на каждую загрузку сегмента, как в hls.js, и поверхность метрик, которую можно навесить на Mux Data или Conviva, уже. Третья – покрытие форматов: нативный Safari проигрывает HLS – и только HLS; он не проигрывает DASH (MPEG Dynamic Adaptive Streaming over HTTP), не проигрывает прогрессивный WebM, а <video src="manifest.mpd"> просто не загружается. Четвёртая – шифрование: единственный web-DRM Safari – FairPlay Streaming, применяемый к HLS-контенту через тег EXT-X-KEY в плейлисте с методом ключа com.apple.streamingkeydelivery`. Widevine в Safari нет – ни на iOS, ни где-либо ещё; PlayReady тоже нет. Если ваш каталог мульти-DRM, на iOS у вас FairPlay.
Два из четырёх ограничений – собственный ABR Apple и FairPlay как единственный DRM – это политические решения, с которыми остальная индустрия научилась жить, потому что в комплекте идут реальные плюсы: эффективное энергопотребление, picture-in-picture, AirPlay 2 на Apple TV, Spatial Audio и весь стек доступности iOS, включая дружественные к VoiceOver субтитры и аудиоописания. Два других – узкая телеметрия и поддержка только HLS – это причина, по которой существует вторая поверхность.
Обрыв атрибутов воспроизведения
Есть класс багов, который каждая команда узнаёт через продакшен: видео, которое воспроизводится в Safari Simulator на маке и на тестовом iPhone, отказывается автозапускаться muted-inline на реальном iPhone у пользователя. Причина – один из трёх HTML-атрибутов, которые остальной веб воспринимает как рекомендацию, а мобильный Safari – как жёсткое условие.
playsinline – первый. Без него iPhone-Safari-видео по умолчанию уходит в полноэкранный режим в момент нажатия на play – страница исчезает, систему берёт на себя ОС, и любые кастомные контролы или оверлеи, которые дизайнер придумал вокруг видео, пропадают. Добавление <video playsinline> (или просто boolean-атрибут без значения в современном HTML) возвращает поведение в-странице, к которому веб привык по умолчанию (WebKit Blog, New <video> Policies for iOS, 2016). На iPadOS Safari и macOS Safari атрибут не нужен – там переход в полноэкранный режим всегда был opt-in; атрибут специфичен для iPhone.
muted – второй. iOS Safari отказывается автозапускать любое видео со звуком, если звук не отключён на уровне элемента, какой бы user-gesture API вы ни вызвали. Поэтому <video autoplay muted playsinline> – каноничный рецепт для hero-видео на маркетинговой странице. Если живой пользователь кликает Play, он может включить звук; muted-on-load – стартовое условие, которое Safari требует, прежде чем play() разрешится без исключения.
preload="auto" – третий, и это барьер производительности, а не корректности. iPhone Safari жёстко лимитирует preload-запросы на мобильной сети, поэтому даже если на элементе стоит preload="auto", браузер может загрузить только первый сегмент, пока пользователь не нажал Play. Для пользователя это правильно – экономит трафик, – но удивляет команды, которые профилируют видео по Wi-Fi, видят быстрый старт и релизятся, не протестировав на лимитированном соединении.
Четвёртая особенность: дочерний элемент <source> – правильный способ указать HLS-URL, когда нужен fallback на MP4 для не-Safari-браузеров. Конструкция <source src="movie.m3u8" type="application/vnd.apple.mpegurl"> плюс <source src="movie.mp4" type="video/mp4"> позволяет браузеру выбрать формат, который он понимает. Если положить HLS-URL прямо в атрибут <video src>, в Safari работает, но не-Safari-браузер не пропускает отсутствующий MP4-fallback так же.
Low-Latency HLS в iOS Safari
Apple представила Low-Latency HLS – в индустрии его называют LL-HLS – в 2019 году, а в редакции HLS Authoring Specification от сентября 2023 года тихо убрала требование HTTP/2 server push (Apple, HLS Authoring Specification for Apple Devices, редакция 2025-09). В мобильном Safari LL-HLS-приёмник встроен в тот же элемент <video>, которым вы уже пользуетесь; opt-in не нужен. Если в манифесте есть теги EXT-X-SERVER-CONTROL, EXT-X-PART, EXT-X-PRELOAD-HINT и EXT-X-RENDITION-REPORT, а медиа поддерживает частичные сегменты, плеер iPhone будет тянуть части и попадать в цель «менее трёх секунд glass-to-glass» в хорошей сети. Если манифест обычный HLS, плеер работает с целью пятнадцать – тридцать секунд. Это единственный путь к sub-3-секундному live на iPhone Safari без нативного приложения – Safari отказывается давать строительные блоки для написания собственного low-latency приёмника на JavaScript, потому что Managed Media Source (следующая поверхность) для этого профиля пока не подходит.
Поверхность 2 – Managed Media Source для элемента `<video>`
Вторая поверхность – Managed Media Source API, сокращённо MMS, которую Apple выпустила в Safari 17.1 в ноябре 2023 года на iPhone после многих лет отказа от Media Source Extensions, использовавшегося остальным вебом с 2013 года (Apple, Safari 17.1 Release Notes, ноябрь 2023; Bitmovin, Apple's New Managed Media Source, 2023). Поверхность MMS даёт JavaScript-библиотекам путь скармливать байты сегментов в элемент <video> вместо указания URL – тот самый строительный блок, которым hls.js, Shaka Player, dash.js и Video.js пользуются на каждом современном браузере уже десять лет, теперь наконец на iPhone.
В поверхности MMS важно понять две вещи. Первая – зачем она: впервые на iPhone можно проигрывать не-HLS-источники – манифесты DASH, прогрессивный fragmented-MP4 и любой формат, который библиотека умеет демультиплексировать в CMAF-chunk. Вторая – что она такое: вариант Media Source Extensions, сокращённо MSE, с двумя структурными отличиями и управлением питанием. MMS позволяет операционной системе сообщить JavaScript, когда нужно сбавить обороты – когда устройство на мобильной сети, когда экран заблокирован, когда пользователь переключился на другую вкладку – через новое свойство MediaSource.streaming и события startstreaming и endstreaming. И MMS держит автоматический eviction source-buffer плотнее, чем MSE, чтобы iPhone Safari не накапливал 60-секундный буфер на iPhone с ограниченной памятью.
Поддержка библиотек подоспела быстро. hls.js – самый популярный HLS-плеер в мире JavaScript с примерно пятью миллионами загрузок в неделю – получил поддержку MMS в конце 2023 года и теперь автоматически определяет MMS-путь на iOS Safari без конфигурации: если window.ManagedMediaSource определён, hls.js предпочтёт его нативному <video src="m3u8"> на том же устройстве (hls.js GitHub, Issue #6161 – hls.js on iOS > 17.1, 2023–2024). Shaka Player добавил такое же определение в 2024 году.
Чего MMS не даёт в 2026 году:
- Не открывает Widevine или PlayReady на iOS Safari. Единственный DRM Safari – по-прежнему FairPlay, применяемый через слой Encrypted Media Extensions (EME), который Safari поддерживает на macOS и теперь распространяет на iOS. Если ваша библиотека скармливает зашифрованный CMAF-источник через MMS, ключевой запрос обслуживается FairPlay-лицензионным сервером с идентификатором key system com.apple.fps, а не Widevine.
- Не даёт LL-HLS в JavaScript. Apple не открыла low-latency-приёмник библиотекам MSE-уровня; LL-HLS на iPhone Safari по-прежнему идёт через нативный <video src="m3u8"> или через AVPlayer в нативном приложении.
- Не даёт WebRTC-стриминга на масштабе. Браузеры без полной поддержки WebRTC – не тема этой статьи; iOS Safari WebRTC поставляет, но тема статьи – media-element-путь, а он только HLS и fMP4.
Практический вывод: если на остальной части веба у вас MPEG-DASH и хочется одной кодовой ветки плеера покрыть iPhone Safari тоже, MMS плюс hls.js или Shaka – путь 2026 года. Если каталог в любом случае только HLS, более старый нативный <video src="m3u8"> остаётся проще, легче для батареи, и большинство команд продолжает использовать его.
Поверхность 3 – AVPlayer в нативном iOS-приложении
Третья поверхность – AVPlayer, системный класс воспроизведения видео внутри фреймворка AVFoundation Apple, который используют собственные приложения Apple (приложение TV, Apple Music, Safari внутри для video-элемента под капотом) и каждое серьёзное стороннее iOS-видео-приложение. AVPlayer – единственная поверхность с полным контролем над конвейером воспроизведения: полный FairPlay через AVContentKeySession, полный picture-in-picture, AirPlay 2 на Apple TV, Spatial Audio, интеграция Top Shelf на Apple TV, Now Playing на экране блокировки и на подключённом экране CarPlay, Background Audio с корректной обработкой iOS audio-session и полностью программируемая стратегия адаптивного битрейта через AVPlayerItem.preferredPeakBitRate и AVPlayerItem.preferredMaximumResolution.
Форма API стабильна уже десять лет. Минимальная настройка AVPlayer на Swift – три строки:
let url = URL(string: "https://example.com/manifest.m3u8")!
let player = AVPlayer(url: url)
let controller = AVPlayerViewController()
controller.player = player
present(controller, animated: true) { player.play() }AVPlayerViewController – системный view controller со стандартной обвязкой плеера (кнопка Play, тайм-слайдер, меню субтитров, выбор маршрута AirPlay). Можно собрать собственные контролы поверх AVPlayerLayer и кастомного UIView – так и делают большинство продакшен-приложений, когда подключается дизайн, – но системный controller – правильная стартовая точка.
Для HLS URL может быть live-манифестом или VOD-манифестом; AVPlayer адаптируется. LL-HLS-приёмник Apple встроила в AVPlayer в 2019 году и шлифовала в iOS 14, 15, 16, 17 и 18; единственная «настройка» – теги в самом манифесте. Для FairPlay-защищённого контента модель – присоединить AVAssetResourceLoaderDelegate (легаси) или, на iOS 11 и новее, AVContentKeySession (современный путь), который обрабатывает ключевой запрос, отправляет его на ваш FairPlay-лицензионный сервер и возвращает Content Key Context, сокращённо CKC, позволяющий декодеру играть сегменты. Сертификат приложения, который Apple выпускает на каждое FairPlay-развёртывание, – единственное, что нужно от системы; всё остальное – ваша серверная часть.
Несколько продакшен-моментов:
WWDC 2025 добавила AVMetrics на путь прогрессивной загрузки и на офлайн-загрузки HLS (Apple, What's New in HTTP Live Streaming, WWDC 2025, июнь 2025). Те же классы AVMetricEvent, что были доступны на HLS, теперь доступны на пути URLSession-загрузки через новый колбэк urlSession:assetDownloadTask:didReceiveMetricEvent: в AVAssetDownloadDelegate. Если ваше приложение делает offline-first видео для образовательной или туристической платформы, ваша QoE-телеметрия теперь покрывает оба пути одной схемой событий.
Picture-in-picture – одна строка. Установка AVPlayerViewController.allowsPictureInPicturePlayback = true – это весь opt-in для PiP на iOS 14 и новее, с одной оговоркой: в Info.plist приложения нужен массив UIBackgroundModes с audio и voip, а на iPhone (в отличие от iPad) пользователь должен включить PiP системно в Settings → General → Picture in Picture. С iOS 17 настройка включена по умолчанию; старые пользователи могли её отключить.
FairPlay – не опция для премиум-каталогов HLS. Если контракты со студиями требуют Widevine L1 на Android и FairPlay на Apple, iOS-приложение – единственный путь поставить FairPlay-половину. Safari тоже играет FairPlay-защищённый HLS через EME com.apple.fps, но процедура выдачи сертификата идентична, и команды премиум-каталогов на платформах Apple предпочитают нативный путь – он же открывает офлайн-загрузки с персистентностью FairPlay-ключей.
Воспроизведение аудио в фоне переживает блокировку экрана. Нативное приложение с UIBackgroundMode=audio и сконфигурированным AVAudioSession продолжает играть звук при блокировке. Safari – нет; пауза-при-блокировке – поведение WebKit по умолчанию для воспроизведения во вкладке. Поэтому подкаст-style продукты ставят нативное приложение, даже когда их видео – HLS, который иначе работал бы в Safari.
Матрица форматов и DRM в 2026 году
Один и тот же контент должен проигрываться на всех трёх поверхностях, если продукт кросс-платформенный. Ниже – что принимает на вход каждая поверхность и чего не принимает.
| Поверхность | HLS | LL-HLS | DASH | Progressive MP4 | FairPlay | Widevine | PlayReady |
|---|---|---|---|---|---|---|---|
| Safari <video src=> (нативный HLS) | да | да | нет | да (не-streaming) | да (EME com.apple.fps) | нет | нет |
| Safari + MMS (hls.js / Shaka) | да | нет, fallback на обычный HLS | да (через библиотеку) | да | да (EME) | нет | нет |
| Нативное приложение, AVPlayer | да | да | нет (нет первой стороны для DASH – есть community-библиотеки) | да | да (AVContentKeySession) | нет | нет |
| Стороннее iOS-приложение через WKWebView | наследует Safari выше | наследует Safari выше | наследует Safari выше | наследует Safari выше | наследует Safari выше | нет | нет |
Из матрицы вытекают два следствия.
Первое, мульти-DRM в режиме шифрования cbcs – единственный способ делить зашифрованный файл между Apple и не-Apple-платформами. ISO/IEC 23001-7 Common Encryption (CENC) определяет два режима – cenc (CTR-mode, AES-128, более старый) и cbcs (CBC-mode subsample, более новый). FairPlay принимает только cbcs; Widevine и PlayReady принимают cbcs с 2018 года. Стандарт 2026 года – поэтому cbcs-зашифрованный CMAF-источник, отдаваемый трём DRM из одного файла, с тремя разными лицензионными серверами (PallyCon, EZDRM, Axinom, BuyDRM, AWS – каждый предлагает это как managed-сервис). Решение по упаковке живёт в статье про CMAF и в подробном разборе FairPlay; решение по плееру – здесь.
Второе, если единственное требование к iOS Safari – «играет HLS», то самый простой плеер – никакого плеера. Голый <video src="manifest.m3u8" controls playsinline> в HTML, с FairPlay через ваш EME-license-колбэк, даёт нативный ABR, нативный LL-HLS, нативный AirPlay, нативный PiP и наименьший расход батареи из трёх поверхностей. К hls.js или Shaka с Managed Media Source имеет смысл тянуться, только когда нужен ещё и DASH или когда нужна более тонкая телеметрия, чем дают нативные HTML5 media-события.
Распространённая ошибка – относиться к iOS как к «цели полифилла»
Самая дорогостоящая архитектурная ошибка, которую мы видим на продуктовых ревью, – относиться к iOS Safari как к платформе, на которую можно «полифиллить» плеер с остального веба. Инстинкт понятен – большинство команд собирают плеер сначала под Chrome и Firefox, где есть MSE и Widevine, а потом спрашивают «что делать с iOS». Неправильный ответ – писать героический shim, который пытается заставить iOS вести себя как остальной веб. Правильный ответ – принять, что три перечисленные выше поверхности – это вся история воспроизведения на iOS, спроектировать архитектуру вокруг того, что они могут, и относиться к остальному вебу как к «расширению», а не наоборот.
Конкретно: собрать мастер-плейлист как HLS с cbcs-шифрованием, упаковать CMAF-сегменты, работающие и для HLS, и для DASH, из одних и тех же зашифрованных файлов, выдавать лицензии FairPlay на платформах Apple и Widevine плюс PlayReady на остальных, направлять Safari прямо на HLS-мастер-плейлист, направлять Android и десктоп-Chrome на DASH-манифест через Shaka или dash.js и ставить нативное iOS-приложение для случаев «FairPlay плюс офлайн», которых требуют студийные контракты. HLS-first архитектура – самый дешёвый проход через политические решения Apple, и она даёт рабочий iOS-плеер в первый день, а не на третьем milestone.
Где это пересекается с Фора Софт
Мы делаем видео-конвейеры для OTT, телемедицины, e-learning, видео-наблюдения и AR/VR клиентов с 2005 года, и поверхность воспроизведения на iOS – часть стека, которую мы рефакторили чаще всего для клиентов, начавших с Android-first. Паттерн повторяется: команда выбирает MPEG-DASH для веба, строит лицензионный сервер только для Widevine, а потом вынуждена добавлять параллельный HLS+FairPlay-путь для iOS-половины аудитории. Мы укладываем каталог на cbcs-зашифрованный CMAF-источник один раз, подключаем FairPlay к iOS-приложению и Widevine+PlayReady ко всему остальному, и один и тот же контент проигрывается везде из одного выхода паковщика. Архитектурная экономия копится на каждом следующем студийном контракте.
Ключевые выводы
- iOS даёт три поверхности воспроизведения – нативный HLS в Safari, Managed Media Source для не-HLS в Safari, AVPlayer в нативном приложении – и четвёртого пути нет.
- Пока вы не отправили комбинацию playsinline плюс muted плюс autoplay, видео в iPhone Safari будет либо отказываться автозапускаться, либо уходить в полноэкранный режим при первом тапе.
- FairPlay – единственный DRM на любой iOS-поверхности; Widevine и PlayReady на iPhone Safari или AVPlayer не работают.
- MPEG-DASH на iPhone Safari требует Managed Media Source плюс библиотеку вроде hls.js или Shaka, доступную на iOS 17.1 и новее.
- LL-HLS на iPhone Safari работает только через нативный <video src="m3u8"> или через AVPlayer; путь Managed Media Source не подходит для low-latency.
- Мульти-DRM в режиме CENC cbcs позволяет одному зашифрованному CMAF-источнику обслуживать FairPlay на Apple и Widevine плюс PlayReady на всём остальном.