diff --git a/guacamole-common-js/src/main/webapp/modules/AudioContextFactory.js b/guacamole-common-js/src/main/webapp/modules/AudioContextFactory.js new file mode 100644 index 000000000..f39ea35d9 --- /dev/null +++ b/guacamole-common-js/src/main/webapp/modules/AudioContextFactory.js @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +var Guacamole = Guacamole || {}; + +/** + * Maintains a singleton instance of the Web Audio API AudioContext class, + * instantiating the AudioContext only in response to the first call to + * getAudioContext(), and only if no existing AudioContext instance has been + * provided via the singleton property. Subsequent calls to getAudioContext() + * will return the same instance. + * + * @namespace + */ +Guacamole.AudioContextFactory = { + + /** + * A singleton instance of a Web Audio API AudioContext object, or null if + * no instance has yes been created. This property may be manually set if + * you wish to supply your own AudioContext instance, but care must be + * taken to do so as early as possible. Assignments to this property will + * not retroactively affect the value returned by previous calls to + * getAudioContext(). + * + * @type {AudioContext} + */ + 'singleton' : null, + + /** + * Returns a singleton instance of a Web Audio API AudioContext object. + * + * @return {AudioContext} + * A singleton instance of a Web Audio API AudioContext object, or null + * if the Web Audio API is not supported. + */ + 'getAudioContext' : function getAudioContext() { + + // Fallback to Webkit-specific AudioContext implementation + var AudioContext = window.AudioContext || window.webkitAudioContext; + + // Get new AudioContext instance if Web Audio API is supported + if (AudioContext) { + try { + + // Create new instance if none yet exists + if (!Guacamole.AudioContextFactory.singleton) + Guacamole.AudioContextFactory.singleton = new AudioContext(); + + // Return singleton instance + return Guacamole.AudioContextFactory.singleton; + + } + catch (e) { + // Do not use Web Audio API if not allowed by browser + } + } + + // Web Audio API not supported + return null; + + } + +}; diff --git a/guacamole-common-js/src/main/webapp/modules/AudioPlayer.js b/guacamole-common-js/src/main/webapp/modules/AudioPlayer.js index 881ef9450..9cc6b3a3c 100644 --- a/guacamole-common-js/src/main/webapp/modules/AudioPlayer.js +++ b/guacamole-common-js/src/main/webapp/modules/AudioPlayer.js @@ -137,25 +137,7 @@ Guacamole.RawAudioPlayer = function RawAudioPlayer(stream, mimetype) { * @private * @type {AudioContext} */ - var context = (function getAudioContext() { - - // Fallback to Webkit-specific AudioContext implementation - var AudioContext = window.AudioContext || window.webkitAudioContext; - - // Get new AudioContext instance if Web Audio API is supported - if (AudioContext) { - try { - return new AudioContext(); - } - catch (e) { - // Do not use Web Audio API if not allowed by browser - } - } - - // Web Audio API not supported - return null; - - })(); + var context = Guacamole.AudioContextFactory.getAudioContext(); /** * The earliest possible time that the next packet could play without @@ -488,7 +470,7 @@ Guacamole.RawAudioPlayer.prototype = new Guacamole.AudioPlayer(); Guacamole.RawAudioPlayer.isSupportedType = function isSupportedType(mimetype) { // No supported types if no Web Audio API - if (!window.AudioContext && !window.webkitAudioContext) + if (!Guacamole.AudioContextFactory.getAudioContext()) return false; return Guacamole.RawAudioFormat.parse(mimetype) !== null; @@ -511,7 +493,7 @@ Guacamole.RawAudioPlayer.isSupportedType = function isSupportedType(mimetype) { Guacamole.RawAudioPlayer.getSupportedTypes = function getSupportedTypes() { // No supported types if no Web Audio API - if (!window.AudioContext && !window.webkitAudioContext) + if (!Guacamole.AudioContextFactory.getAudioContext()) return []; // We support 8-bit and 16-bit raw PCM diff --git a/guacamole-common-js/src/main/webapp/modules/AudioRecorder.js b/guacamole-common-js/src/main/webapp/modules/AudioRecorder.js index 34185ad95..dff35d7de 100644 --- a/guacamole-common-js/src/main/webapp/modules/AudioRecorder.js +++ b/guacamole-common-js/src/main/webapp/modules/AudioRecorder.js @@ -129,25 +129,7 @@ Guacamole.RawAudioRecorder = function RawAudioRecorder(stream, mimetype) { * @private * @type {AudioContext} */ - var context = (function getAudioContext() { - - // Fallback to Webkit-specific AudioContext implementation - var AudioContext = window.AudioContext || window.webkitAudioContext; - - // Get new AudioContext instance if Web Audio API is supported - if (AudioContext) { - try { - return new AudioContext(); - } - catch (e) { - // Do not use Web Audio API if not allowed by browser - } - } - - // Web Audio API not supported - return null; - - })(); + var context = Guacamole.AudioContextFactory.getAudioContext(); /** * A function which directly invokes the browser's implementation of @@ -289,7 +271,7 @@ Guacamole.RawAudioRecorder.prototype = new Guacamole.AudioRecorder(); Guacamole.RawAudioRecorder.isSupportedType = function isSupportedType(mimetype) { // No supported types if no Web Audio API - if (!window.AudioContext && !window.webkitAudioContext) + if (!Guacamole.AudioContextFactory.getAudioContext()) return false; return Guacamole.RawAudioFormat.parse(mimetype) !== null; @@ -312,7 +294,7 @@ Guacamole.RawAudioRecorder.isSupportedType = function isSupportedType(mimetype) Guacamole.RawAudioRecorder.getSupportedTypes = function getSupportedTypes() { // No supported types if no Web Audio API - if (!window.AudioContext && !window.webkitAudioContext) + if (!Guacamole.AudioContextFactory.getAudioContext()) return []; // We support 8-bit and 16-bit raw PCM