Веб-аудио, политика автозапуска и игры

В сентябре 2017 года мы объявили о предстоящем изменении способа обработки звука с помощью политики автозапуска в Chrome. Изменение политики было выпущено в Chrome 66 Stable в мае 2018 года.

После отзывов сообщества разработчиков веб-аудио мы отложили выпуск части политики автозапуска, касающейся веб-аудио, чтобы дать разработчикам больше времени для обновления своих веб-сайтов. Мы также внесли некоторые изменения в реализацию политики веб-аудио, которая уменьшит количество веб-сайтов, которым необходимо корректировать свой код (особенно веб-игр), и, следовательно, обеспечит лучший опыт для наших пользователей.

Это изменение политики теперь планируется внедрить в Chrome 71 в декабре 2018 года .

Что конкретно дает изменение политики?

Автовоспроизведение — это имя, присвоенное фрагменту контента, который воспроизводится сразу после загрузки веб-страницы. Для веб-сайтов, которые должны иметь возможность автоматического воспроизведения своего контента, это изменение предотвратит воспроизведение по умолчанию. В большинстве случаев воспроизведение возобновится, но в других потребуется небольшая корректировка кода. В частности, разработчики должны добавить код, который возобновляет работу содержимого, если пользователь взаимодействует с веб-страницей.

Однако если пользователь попадает на страницу с контентом автозапуска и перешел на эту страницу со страницы того же происхождения, то этот контент никогда не будет заблокирован. Прочтите нашу предыдущую публикацию в блоге о политике автозапуска для получения более подробных примеров .

Кроме того, мы добавили эвристику, позволяющую изучить прошлое поведение пользователей в отношении веб-сайтов, на которых автоматически воспроизводится звук. Мы обнаруживаем, что пользователи регулярно воспроизводят аудио более 7 секунд во время большинства посещений веб-сайта, и включаем автозапуск для этого веб-сайта.

Мы делаем это с помощью индекса, который хранится локально для каждого профиля Chrome на устройстве — он не синхронизируется между устройствами и передается только как часть анонимной пользовательской статистики. Мы называем этот индекс Индексом вовлеченности СМИ (MEI), и вы можете просмотреть его через chrome://media-engagement.

MEI отслеживает, сколько посещений сайта сопровождается воспроизведением звука длительностью более 7 секунд. Мы считаем, что на основе MEI пользователя мы можем понять, ожидает ли пользователь аудио с определенного веб-сайта или нет, и предугадать намерения пользователя в будущем.

Если пользователь часто разрешает домену веб-сайта воспроизводить звук более 7 секунд, то в будущем мы предполагаем, что пользователь ожидает, что этот веб-сайт будет иметь право на автоматическое воспроизведение звука. Поэтому мы предоставляем этому веб-сайту право на автоматическое воспроизведение аудио, не требуя от пользователя взаимодействия с вкладкой из этого домена.

Однако это право не гарантируется на неопределенный срок. Если поведение пользователя меняется – например, останавливается воспроизведение аудио или закрывает вкладку в течение 7 секунд в течение нескольких посещений – мы лишаем веб-сайт права на автозапуск.

Использование HTML-элементов мультимедиа (видео и аудио) и веб-аудио (экземпляры объектов AudioContext, созданных в JavaScript) будет способствовать развитию MEI. При подготовке к внедрению этой политики поведение пользователей в отношении веб-аудио начнет вносить вклад в MEI, начиная с Chrome 70 и более поздних версий. Это гарантирует, что мы уже сможем предугадать желаемое намерение пользователя в отношении автозапуска и веб-сайтов, которые он обычно посещает.

Следует отметить, что iframe может получить право на автоматическое воспроизведение без взаимодействия с пользователем только в том случае, если родительская веб-страница, встраивающая iframe , распространяет это право на данный iframe .

Отсрочка изменений ради поддержки сообщества

Сообщество разработчиков веб-аудио, особенно разработчики веб-игр и разработчики WebRTC этого сообщества, обратили внимание, когда это изменение появилось в канале Chrome Stable.

По отзывам сообщества, это изменение отрицательно повлияет на многие веб-игры и веб-аудио — в частности, многие сайты, которые не были обновлены, больше не будут воспроизводить звук для пользователей. В результате наша команда решила, что стоит отложить это изменение, чтобы дать разработчикам веб-аудио больше времени для обновления своих веб-сайтов.

Кроме того, мы потратили это время на то, чтобы:

  • Серьезно подумайте, было ли это изменение политики лучшим решением или нет.
  • Узнайте, как мы можем помочь уменьшить количество веб-сайтов со звуком, на которые это повлияет.

В первом случае мы в конечном итоге решили, что изменение политики действительно необходимо для улучшения пользовательского опыта для большинства наших пользователей. Подробнее о том, какую проблему решает изменение политики, можно прочитать в следующем разделе этой статьи.

