From dfdba323fbd6a78be85feb2dc439cdde00e7f731 Mon Sep 17 00:00:00 2001 From: Richard Davey Date: Tue, 11 Jun 2019 14:31:43 +0100 Subject: [PATCH] New decodeAudio method for decoding base64 audio into webaudio --- src/sound/webaudio/WebAudioSoundManager.js | 82 ++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/src/sound/webaudio/WebAudioSoundManager.js b/src/sound/webaudio/WebAudioSoundManager.js index 7044e77ec..a047ff104 100644 --- a/src/sound/webaudio/WebAudioSoundManager.js +++ b/src/sound/webaudio/WebAudioSoundManager.js @@ -5,6 +5,7 @@ * @license {@link https://opensource.org/licenses/MIT|MIT License} */ +var Base64ToArrayBuffer = require('../../utils/base64/Base64ToArrayBuffer'); var BaseSoundManager = require('../BaseSoundManager'); var Class = require('../../utils/Class'); var Events = require('../events'); @@ -133,6 +134,87 @@ var WebAudioSoundManager = new Class({ return sound; }, + /** + * Decode audio data into a format ready for playback via Web Audio. + * + * The audio data can be a base64 encoded string, an audio media-type data uri, or an ArrayBuffer instance. + * + * The `audioKey` is the key that will be used to save the decoded audio to the audio cache. + * + * Instead of passing a single entry you can instead pass an array of `Phaser.Types.Sound.DecodeAudioConfig` + * objects as the first and only argument. + * + * Decoding is an async process, so be sure to listen for the events to know when decoding has completed. + * + * Once the audio has decoded it can be added to the Sound Manager or played via its key. + * + * @method Phaser.Sound.WebAudioSoundManager#decodeAudio + * @fires Phaser.Sound.Events#DECODED + * @fires Phaser.Sound.Events#DECODED_ALL + * @since 3.18.0 + * + * @param {(Phaser.Types.Sound.DecodeAudioConfig[]|string)} [audioKey] - The string-based key to be used to reference the decoded audio in the audio cache, or an array of audio config objects. + * @param {(ArrayBuffer|string)} [audioData] - The audio data, either a base64 encoded string, an audio media-type data uri, or an ArrayBuffer instance. + */ + decodeAudio: function (audioKey, audioData) + { + var audioFiles; + + if (!Array.isArray(audioKey)) + { + audioFiles = [ { key: audioKey, data: audioData } ]; + } + else + { + audioFiles = audioKey; + } + + var cache = this.game.cache.audio; + var remaining = audioFiles.length; + + for (var i = 0; i < audioFiles.length; i++) + { + var entry = audioFiles[i]; + + var key = entry.key; + var data = entry.data; + + if (typeof data === 'string') + { + data = Base64ToArrayBuffer(data); + } + + var success = function (key, audioBuffer) + { + cache.add(key, audioBuffer); + + this.emit(Events.DECODED, key); + + remaining--; + + if (remaining === 0) + { + this.emit(Events.DECODED_ALL); + } + }.bind(this, key); + + var failure = function (key, error) + { + // eslint-disable-next-line no-console + console.error('Error decoding audio: ' + key + ' - ', error ? error.message : ''); + + remaining--; + + if (remaining === 0) + { + this.emit(Events.DECODED_ALL); + } + }.bind(this, key); + + this.context.decodeAudioData(data, success, failure); + } + }, + /** * Unlocks Web Audio API on the initial input event. *