浏览代码

Integrating latest webAudio fixes

David Catuhe 9 年之前
父节点
当前提交
08912981db
共有 5 个文件被更改,包括 17472 次插入57 次删除
  1. 17308 0
      lib.d.ts
  2. 9 0
      src/Audio/babylon.audioEngine.js
  3. 13 0
      src/Audio/babylon.audioEngine.ts
  4. 71 28
      src/Audio/babylon.sound.js
  5. 71 29
      src/Audio/babylon.sound.ts

文件差异内容过多而无法显示
+ 17308 - 0
lib.d.ts


+ 9 - 0
src/Audio/babylon.audioEngine.js

@@ -7,10 +7,19 @@ var BABYLON;
             this.canUseWebAudio = false;
             this.canUseWebAudio = false;
             this.WarnedWebAudioUnsupported = false;
             this.WarnedWebAudioUnsupported = false;
             this.unlocked = false;
             this.unlocked = false;
+            this.isMP3supported = false;
+            this.isOGGsupported = false;
             if (typeof window.AudioContext !== 'undefined' || typeof window.webkitAudioContext !== 'undefined') {
             if (typeof window.AudioContext !== 'undefined' || typeof window.webkitAudioContext !== 'undefined') {
                 window.AudioContext = window.AudioContext || window.webkitAudioContext;
                 window.AudioContext = window.AudioContext || window.webkitAudioContext;
                 this.canUseWebAudio = true;
                 this.canUseWebAudio = true;
             }
             }
+            var audioElem = document.createElement('audio');
+            if (audioElem && !!audioElem.canPlayType && audioElem.canPlayType('audio/mpeg; codecs="mp3"').replace(/^no$/, '')) {
+                this.isMP3supported = true;
+            }
+            if (audioElem && !!audioElem.canPlayType && audioElem.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/, '')) {
+                this.isOGGsupported = true;
+            }
             if (/iPad|iPhone|iPod/.test(navigator.platform)) {
             if (/iPad|iPhone|iPod/.test(navigator.platform)) {
                 this._unlockiOSaudio();
                 this._unlockiOSaudio();
             }
             }

+ 13 - 0
src/Audio/babylon.audioEngine.ts

@@ -10,6 +10,9 @@
         public unlocked: boolean = false;
         public unlocked: boolean = false;
         public onAudioUnlocked: () => any;
         public onAudioUnlocked: () => any;
 
 
+        public isMP3supported: boolean = false;
+        public isOGGsupported: boolean = false;
+
         public get audioContext(): AudioContext {
         public get audioContext(): AudioContext {
             if (!this._audioContextInitialized) {
             if (!this._audioContextInitialized) {
                 this._initializeAudioContext();
                 this._initializeAudioContext();
@@ -23,6 +26,16 @@
                 this.canUseWebAudio = true;
                 this.canUseWebAudio = true;
             }
             }
 
 
+            var audioElem = document.createElement('audio');
+
+            if (audioElem && !!audioElem.canPlayType && audioElem.canPlayType('audio/mpeg; codecs="mp3"').replace(/^no$/, '')) {
+                this.isMP3supported = true;
+            }
+
+            if (audioElem && !!audioElem.canPlayType && audioElem.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/, '')) {
+                this.isOGGsupported = true;
+            }
+
             if (/iPad|iPhone|iPod/.test(navigator.platform)) {
             if (/iPad|iPhone|iPod/.test(navigator.platform)) {
                 this._unlockiOSaudio();
                 this._unlockiOSaudio();
             }
             }

+ 71 - 28
src/Audio/babylon.sound.js

@@ -37,6 +37,7 @@ var BABYLON;
             this._coneOuterAngle = 360;
             this._coneOuterAngle = 360;
             this._coneOuterGain = 0;
             this._coneOuterGain = 0;
             this._isOutputConnected = false;
             this._isOutputConnected = false;
+            this._urlType = "Unknown";
             this.name = name;
             this.name = name;
             this._scene = scene;
             this._scene = scene;
             this._readyToPlayCallback = readyToPlayCallback;
             this._readyToPlayCallback = readyToPlayCallback;
@@ -74,41 +75,83 @@ var BABYLON;
                     this._createSpatialParameters();
                     this._createSpatialParameters();
                 }
                 }
                 this._scene.mainSoundTrack.AddSound(this);
                 this._scene.mainSoundTrack.AddSound(this);
