Áudio da Web, política de reprodução automática e jogos

Tom Greenaway
Hangchan Choi

Em setembro de 2017, anunciamos uma mudança futura na forma como o áudio seria tratado com a política de comportamento de reprodução automática no Chrome. A mudança na política foi lançada com o Chrome 66 Stable em maio de 2018.

Após o feedback da comunidade de desenvolvimento de áudio da Web, atrasamos o lançamento da parte de áudio da Web da política de reprodução automática para dar aos desenvolvedores mais tempo para atualizar seus sites. Também fizemos algumas alterações na implementação da política de áudio da web, o que reduzirá o número de sites que precisam ajustar seu código, especialmente jogos da web, e, portanto, proporcionará uma experiência melhor para nossos usuários.

Essa alteração de política está programada para ser lançada no Chrome 71 em dezembro de 2018.

O que a alteração da política faz exatamente?

Reprodução automática é o nome dado a um conteúdo reproduzido imediatamente após o carregamento de uma página da Web. Em sites que podem reproduzir automaticamente o próprio conteúdo, essa mudança impedirá a reprodução por padrão. Na maioria dos casos, a reprodução será retomada, mas, em outros, será necessário fazer um pequeno ajuste no código. Mais especificamente, os desenvolvedores precisam adicionar um código que retoma o conteúdo quando o usuário interage com a página da Web.

No entanto, se o usuário acessar uma página com conteúdo de reprodução automática e acessar essa página a partir de uma página com a mesma origem, esse conteúdo nunca será bloqueado. Leia nossa postagem anterior sobre a política de reprodução automática para ver exemplos mais detalhados.

Além disso, adicionamos uma heurística para aprender com o comportamento anterior dos usuários em relação a sites que reproduzem áudio automaticamente. Detectamos quando os usuários deixam o áudio regularmente por mais de sete segundos durante a maioria das visitas a um site e ativamos a reprodução automática para esse site.

Fazemos isso com um índice armazenado localmente por perfil do Chrome em um dispositivo. Ele não é sincronizado entre os dispositivos e é compartilhado apenas como parte das estatísticas anônimas do usuário. Chamamos esse índice de "Media Engagement Index (MEI)", e ele pode ser visualizado em chrome://media-engagement.

O MEI monitora quantas visitas a um site incluem reprodução de áudio com mais de sete segundos. Com base no MEI de um usuário, acreditamos que podemos entender se um usuário espera áudio de um site específico e antecipar a intenção do usuário no futuro.

Se o usuário muitas vezes permite que o domínio de um site reproduza áudio por mais de sete segundos, presumimos, no futuro, que o usuário espera que o site tenha o direito de reproduzir áudio automaticamente. Portanto, concedemos a esse site o direito de reproduzir áudio automaticamente sem exigir que o usuário interaja com uma guia desse domínio.

No entanto, esse direito não é garantido indefinidamente. Se o comportamento do usuário mudar, por exemplo, parar a reprodução de áudio ou fechar a guia dentro do limite de sete segundos ao longo de várias visitas, removeremos o direito do site de reproduzir automaticamente.

O uso de elementos HTML de mídia (vídeo e áudio) e Web Audio (objetos AudioContext instanciados com JavaScript) contribuirá para o MEI. Como preparação para o lançamento dessa política, o comportamento do usuário em relação ao Web Audio começará a contribuir para o MEI a partir do Chrome 70. Assim, conseguimos prever a intenção do usuário em relação à reprodução automática e aos sites que ele acessa com frequência.

Os iframes só podem ter o direito de reprodução automática sem interação do usuário se a página da Web mãe que incorpora o iframe estendê-lo diretamente para o iframe especificado.

Atrasar a alteração para apoiar a comunidade

A comunidade de desenvolvedores de Web Audio, especialmente os desenvolvedores de jogos da Web e as partes de desenvolvedores WebRTC desta comunidade, notou quando essa mudança apareceu no Canal Stable do Chrome.

