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 continuamos a oferecer 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 sem 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, e continuaremos entrando em contato com os autores para corrigir os apps do Web Audio.
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 mapeamento, 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, 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 em um tempo mínimo, porque cria aliases para os objetos e métodos de maneira 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!
Mas 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 inadequadas. 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 delas (como a renomeação de createGainNode e a remoção da decodificação síncrona em createBuffer) obviamente 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!