+                var validParameter = true;
                 // if no parameter is passed, you need to call setAudioBuffer yourself to prepare the sound
                 // if no parameter is passed, you need to call setAudioBuffer yourself to prepare the sound
                 if (urlOrArrayBuffer) {
                 if (urlOrArrayBuffer) {
-                    // If it's an URL
-                    if (typeof (urlOrArrayBuffer) === "string") {
-                        // Loading sound using XHR2
-                        if (!this._streaming) {
-                            BABYLON.Tools.LoadFile(urlOrArrayBuffer, function (data) { _this._soundLoaded(data); }, null, this._scene.database, true);
-                        }
-                        else {
-                            this._htmlAudioElement = new Audio(urlOrArrayBuffer);
-                            this._htmlAudioElement.controls = false;
-                            this._htmlAudioElement.loop = this.loop;
-                            this._htmlAudioElement.crossOrigin = "anonymous";
-                            this._htmlAudioElement.preload = "auto";
-                            this._htmlAudioElement.addEventListener("canplaythrough", function () {
-                                _this._isReadyToPlay = true;
-                                if (_this.autoplay) {
-                                    _this.play();
+                    if (typeof (urlOrArrayBuffer) === "string")
+                        this._urlType = "String";
+                    if (Array.isArray(urlOrArrayBuffer))
+                        this._urlType = "Array";
+                    if (urlOrArrayBuffer instanceof ArrayBuffer)
+                        this._urlType = "ArrayBuffer";
+                    var urls = [];
+                    var codecSupportedFound = false;
+                    switch (this._urlType) {
+                        case "ArrayBuffer":
+                            if (urlOrArrayBuffer.byteLength > 0) {
+                                codecSupportedFound = true;
+                                this._soundLoaded(urlOrArrayBuffer);
+                            }
+                            break;
+                        case "String":
+                            urls.push(urlOrArrayBuffer);
+                        case "Array":
+                            if (urls.length === 0)
+                                urls = urlOrArrayBuffer;
+                            // If we found a supported format, we load it immediately and stop the loop
+                            for (var i = 0; i < urls.length; i++) {
+                                var url = urls[i];
+                                if (url.indexOf(".mp3", url.length - 4) !== -1 && BABYLON.Engine.audioEngine.isMP3supported) {
+                                    codecSupportedFound = true;
                                 }
                                 }
-                                if (_this._readyToPlayCallback) {
-                                    _this._readyToPlayCallback();
+                                if (url.indexOf(".ogg", url.length - 4) !== -1 && BABYLON.Engine.audioEngine.isOGGsupported) {
+                                    codecSupportedFound = true;
                                 }
                                 }
-                            });
-                            document.body.appendChild(this._htmlAudioElement);
-                        }
+                                if (url.indexOf(".wav", url.length - 4) !== -1) {
+                                    codecSupportedFound = true;
+                                }
+                                if (codecSupportedFound) {
+                                    // Loading sound using XHR2
+                                    if (!this._streaming) {
+                                        BABYLON.Tools.LoadFile(url, function (data) { _this._soundLoaded(data); }, null, this._scene.database, true);
+                                    }
+                                    else {
+                                        this._htmlAudioElement = new Audio(url);
+                                        this._htmlAudioElement.controls = false;
+                                        this._htmlAudioElement.loop = this.loop;
+                                        this._htmlAudioElement.crossOrigin = "anonymous";
+                                        this._htmlAudioElement.preload = "auto";
+                                        this._htmlAudioElement.addEventListener("canplaythrough", function () {
+                                            _this._isReadyToPlay = true;
+                                            if (_this.autoplay) {
+                                                _this.play();
+                                            }
+                                            if (_this._readyToPlayCallback) {
+                                                _this._readyToPlayCallback();
+                                            }
+                                        });
+                                        document.body.appendChild(this._htmlAudioElement);
+                                    }
+                                    break;
+                                }
+                            }
+                            break;
+                        default:
+                            validParameter = false;
+                            break;
+                    }
+                    if (!validParameter) {
+                        BABYLON.Tools.Error("Parameter must be a URL to the sound, an Array of URLs (.mp3 & .ogg) or an ArrayBuffer of the sound.");
                     }
                     }
                     else {
                     else {
-                        if (urlOrArrayBuffer instanceof ArrayBuffer) {
-                            if (urlOrArrayBuffer.byteLength > 0) {
-                                this._soundLoaded(urlOrArrayBuffer);
+                        if (!codecSupportedFound) {
+                            // Simulating a ready to play event to avoid breaking code path
+                            if (this._readyToPlayCallback) {
+                                window.setTimeout(function () {
+                                    _this._readyToPlayCallback();
+                                }, 1000);
                             }
                             }
                         }
                         }
-                        else {
-                            BABYLON.Tools.Error("Parameter must be a URL to the sound or an ArrayBuffer of the sound.");
-                        }
                     }
                     }
                 }
                 }
             }
             }