O feedback da comunidade foi de que muitas experiências de jogos e áudio na Web seriam afetadas negativamente por essa mudança. Especificamente, muitos sites que não foram atualizados deixaram de reproduzir áudio para os usuários. Por isso, nossa equipe decidiu que valia a pena adiar essa mudança para dar aos desenvolvedores de áudio da Web mais tempo para atualizar os sites.

Além disso, usamos este tempo para:

  • Considere muito se essa mudança na política foi a melhor providência a ser tomada ou não.
  • Conheça maneiras de ajudar a reduzir o número de sites com áudio que seriam afetados.

No primeiro caso, decidimos que a mudança na política é realmente necessária para melhorar a experiência da maioria dos usuários. Leia mais detalhes sobre o problema que a alteração da política está resolvendo na próxima seção deste artigo.

Em relação ao segundo caso, fizemos um ajuste na implementação do áudio da Web, o que reduzirá o número de sites afetados originalmente. Dos sites que conhecíamos que foram corrompidos pela mudança, muitos deles foram fornecidos como exemplos pela comunidade de desenvolvedores de jogos para Web, esse ajuste fez com que mais de 80% deles funcionassem automaticamente. Confira nossa análise e teste destes sites de exemplo aqui. Esse novo ajuste é descrito com mais detalhes abaixo.

Também fizemos uma alteração para oferecer suporte a aplicativos WebRTC. Enquanto houver uma sessão de captura ativa, a reprodução automática será permitida.

Que problema essa mudança de comportamento pretende resolver?

Historicamente, os navegadores têm sido ruins em ajudar o usuário a gerenciar o som. Quando os usuários abrem uma página da Web e recebem sons que não esperavam ou não querem, eles têm uma experiência ruim. Essa experiência do usuário ruim é o problema que estamos tentando resolver. O ruído indesejado é o principal motivo para os usuários não quererem que o navegador reproduza conteúdo automaticamente.

No entanto, às vezes os usuários querem que o conteúdo seja reproduzido automaticamente, e um número significativo de reproduções automáticas bloqueadas no Chrome é reproduzido por eles depois.

Portanto, acreditamos que podemos criar a melhor experiência do usuário ao aprender com o usuário e antecipar a intenção dele em cada site. Se os usuários tendem a permitir que o conteúdo seja reproduzido em um site, nós reproduziremos automaticamente o conteúdo desse site no futuro. Por outro lado, se os usuários tendem a interromper a reprodução automática de um determinado site, impediremos a reprodução automática desse conteúdo por padrão.

Uma proposta da comunidade foi silenciar o áudio de uma guia em vez de pausar a reprodução automática. No entanto, acreditamos que é melhor interromper a experiência de reprodução automática para que o site saiba que ela foi bloqueada e permita que o desenvolvedor reaja a isso. Por exemplo, embora alguns desenvolvedores queiram simplesmente silenciar o áudio, outros podem preferir que o conteúdo de áudio seja pausado até que o usuário interaja ativamente com o conteúdo. Caso contrário, o usuário pode perder parte da experiência de áudio.

Novos ajustes para ajudar os desenvolvedores de jogos da Web

A forma mais comum de os desenvolvedores usarem a API Web Audio é criando dois tipos de objetos para reproduzir áudio:

Os desenvolvedores de áudio da Web vão criar um AudioContext para tocar áudio. Para retomar o áudio depois que a política de reprodução automática suspender automaticamente o AudioContext, ele precisará chamar a função resume() nesse objeto depois que o usuário interagir com a guia:

    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');
      });
    });

Há muitas interfaces que herdam o AudioNode, uma delas é a interface AudioScheduledSourceNode. Os AudioNodes que implementam a interface AudioScheduledSourceNode são normalmente chamados de nós de origem (como AudioBufferSourceNode, ConstantSourceNode e OscillatorNode). Os nós de origem implementam um método start().

Os nós de origem geralmente representam trechos de áudio individuais que os jogos tocam, por exemplo: o som que é reproduzido quando um jogador coleta uma moeda ou a música de fundo que é tocada no estágio atual. É muito provável que os desenvolvedores de jogos chamem a função start() nos nós de origem sempre que algum desses sons for necessário para o jogo.

Depois de reconhecer esse padrão comum em jogos da Web, decidimos ajustar nossa implementação para o seguinte:

Um AudioContext será retomado automaticamente quando duas condições forem atendidas:

  • O usuário interagiu com uma página.
  • O método start() de um nó de origem é chamado.

Devido a essa mudança, a maioria dos jogos da Web retomará o áudio quando o usuário começar a jogar.

Levando a Web adiante

Para levar a plataforma da Web adiante, às vezes é necessário fazer alterações que podem prejudicar a compatibilidade. Infelizmente, a reprodução automática de áudio é complexa e se enquadra nessa categoria de mudança. Mas fazer essa mudança é fundamental para garantir que a web não fique estagnada ou perca seu espírito inovador.

No entanto, reconhecemos que a aplicação de correções para sites nem sempre é viável a curto prazo por vários motivos:

  • Os desenvolvedores da Web podem estar concentrados em um novo projeto e a manutenção de um site mais antigo não é imediatamente possível.
  • Os portais de jogos da Web podem não ter controle sobre a implementação dos jogos em seu catálogo, e atualizar centenas (ou até milhares) de jogos pode ser demorado e caro para os editores.
  • Alguns sites podem ser muito antigos e, por algum motivo, deixaram de ser mantidos, mas ainda são hospedados para fins históricos.

Veja um breve snippet de código JavaScript que intercepta a criação de novos objetos AudioContext e aciona automaticamente a função de retomada desses objetos quando o usuário realiza várias interações com o usuário. Esse código deve ser executado antes da criação de qualquer objeto AudioContext em sua página web – por exemplo, você pode adicionar este código à tag de sua página web:

(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);
  });
})();

Não esqueça que esse snippet de código não ajuda a retomar AudioContexts que são instanciados em um iframe, a menos que esse snippet de código seja incluído no escopo do conteúdo do próprio iframe.

Como atender melhor nossos usuários

Para acompanhar a mudança na política, também estamos lançando um mecanismo que permite que os usuários desativem a política de reprodução automática para cobrir os casos em que o aprendizado automático não funciona como esperado ou para sites que não possam ser usados pela mudança. Essa mudança será lançada com a nova política no Chrome 71 e poderá ser encontrada nas configurações de som. Os sites em que o usuário permitir a reprodução automática podem ser adicionados à lista de permissões.

Como o MEI é criado para novos usuários?

Como mencionado antes, criamos o MEI automaticamente ao longo do tempo com base no comportamento do usuário para antecipar a intenção desejada em relação a um determinado site com conteúdo de reprodução automática. A pontuação de cada site neste índice está entre 0 e 1. Pontuações mais altas indicam que o usuário espera que o conteúdo seja reproduzido nesse site.

No entanto, no caso de perfis de novos usuários ou se um usuário limpar os dados de navegação, em vez de bloquear a reprodução automática em todos os lugares, uma lista de sugestão com base em pontuações de MEI agregadas e anonimizadas será usada para determinar quais sites podem ser reproduzidos automaticamente. Esses dados determinam apenas o estado inicial da MEI na criação do perfil de usuário. À medida que o usuário navega na Web e interage com sites com conteúdo de reprodução automática, a MEI pessoal substitui a configuração padrão.

Essa lista é gerada por algoritmos em vez de selecionada manualmente, e qualquer site está qualificado para inclusão. Os sites são adicionados à lista se um número suficiente de usuários que visitam o site permitirem a reprodução automática. Esse limite é baseado em porcentagem para não favorecer sites maiores.

Buscando o equilíbrio

Publicamos uma nova documentação para fornecer mais informações sobre nosso processo de tomada de decisões e a lógica de design por trás dessa política. Além da nova documentação sobre como funciona a lista de sites pré-prontos.

Sempre colocamos nossos usuários em primeiro lugar, mas não queremos desapontar a comunidade de desenvolvimento da Web. Às vezes, ser o navegador significa que esses dois objetivos devem ser cuidadosamente equilibrados. Com os ajustes na implementação da política e o tempo adicional que oferecemos para que os desenvolvedores de áudio da Web atualizem o código, acreditamos que alcançaremos esse equilíbrio com o Chrome 71.

Feedback