Что касается последнего, мы внесли коррективы в нашу реализацию веб-аудио, которая уменьшит количество первоначально затронутых веб-сайтов. Из известных нам сайтов, которые были повреждены в результате изменения (многие из которых были приведены в качестве примеров сообществом разработчиков веб-игр), эта корректировка означала, что более 80% из них будут работать автоматически. Наш анализ и тестирование этих примеров сайтов можно посмотреть здесь . Более подробно эта новая настройка описана ниже.

Мы также внесли изменения для поддержки приложений WebRTC; пока идет активный сеанс захвата, автовоспроизведение будет разрешено.

Какую проблему призвано решить такое изменение поведения?

Браузеры исторически плохо помогали пользователю управлять звуком. Когда пользователи открывают веб-страницу и получают звук, которого они не ожидали или не хотели, у них плохой пользовательский опыт. Этот плохой пользовательский опыт — проблема, которую мы пытаемся решить. Нежелательный шум — основная причина, по которой пользователи не хотят, чтобы их браузер автоматически воспроизводил контент.

Однако иногда пользователи хотят, чтобы контент воспроизводился автоматически, и впоследствии пользователь воспроизводит значительное количество заблокированных автозапусков в Chrome.

Поэтому мы считаем, что, учась у пользователя и предвидя его намерения для каждого веб-сайта, мы сможем создать лучший пользовательский опыт. Если пользователи склонны разрешать воспроизведение контента с веб-сайта, в будущем мы будем автоматически воспроизводить контент с этого сайта. И наоборот, если пользователи склонны прекращать автоматическое воспроизведение контента с определенного веб-сайта, мы по умолчанию запретим автозапуск этого контента.

Одним из предложений, выдвинутых сообществом, было отключить звук на вкладке вместо приостановки автозапуска. Однако мы считаем, что лучше остановить автозапуск, чтобы веб-сайт знал, что автозапуск заблокирован, и позволить разработчику веб-сайта отреагировать на это. Например, хотя некоторые разработчики могут захотеть просто отключить звук, другие разработчики могут предпочесть, чтобы их аудиоконтент был приостановлен до тех пор, пока пользователь не начнет активно с ним работать — в противном случае пользователь может пропустить часть звукового опыта.

Новые изменения в помощь разработчикам веб-игр

Наиболее распространенный способ использования API веб-аудио разработчиками — создание двух типов объектов для воспроизведения аудио:

Разработчики веб-аудио создадут AudioContext для воспроизведения аудио. Чтобы возобновить воспроизведение звука после того, как политика автозапуска автоматически приостановила их AudioContext, им необходимо вызвать функцию возобновления() для этого объекта после того, как пользователь взаимодействует с вкладкой:

    const context = new AudioContext();

    // Setup an audio graph with AudioNodes and schedule playback.
    ...

    // Resume AudioContext playback when user clicks a button on the page.
    document.querySelector('button').addEventListener('click', function() {
      context.resume().then(() => {
        console.log('AudioContext playback resumed successfully');
      });
    });

Существует множество интерфейсов, наследуемых от AudioNode, одним из которых является интерфейс AudioScheduledSourceNode . AudioNodes, реализующие интерфейс AudioScheduledSourceNode, обычно называются исходными узлами (например, AudioBufferSourceNode, ConstantSourceNode и OscillatorNode). Исходные узлы реализуют метод start().

Исходные узлы обычно представляют собой отдельные аудиофрагменты, которые воспроизводятся в играх, например: звук, который воспроизводится, когда игрок собирает монету, или фоновую музыку, которая играет на текущем этапе. Разработчики игр, скорее всего, будут вызывать функцию start() на исходных узлах всякий раз, когда какой-либо из этих звуков необходим для игры.

Как только мы осознали эту распространенную закономерность в веб-играх, мы решили скорректировать нашу реализацию следующим образом:

Аудиоконтекст будет возобновлен автоматически при выполнении двух условий:

  • Пользователь взаимодействовал со страницей.
  • Вызывается метод start() исходного узла.

Благодаря этому изменению звук в большинстве веб-игр теперь возобновляется, когда пользователь начинает играть в игру.

Движение Интернета вперед

Чтобы продвинуть веб-платформу вперед, иногда необходимо внести изменения, которые могут нарушить совместимость. К сожалению, автовоспроизведение аудио является сложным процессом и попадает в эту категорию изменений. Но этот сдвиг имеет решающее значение для того, чтобы Интернет не застоялся и не потерял своего инновационного преимущества.