@@ -175,7 +218,7 @@ var BABYLON;
                 if (_this._readyToPlayCallback) {
                 if (_this._readyToPlayCallback) {
                     _this._readyToPlayCallback();
                     _this._readyToPlayCallback();
                 }
                 }
-            }, function () { BABYLON.Tools.Error("Error while decoding audio data for: " + _this.name); });
+            }, function (err) { BABYLON.Tools.Error("Error while decoding audio data for: " + _this.name + " / Error: " + err); });
         };
         };
         Sound.prototype.setAudioBuffer = function (audioBuffer) {
         Sound.prototype.setAudioBuffer = function (audioBuffer) {
             if (BABYLON.Engine.audioEngine.canUseWebAudio) {
             if (BABYLON.Engine.audioEngine.canUseWebAudio) {

+ 71 - 29
src/Audio/babylon.sound.ts

@@ -43,6 +43,7 @@
         private _registerFunc: (connectedMesh: AbstractMesh) => any;
         private _registerFunc: (connectedMesh: AbstractMesh) => any;
         private _isOutputConnected = false;
         private _isOutputConnected = false;
         private _htmlAudioElement: HTMLAudioElement;
         private _htmlAudioElement: HTMLAudioElement;
+        private _urlType: string = "Unknown";
 
 
         /**
         /**
         * Create a sound and attach it to a scene
         * Create a sound and attach it to a scene
@@ -90,42 +91,83 @@
                     this._createSpatialParameters();
                     this._createSpatialParameters();
                 }
                 }
                 this._scene.mainSoundTrack.AddSound(this);
                 this._scene.mainSoundTrack.AddSound(this);
+                var validParameter = true;
                 // if no parameter is passed, you need to call setAudioBuffer yourself to prepare the sound
                 // if no parameter is passed, you need to call setAudioBuffer yourself to prepare the sound
                 if (urlOrArrayBuffer) {
                 if (urlOrArrayBuffer) {
-                    // If it's an URL
-                    if (typeof (urlOrArrayBuffer) === "string") {
-                        // Loading sound using XHR2
-                        if (!this._streaming) {
-                            Tools.LoadFile(urlOrArrayBuffer, (data) => { this._soundLoaded(data); }, null, this._scene.database, true);
-                        }
-                        // Streaming sound using HTML5 Audio tag
-                        else {
-                            this._htmlAudioElement = new Audio(urlOrArrayBuffer);
-                            this._htmlAudioElement.controls = false;
-                            this._htmlAudioElement.loop = this.loop;
-                            this._htmlAudioElement.crossOrigin = "anonymous";
-                            this._htmlAudioElement.preload = "auto";
-                            this._htmlAudioElement.addEventListener("canplaythrough", () => {
-                                this._isReadyToPlay = true;
-                                if (this.autoplay) {
-                                    this.play();
+                    if (typeof (urlOrArrayBuffer) === "string") this._urlType = "String";
+                    if (Array.isArray(urlOrArrayBuffer)) this._urlType = "Array";
+                    if (urlOrArrayBuffer instanceof ArrayBuffer) this._urlType = "ArrayBuffer";
+
+                    var urls:string[] = [];
+                    var codecSupportedFound = false;
+ 
+                    switch (this._urlType) {
+                        case "ArrayBuffer":
+                            if ((<ArrayBuffer>urlOrArrayBuffer).byteLength > 0) {
+                                codecSupportedFound = true;
+                                this._soundLoaded(urlOrArrayBuffer);
+                            }
+                            break;
+                        case "String":
+                            urls.push(urlOrArrayBuffer);
+                        case "Array":
+                            if (urls.length === 0) urls = urlOrArrayBuffer;
+                            // If we found a supported format, we load it immediately and stop the loop
+                            for (var i = 0; i < urls.length; i++) {
+                                var url = urls[i];
+                                if (url.indexOf(".mp3", url.length - 4) !== -1 && Engine.audioEngine.isMP3supported) {
+                                    codecSupportedFound = true;
                                 }
                                 }
-                                if (this._readyToPlayCallback) {
-                                    this._readyToPlayCallback();
+                                if (url.indexOf(".ogg", url.length - 4) !== -1 && Engine.audioEngine.isOGGsupported) {
+                                    codecSupportedFound = true;
                                 }
                                 }
-                            });
-                            document.body.appendChild(this._htmlAudioElement);
-                        }
+                                if (url.indexOf(".wav", url.length - 4) !== -1) {
+                                    codecSupportedFound = true;
+                                }
+                                if (codecSupportedFound) {
+                                    // Loading sound using XHR2
+                                    if (!this._streaming) {
+                                        Tools.LoadFile(url, (data) => { this._soundLoaded(data); }, null, this._scene.database, true);
+                                    }
+                                    // Streaming sound using HTML5 Audio tag
+                                    else {
+                                        this._htmlAudioElement = new Audio(url);
+                                        this._htmlAudioElement.controls = false;
+                                        this._htmlAudioElement.loop = this.loop;
+                                        this._htmlAudioElement.crossOrigin = "anonymous";
+                                        this._htmlAudioElement.preload = "auto";
+                                        this._htmlAudioElement.addEventListener("canplaythrough", () => {
+                                            this._isReadyToPlay = true;
+                                            if (this.autoplay) {
+                                                this.play();
+                                            }
+                                            if (this._readyToPlayCallback) {
+                                                this._readyToPlayCallback();
+                                            }
+                                        });
+                                        document.body.appendChild(this._htmlAudioElement);
+                                    }
+                                    break;
+                                }
+                            }
+                            break;
+                        default:
+                            validParameter = false;
+                            break;
+                    }
+
+                    if (!validParameter) {
+                        Tools.Error("Parameter must be a URL to the sound, an Array of URLs (.mp3 & .ogg) or an ArrayBuffer of the sound.");
                     }
                     }
                     else {
                     else {
-                        if (urlOrArrayBuffer instanceof ArrayBuffer) {
-                            if ((<ArrayBuffer>urlOrArrayBuffer).byteLength > 0) {
-                                this._soundLoaded(urlOrArrayBuffer);
+                        if (!codecSupportedFound) {
+                            // Simulating a ready to play event to avoid breaking code path
+                            if (this._readyToPlayCallback) {
+                                window.setTimeout(() => {
+                                    this._readyToPlayCallback();
+                                }, 1000);
                             }
                             }
                         }
                         }
-                        else {
-                            Tools.Error("Parameter must be a URL to the sound or an ArrayBuffer of the sound.");
-                        }
                     }
                     }
                 }
                 }
             }
             }
@@ -191,7 +233,7 @@
                 this._isReadyToPlay = true;
                 this._isReadyToPlay = true;
                 if (this.autoplay) { this.play(); }
                 if (this.autoplay) { this.play(); }
                 if (this._readyToPlayCallback) { this._readyToPlayCallback(); }
                 if (this._readyToPlayCallback) { this._readyToPlayCallback(); }
-            }, () => { Tools.Error("Error while decoding audio data for: " + this.name); });
+            }, (err: any) => { Tools.Error("Error while decoding audio data for: " + this.name + " / Error: " + err); });
         }
         }
 
 
         public setAudioBuffer(audioBuffer: AudioBuffer): void {
         public setAudioBuffer(audioBuffer: AudioBuffer): void {