From e93d3e00f2dce48e5bafcd660387614551b04e51 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 23 Dec 2019 20:40:34 -0800 Subject: [PATCH] GUACAMOLE-732: Retrieve audio stream via Promise for newer versions of getUserMedia(). --- .../src/main/webapp/modules/AudioRecorder.js | 81 ++++++++++++------- 1 file changed, 54 insertions(+), 27 deletions(-) diff --git a/guacamole-common-js/src/main/webapp/modules/AudioRecorder.js b/guacamole-common-js/src/main/webapp/modules/AudioRecorder.js index d91bf50e5..e54dcca61 100644 --- a/guacamole-common-js/src/main/webapp/modules/AudioRecorder.js +++ b/guacamole-common-js/src/main/webapp/modules/AudioRecorder.js @@ -411,6 +411,53 @@ Guacamole.RawAudioRecorder = function RawAudioRecorder(stream, mimetype) { }; + /** + * getUserMedia() callback which handles successful retrieval of an + * audio stream (successful start of recording). + * + * @private + * @param {MediaStream} stream + * A MediaStream which provides access to audio data read from the + * user's local audio input device. + */ + var streamReceived = function streamReceived(stream) { + + // Create processing node which receives appropriately-sized audio buffers + processor = context.createScriptProcessor(BUFFER_SIZE, format.channels, format.channels); + processor.connect(context.destination); + + // Send blobs when audio buffers are received + processor.onaudioprocess = function processAudio(e) { + writer.sendData(toSampleArray(e.inputBuffer).buffer); + }; + + // Connect processing node to user's audio input source + source = context.createMediaStreamSource(stream); + source.connect(processor); + + // Save stream for later cleanup + mediaStream = stream; + + }; + + /** + * getUserMedia() callback which handles audio recording denial. The + * underlying Guacamole output stream is closed, and the failure to + * record is noted using onerror. + * + * @private + */ + var streamDenied = function streamDenied() { + + // Simply end stream if audio access is not allowed + writer.sendEnd(); + + // Notify of closure + if (recorder.onerror) + recorder.onerror(); + + }; + /** * Requests access to the user's microphone and begins capturing audio. All * received audio data is resampled as necessary and forwarded to the @@ -423,34 +470,14 @@ Guacamole.RawAudioRecorder = function RawAudioRecorder(stream, mimetype) { var beginAudioCapture = function beginAudioCapture() { // Attempt to retrieve an audio input stream from the browser - navigator.mediaDevices.getUserMedia({ 'audio' : true }, function streamReceived(stream) { + var promise = navigator.mediaDevices.getUserMedia({ + 'audio' : true + }, streamReceived, streamDenied); - // Create processing node which receives appropriately-sized audio buffers - processor = context.createScriptProcessor(BUFFER_SIZE, format.channels, format.channels); - processor.connect(context.destination); - - // Send blobs when audio buffers are received - processor.onaudioprocess = function processAudio(e) { - writer.sendData(toSampleArray(e.inputBuffer).buffer); - }; - - // Connect processing node to user's audio input source - source = context.createMediaStreamSource(stream); - source.connect(processor); - - // Save stream for later cleanup - mediaStream = stream; - - }, function streamDenied() { - - // Simply end stream if audio access is not allowed - writer.sendEnd(); - - // Notify of closure - if (recorder.onerror) - recorder.onerror(); - - }); + // Handle stream creation/rejection via Promise for newer versions of + // getUserMedia() + if (promise && promise.then) + promise.then(streamReceived, streamDenied); };