Раньше, когда деревья были большими, а веб был с градиентными кнопочками, на сайтах любили впилить рекламные видео, которые автоматически запускались с громким звуком. И вместо того чтобы приятно провести время или найти нужную информацию, приходилось судорожно искать источник этого звука.
Это негативно сказывалось на пользовательском опыте, и в какой-то момент разработчики браузеров решили, что хватит это терпеть.
Итак, давайте поговорим, что это такое и какие палки и колёса мы можем встретить.
По сути, Autoplay Policy ограничивает автовоспроизведение видео со звуком, но не всегда. Есть ряд условий, при выполнении одного из которых браузер всё же разрешает воспроизвести видео со звуком, а именно:
Превышение порога индекса вовлечённости означает, что:
и даже не этого парня с громом и молниями:
А что, если нам нужно реализовать веб-приложение с лентой видео? И лента бесконечная, видео в ней воспроизводятся автоматически при свайпе пользователя. Такое поведение очень похоже на поведение привычных нам приложений социальных сетей. И вот тут как раз появляются те самые палки и колёса, на которых работает наша лента.
Обычно базовой реализацией является что-то типа:
tryPlay() {
// метод play возвращает promise
this.video.play()
.then(() => {
// скрываем кнопку плей, видео удалось воспроизвести
})
.catch(() => {
// не удалось воспроизвести видео
const retry = !this.video.muted;
// выключаем звук
this.video.muted = true;
this.video.volume = 0;
// пробуем воспроизвести еще раз
retry && this.tryPlay();
});
}
Если внимательно посмотреть на пример реализации, можно заметить, что даже без звука видео может не запуститься. Да, такой сценарий возможен, но об этом позже.
tryPlay() {
// метод play возвращает promise
this.video.play()
.then(() => {
// скрываем кнопку плей, видео удалось воспроизвести
})
.catch(() => {});
}
Обратите внимание, что лучше не опускать вызов catch, потому что Firefox может выбросить исключение при попытке воспроизведения видео без переданного обработчика ошибок.
С этим вроде бы разобрались. Первым ограничением кажется, что видео нужно воспроизводить при действии пользователя. Это просто: просим пользователя при открытии ленты один раз совершить это действие. Например, показываем ему большую кнопку “Play”.
После того как пользователь нажмёт на эту кнопку… Внимание!
Видео воспроизвелось со звуком. И мы радостно реализовываем всю остальную логику, делаем красивый UI, Pixel Perfect по макету, любезно предоставленному талантливыми дизайнерами, прикручиваем свайп к следующим постам. И вроде бы всё классно, но… Решаем проверить свою реализацию на разных устройствах и браузерах. Берём среднестатистический смартфон, воспроизводим первое видео, свайпаем к следующему посту — и… Тадам!
Видео не воспроизвелось.
Подключаем шнур к устройству, открываем отладчик — и видим, что браузер такой:
Итак, мы знаем: чтобы автоматически воспроизвести видео со звуком, нам требуются как минимум одно действие пользователя и один тег <video />. Но нам никто не запрещал воспроизводить в рамках этого <video /> разные ролики, меняя src как нам вздумается.
Всё, что нам нужно, — это вынести <video /> из поста, сделать его уникальным на странице и при изменении видимости поста делать что-то типа этого:
changeVideoSrc(src: string) {
this.video.src = '';
this.video.load();
setTimeout(() => {
this.video.src = src;
}, 50);
}
Перед тем как изменить src у video, для некоторых браузеров (например Safari и браузеры под iOS), сначала нужно:
Но это позволит лишь частично сохранить пользовательский опыт. В чём же нюанс? Так как тег <video /> у нас теперь один на странице, то при свайпе постов нам нужно дать пользователю понять, что видео свайпается за его действием. Это позволит дать пользователю ощущение реального перемещения поста. Создать ещё один тег <video /> мы не можем, потому что в этом случае потеряем автоплей. Но так ли нам нужно свайпать в посте именно видео? Наверное, если пользователь решил смахнуть текущий пост, то этот контент ему уже неинтересен. Поэтому в базовом варианте можно сделать такое допущение — и в ответ на касание пользователя рисовать в посте обложку, например с первым кадром из видео.
Можно прийти к выводу, что задача решена — с неплохо сохранённым пользовательским опытом.
И да, я в самом начале упоминал сценарий, когда браузер не разрешит автоплей видео даже без звука. Такое поведение свойственно iOS в режиме энергосбережения. В этом режиме браузер обязательно потребует действия пользователя — без него воспроизвести видео не получится.
Преисполниться в автоплей можно с помощью этой доки.
Это негативно сказывалось на пользовательском опыте, и в какой-то момент разработчики браузеров решили, что хватит это терпеть.
В результате появилась Autoplay Policy
Как понятно из названия, это политика автовоспроизведения видео в браузере. Инициатором её введения стал Chrome (с v.66), и на текущий момент эту политику поддержали все современные браузеры.Итак, давайте поговорим, что это такое и какие палки и колёса мы можем встретить.
По сути, Autoplay Policy ограничивает автовоспроизведение видео со звуком, но не всегда. Есть ряд условий, при выполнении одного из которых браузер всё же разрешает воспроизвести видео со звуком, а именно:
- Пользователь взаимодействует с доменом. Это может быть клик, например по кнопке “Play”.
- Индекс вовлечённости домена, на котором располагается приложение, превышает пороговое значение.
- Пользователь добавляет веб-приложение на главный экран (в случае с PWA).
Превышение порога индекса вовлечённости означает, что:
- Пользователь ранее смотрел видео на этом домене со звуком (чем больше, тем лучше).
- Продолжительность просмотра пользователем видео превышает n секунд (для Chrome n = 7).
- Вкладка открыта в момент попытки воспроизведения.
- Видео достаточно большое по размеру (для Chrome — от 200×140px).
и даже не этого парня с громом и молниями:
А что, если нам нужно реализовать веб-приложение с лентой видео? И лента бесконечная, видео в ней воспроизводятся автоматически при свайпе пользователя. Такое поведение очень похоже на поведение привычных нам приложений социальных сетей. И вот тут как раз появляются те самые палки и колёса, на которых работает наша лента.
Обычно базовой реализацией является что-то типа:
tryPlay() {
// метод play возвращает promise
this.video.play()
.then(() => {
// скрываем кнопку плей, видео удалось воспроизвести
})
.catch(() => {
// не удалось воспроизвести видео
const retry = !this.video.muted;
// выключаем звук
this.video.muted = true;
this.video.volume = 0;
// пробуем воспроизвести еще раз
retry && this.tryPlay();
});
}
Если внимательно посмотреть на пример реализации, можно заметить, что даже без звука видео может не запуститься. Да, такой сценарий возможен, но об этом позже.
Автоплей не пройдёт
Итак, давайте подумаем, как можно реализовать ленту в условиях Autoplay Policy. Что у нас есть?- n карточек с видео (дальше будем называть их постами).
- Видео в каждом посте нужно воспроизводить со звуком при отображении поста на экране.
tryPlay() {
// метод play возвращает promise
this.video.play()
.then(() => {
// скрываем кнопку плей, видео удалось воспроизвести
})
.catch(() => {});
}
Обратите внимание, что лучше не опускать вызов catch, потому что Firefox может выбросить исключение при попытке воспроизведения видео без переданного обработчика ошибок.
С этим вроде бы разобрались. Первым ограничением кажется, что видео нужно воспроизводить при действии пользователя. Это просто: просим пользователя при открытии ленты один раз совершить это действие. Например, показываем ему большую кнопку “Play”.
После того как пользователь нажмёт на эту кнопку… Внимание!
Видео воспроизвелось со звуком. И мы радостно реализовываем всю остальную логику, делаем красивый UI, Pixel Perfect по макету, любезно предоставленному талантливыми дизайнерами, прикручиваем свайп к следующим постам. И вроде бы всё классно, но… Решаем проверить свою реализацию на разных устройствах и браузерах. Берём среднестатистический смартфон, воспроизводим первое видео, свайпаем к следующему посту — и… Тадам!
Видео не воспроизвелось.
Подключаем шнур к устройству, открываем отладчик — и видим, что браузер такой:
«Слушай, а ты же совершил действие с другим <video />, так не пойдёт, давай ты на этом его повторишь».
Выхода нет?
Что же с этим можно сделать? Ведь постов у нас много, и хотелось бы сохранить привычное для пользователя поведение. Выходов на самом деле несколько.Пользовательский опыт? Не, не слышал
Можно пожертвовать пользовательским опытом (что не хорошо) — и на каждом неуспешно воспроизведённом посте рисовать кнопку “Play” и надеяться, что пользователь не забьёт и посмотрит больше двух-трёх видео в ленте.Спасти UX полностью (ну почти)
На мой взгляд, есть лучшее решение, которое позволит частично сохранить пользовательский опыт.Итак, мы знаем: чтобы автоматически воспроизвести видео со звуком, нам требуются как минимум одно действие пользователя и один тег <video />. Но нам никто не запрещал воспроизводить в рамках этого <video /> разные ролики, меняя src как нам вздумается.
Всё, что нам нужно, — это вынести <video /> из поста, сделать его уникальным на странице и при изменении видимости поста делать что-то типа этого:
changeVideoSrc(src: string) {
this.video.src = '';
this.video.load();
setTimeout(() => {
this.video.src = src;
}, 50);
}
Перед тем как изменить src у video, для некоторых браузеров (например Safari и браузеры под iOS), сначала нужно:
- Сбросить текущее видео.
- Вызвать метод load, чтобы остановить загрузку текущего видео и сбросить то, что уже загружено.
- С небольшой задержкой заменить видео на новое (задержка нужна, чтобы браузер успел сбросить метаинформацию).
Но это позволит лишь частично сохранить пользовательский опыт. В чём же нюанс? Так как тег <video /> у нас теперь один на странице, то при свайпе постов нам нужно дать пользователю понять, что видео свайпается за его действием. Это позволит дать пользователю ощущение реального перемещения поста. Создать ещё один тег <video /> мы не можем, потому что в этом случае потеряем автоплей. Но так ли нам нужно свайпать в посте именно видео? Наверное, если пользователь решил смахнуть текущий пост, то этот контент ему уже неинтересен. Поэтому в базовом варианте можно сделать такое допущение — и в ответ на касание пользователя рисовать в посте обложку, например с первым кадром из видео.
Можно прийти к выводу, что задача решена — с неплохо сохранённым пользовательским опытом.
И да, я в самом начале упоминал сценарий, когда браузер не разрешит автоплей видео даже без звука. Такое поведение свойственно iOS в режиме энергосбережения. В этом режиме браузер обязательно потребует действия пользователя — без него воспроизвести видео не получится.
Преисполниться в автоплей можно с помощью этой доки.
Видео в вебе, Browser Policy и палки в колёсах
Раньше, когда деревья были большими, а веб был с градиентными кнопочками, на сайтах любили впилить рекламные видео, которые автоматически запускались с громким звуком. И вместо того чтобы приятно...
habr.com