Тем не менее, мы понимаем, что применение исправлений для веб-сайтов не всегда осуществимо в краткосрочной перспективе по ряду причин:

  • Веб-разработчики могут быть сосредоточены на новом проекте, а обслуживание старого веб-сайта невозможно сразу.
  • Порталы веб-игр могут не иметь контроля над внедрением игр в свой каталог, а обновление сотен – если не тысяч – игр может отнимать много времени и дорого для издателей.
  • Некоторые веб-сайты могут быть просто очень старыми и по той или иной причине больше не поддерживаются, но все еще размещаются для исторических целей.

Вот короткий фрагмент кода JavaScript, который перехватывает создание новых объектов AudioContext и автоматически запускает функцию возобновления этих объектов, когда пользователь выполняет различные взаимодействия с пользователем. Этот код должен выполняться до создания любых объектов AudioContext на вашей веб-странице. Например, вы можете добавить этот код в тег вашей веб-страницы:

(function () {
  // An array of all contexts to resume on the page
  const audioContextList = [];

  // An array of various user interaction events we should listen for
  const userInputEventNames = [
    'click',
    'contextmenu',
    'auxclick',
    'dblclick',
    'mousedown',
    'mouseup',
    'pointerup',
    'touchend',
    'keydown',
    'keyup',
  ];

  // A proxy object to intercept AudioContexts and
  // add them to the array for tracking and resuming later
  self.AudioContext = new Proxy(self.AudioContext, {
    construct(target, args) {
      const result = new target(...args);
      audioContextList.push(result);
      return result;
    },
  });

  // To resume all AudioContexts being tracked
  function resumeAllContexts(event) {
    let count = 0;

    audioContextList.forEach(context => {
      if (context.state !== 'running') {
        context.resume();
      } else {
        count++;
      }
    });

    // If all the AudioContexts have now resumed then we
    // unbind all the event listeners from the page to prevent
    // unnecessary resume attempts
    if (count == audioContextList.length) {
      userInputEventNames.forEach(eventName => {
        document.removeEventListener(eventName, resumeAllContexts);
      });
    }
  }

  // We bind the resume function for each user interaction
  // event on the page
  userInputEventNames.forEach(eventName => {
    document.addEventListener(eventName, resumeAllContexts);
  });
})();

Следует отметить, что этот фрагмент кода не поможет возобновить аудиоконтексты, экземпляры которых создаются внутри iframe, если только этот фрагмент кода не включен в область содержимого самого iframe.

Лучше обслуживать наших пользователей

В дополнение к изменению политики мы также вводим механизм, позволяющий пользователям отключать политику автозапуска, чтобы охватить случаи, когда автоматическое обучение не работает должным образом, или для веб-сайтов, которые из-за изменения стали непригодными для использования. Это изменение будет реализовано вместе с новой политикой в ​​Chrome 71, и его можно найти в настройках звука; сайты, которым пользователь хочет разрешить автозапуск, можно добавить в список разрешенных.

Как устроен MEI для новых пользователей?

Как упоминалось ранее, мы автоматически создаем MEI с течением времени на основе поведения пользователя, чтобы предугадать его желаемое намерение в отношении данного веб-сайта с автоматическим воспроизведением контента. Каждый веб-сайт имеет оценку от нуля до единицы в этом индексе. Более высокие оценки указывают на то, что пользователь ожидает воспроизведения контента с этого веб-сайта.

Однако для новых профилей пользователей или если пользователь очищает свои данные просмотра, вместо того, чтобы везде блокировать автозапуск, для определения того, какие веб-сайты могут автоматически воспроизводиться, используется список предварительного заполнения, основанный на анонимизированных совокупных показателях MEI пользователей. Эти данные определяют только исходное состояние MEI при создании профиля пользователя. Когда пользователь просматривает Интернет и взаимодействует с веб-сайтами с автоматически воспроизводимым контентом, его личный MEI переопределяет конфигурацию по умолчанию.

Предварительно заполненный список сайтов генерируется алгоритмически, а не курируется вручную, и в него может быть включен любой веб-сайт. Сайты добавляются в список, если достаточное количество пользователей, посещающих этот сайт, разрешают автозапуск на этом сайте. Этот порог основан на процентах, чтобы не отдавать предпочтение более крупным сайтам.

Поиск баланса

Мы опубликовали новую документацию, чтобы лучше понять наш процесс принятия решений и обоснование этой политики. А также новая документация о том , как работает предварительно заполненный список сайтов .

Мы всегда ставим наших пользователей на первое место, но мы также не хотим подводить сообщество веб-разработчиков. Иногда быть браузером означает, что эти две цели должны быть тщательно сбалансированы. Мы полагаем, что благодаря нашим корректировкам реализации политики и дополнительному времени, которое мы предоставили разработчикам веб-аудио для обновления своего кода, мы достигнем этого баланса с Chrome 71.

Обратная связь