Mudanças no Web Audio
No Google, adoramos padrões. Nossa missão é criar a plataforma da Web definida por padrões. Uma das pequenas falhas que já dura algum tempo é a implementação com prefixo webkit da API Web Audio (principalmente o objeto webkitAudioContext) e alguns dos bits descontinuados do Web Audio que ainda oferecemos suporte.
Originalmente, o Chrome 36 iria remover o suporte para o prefixo webkitAudioContext, já que começamos a oferecer suporte ao objeto AudioContext sem prefixo. Isso acabou sendo mais problemático do que o esperado. Por isso, o Chrome 36 oferece suporte a prefixos e a prefixos. No entanto, mesmo no webkitAudioContext reintroduzido, vários métodos e atributos legados, como createGainNode e createJavaScriptNode, foram removidos. Em resumo, no Chrome 36, webkitAudioContext e AudioContext são aliases um do outro. Não há diferença na funcionalidade entre os dois.
Vamos remover o suporte ao prefixo completamente após o Chrome 36, provavelmente em algumas versões. Vamos fazer um anúncio aqui quando a mudança for iminente. Também vamos continuar entrando em contato com os autores para corrigir os apps de áudio da Web.
Por que fizemos isso em vez de reverter para a implementação anterior? Bem, em parte, não queríamos voltar muito no tempo. Já removemos essas APIs, e como um bom efeito colateral desse aliasing, os aplicativos podem funcionar bem no Firefox, que nunca ofereceu suporte a um objeto AudioContext com prefixo (e com razão!). O suporte ao Web Audio foi lançado no outono passado.
O restante desta atualização oferece um guia para corrigir problemas que possam ter ocorrido no código devido a essa mudança. A vantagem de corrigir esses problemas é que seu código provavelmente também vai funcionar no Firefox. Por muito tempo, pensei que meu aplicativo de Vocoder estava quebrado devido à implementação do Firefox, mas era um desses problemas.
Se você quiser começar a usar o recurso, confira uma biblioteca monkey-patch que escrevi para aplicativos criados com o código antigo do Web Audio. Ela pode ajudar você a começar a usar o recurso em um tempo mínimo, porque cria aliases para os objetos e métodos de forma adequada. De fato, os patches listados pela biblioteca são um bom guia para as coisas que mudaram.
Em primeiro lugar
Todas as referências a window.webkitAudioContext
precisam ser feitas para window.AudioContext
. Geralmente, isso é corrigido com um simples:
window.AudioContext = window.AudioContext || window.webkitAudioContext;
Se o app responder com algo como "Infelizmente, seu navegador não oferece suporte ao Web Audio. Use o Chrome ou o Safari." É muito provável que ele esteja procurando explicitamente por webkitAudioContext
. Desenvolvedor ruim! Você pode ter apoiado o Firefox por meses!
No entanto, há outras remoções de código mais sutis, algumas das quais podem ser menos óbvias.
- As constantes de tipo enumerado do BiquadFilter para o atributo
.type
(que agora é uma string) não aparecem mais no objetoBiquadFilterNode
, e não oferecemos suporte a elas no atributo.type
. Assim, você não usa mais.LOWPASS
(ou 0), e sim "lowpass". - Além disso, o atributo
Oscillator.type
agora é um tipo enumerado de string. Não há mais.SAWTOOTH
. PannerNode.type
também é um tipo enumerado de string.PannerNode.distanceModel
também é um tipo enumerado de string.createGainNode
foi renomeado comocreateGain
createDelayNode
foi renomeado comocreateDelay
createJavaScriptNode
foi renomeado comocreateScriptProcessor
AudioBufferSourceNode.noteOn()
foi substituído porstart()
AudioBufferSourceNode.noteGrainOn()
também foi substituído porstart()
.AudioBufferSourceNode.noteOff()
foi renomeado comostop()
.OscillatorNode.noteOn()
foi renomeado comostart()
.OscillatorNode.noteOff()
foi renomeado comostop()
.AudioParam.setTargetValueAtTime()
foi renomeado comosetTargetAtTime()
.AudioContext.createWaveTable()
eOscillatorNode.setWaveTable()
foram renomeados comocreatePeriodicWave() and
setPeriodicWave()AudioBufferSourceNode.looping
foi removido em favor de.loop
AudioContext.createBuffer(ArrayBuffer, boolean)
para decodificar de forma síncrona um blob de dados de áudio codificados foi removido. Chamadas síncronas que demoram muito para serem concluídas são práticas de programação ruins. Use a chamada assíncrona decodeAudioData. Essa é uma das mudanças mais desafiadoras, porque você precisa mudar o fluxo lógico, mas é uma prática muito melhor. Ehsan Angkari, da Mozilla, escreveu um bom exemplo de como fazer isso na postagem sobre a conversão para o Web Audio padrão.
Muitas dessas mudanças (como a renomeação de createGainNode e a remoção da decodificação síncrona em createBuffer) vão aparecer no console de ferramentas para desenvolvedores como um erro. No entanto, outras, como este uso:
MULTI_LINE_CODE_PLACEHOLDER_1
não vai aparecer e falhar silenciosamente (myFilterNode.BANDPASS agora será resolvido como indefinido, e a tentativa de definir .type como indefinido simplesmente não produzirá nenhum efeito. Isso, aliás, era o que estava causando a falha do vocoder. Da mesma forma, basta atribuir o filter.type a um número que funcionava:
myFilterNode.type = 2;
Mas agora você precisa usar a enumeração de string:
myFilterNode.type = “bandpass”;
Portanto, talvez você queira procurar no código os seguintes termos:
webkitAudioContext
.LOWPASS
.HIGHPASS
.BANDPASS
.LOWSHELF
.HIGHSHELF
.PEAKING
.NOTCH
.ALLPASS
.SINE
.SQUARE
.SAWTOOTH
.TRIANGLE
.noteOn
.noteGrainOn
.noteOff
.setWaveTable
.createWaveTable
.looping
.EQUALPOWER
.HRTF
.LINEAR
.INVERSE
.EXPONENTIAL
createGainNode
createDelayNode
.type
(sim, isso vai gerar muitos falsos positivos, mas é a única maneira de detectar o último exemplo acima).
Mais uma vez, se você estiver com pressa e quiser começar a usar, pegue uma cópia da minha biblioteca monkeypatch webkitAudioContext e a inclua no seu aplicativo. Bom trabalho!