Skip to content

Commit

Permalink
Polyfill using webkitAudioContext (#3576)
Browse files Browse the repository at this point in the history
* Polyfill using webkitAudioContext

* Update entry

* Apply suggestions from code review

Co-authored-by: Corina <14900841+corinagum@users.noreply.github.com>

* Rephrase HACK to WORKAROUND

Co-authored-by: Corina <14900841+corinagum@users.noreply.github.com>
  • Loading branch information
compulim and corinagum authored Nov 3, 2020
1 parent efaf3db commit 88e3a8f
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Fixes [#3514](https://github.com/microsoft/BotFramework-WebChat/issues/3514). Fix PoliCheck language errors, by [@corinagum](https://github.com/corinagum) in PR [#3545](https://github.com/microsoft/BotFramework-WebChat/pull/3545)
- Fixes [#3537](https://github.com/microsoft/BotFramework-WebChat/issues/3537). [Accessibility]: Ensure `aria-roledescription` is only used on elements with implicit/explicit role based off of [WAI ARIA role attributes](https://www.w3.org/WAI/PF/aria/roles), by [@corinagum](https://github.com/corinagum) in PR [#3551](https://github.com/microsoft/BotFramework-WebChat/pull/3551)
- Fixes [#3431](https://github.com/microsoft/BotFramework-WebChat/issues/3431). Activities should not be delayed due to missing activity of type "typing", by [@compulim](https://github.com/compulim) in PR [#3554](https://github.com/microsoft/BotFramework-WebChat/pull/3554)
- Fixes [#3574](https://github.com/microsoft/BotFramework-WebChat/issues/3574). Creates workaround for Cognitive Services Speech SDK 1.13.1 regarding removed support of macOS/iOS, by [@compulim](https://github.com/compulim) in PR [#3576](https://github.com/microsoft/BotFramework-WebChat/pull/3576)

### Changed

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { AudioConfig } from 'microsoft-cognitiveservices-speech-sdk/distrib/lib/src/sdk/Audio/AudioConfig';
import { MicAudioSource } from 'microsoft-cognitiveservices-speech-sdk/distrib/lib/src/common.browser/MicAudioSource';
import createPonyfill from 'web-speech-cognitive-services/lib/SpeechServices';

function resolveFunction(fnOrValue) {
Expand Down Expand Up @@ -53,16 +54,38 @@ export default function createCognitiveServicesSpeechServicesPonyfillFactory({
);
}

// HACK: We should prevent AudioContext object from being recreated because they may be blessed and UX-wise expensive to recreate.
// In Cognitive Services SDK, if they detect the "end" function is falsy, they will not call "end" but "suspend" instead.
// And on next recognition, they will re-use the AudioContext object.
// WORKAROUND: We should prevent AudioContext object from being recreated because they may be blessed and UX-wise expensive to recreate.
// In Cognitive Services SDK, if they detect the "end" function is falsy, they will not call "end" but "suspend" instead.
// And on next recognition, they will re-use the AudioContext object.
if (!audioConfig) {
audioConfig = audioInputDeviceId
? AudioConfig.fromMicrophoneInput(audioInputDeviceId)
: AudioConfig.fromDefaultMicrophoneInput();

const source = audioConfig.privSource;

// WORKAROUND: In Speech SDK 1.12.0-1.13.1, it dropped support of macOS/iOS Safari.
// This code is adopted from microsoft-cognitiveservices-speech-sdk/src/common.browser/MicAudioSource.ts.
// We will not need this code when using Speech SDK 1.14.0 or up.
// TODO: [P1] #3575 Remove the following lines when bumping to Speech SDK 1.14.0 or higher
source.createAudioContext = () => {
if (!!source.privContext) {
return;
}

const AudioContext = window.AudioContext || window.webkitAudioContext;

if (typeof AudioContext === 'undefined') {
throw new Error('Browser does not support Web Audio API (AudioContext/webkitAudioContext is not available).');
}

if (navigator.mediaDevices.getSupportedConstraints().sampleRate) {
source.privContext = new AudioContext({ sampleRate: MicAudioSource.AUDIOFORMAT.samplesPerSec });
} else {
source.privContext = new AudioContext();
}
};

// This piece of code is adopted from microsoft-cognitiveservices-speech-sdk/common.browser/MicAudioSource.ts.
// Instead of closing the AudioContext, it will just suspend it. And the next time it is needed, it will be resumed (by the original code).
source.destroyAudioContext = () => {
Expand Down
2 changes: 2 additions & 0 deletions packages/bundle/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ let config = {
resolve: {
alias: {
'microsoft-cognitiveservices-speech-sdk/distrib/lib/src/sdk/Audio/AudioConfig': resolve(__dirname, 'node_modules/microsoft-cognitiveservices-speech-sdk/distrib/lib/src/sdk/Audio/AudioConfig.js'),
// TODO: [P1] #3575 Remove the following line when bumping to Speech SDK 1.14.0 or higher
'microsoft-cognitiveservices-speech-sdk/distrib/lib/src/common.browser/MicAudioSource': resolve(__dirname, 'node_modules/microsoft-cognitiveservices-speech-sdk/distrib/lib/src/common.browser/MicAudioSource.js'),
'microsoft-cognitiveservices-speech-sdk/distrib/lib/microsoft.cognitiveservices.speech.sdk': resolve(__dirname, 'node_modules/microsoft-cognitiveservices-speech-sdk/distrib/lib/microsoft.cognitiveservices.speech.sdk.js'),
'microsoft-cognitiveservices-speech-sdk': resolve(__dirname, 'node_modules/microsoft-cognitiveservices-speech-sdk/distrib/lib/microsoft.cognitiveservices.speech.sdk.js'),
react: resolve(__dirname, 'node_modules/isomorphic-react/dist/react.js'),
Expand Down
33 changes: 29 additions & 4 deletions packages/directlinespeech/src/createAdapters.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import { AudioConfig } from 'microsoft-cognitiveservices-speech-sdk/distrib/lib/src/sdk/Audio/AudioConfig';
import { BotFrameworkConfig, DialogServiceConnector, PropertyId } from 'microsoft-cognitiveservices-speech-sdk';
import { MicAudioSource } from 'microsoft-cognitiveservices-speech-sdk/distrib/lib/src/common.browser/MicAudioSource';

import createWebSpeechPonyfillFactory from './createWebSpeechPonyfillFactory';
import DirectLineSpeech from './DirectLineSpeech';
Expand Down Expand Up @@ -70,6 +71,30 @@ export default async function create({
} else {
audioConfig = AudioConfig.fromDefaultMicrophoneInput();
}

// WORKAROUND: In Speech SDK 1.12.0-1.13.1, it dropped support of macOS/iOS Safari.
// This code is adopted from microsoft-cognitiveservices-speech-sdk/src/common.browser/MicAudioSource.ts.
// We will not need this code when using Speech SDK 1.14.0 or up.
// TODO: [P1] #3575 Remove the following lines when bumping to Speech SDK 1.14.0 or higher
const { privSource: source } = audioConfig;

source.createAudioContext = () => {
if (!!source.privContext) {
return;
}

const AudioContext = window.AudioContext || window.webkitAudioContext;

if (typeof AudioContext === 'undefined') {
throw new Error('Browser does not support Web Audio API (AudioContext/webkitAudioContext is not available).');
}

if (navigator.mediaDevices.getSupportedConstraints().sampleRate) {
source.privContext = new AudioContext({ sampleRate: MicAudioSource.AUDIOFORMAT.samplesPerSec });
} else {
source.privContext = new AudioContext();
}
};
}

if (speechRecognitionEndpointId) {
Expand Down Expand Up @@ -180,18 +205,18 @@ export default async function create({
if (dialogServiceConnector.privIsDisposed) {
clearInterval(interval);
}

const refreshedDirectLineToken = await refreshDirectLineToken(directLineToken);

if (!refreshedDirectLineToken) {
return console.warn(
'botframework-directlinespeech-sdk: Renew token failed because call to refresh token Direct Line API did not return a new token.'
);
}

config.setProperty(PropertyId.Conversation_ApplicationId, refreshedDirectLineToken);
dialogServiceConnector.properties.setProperty(PropertyId.Conversation_ApplicationId, refreshedDirectLineToken)

dialogServiceConnector.properties.setProperty(PropertyId.Conversation_ApplicationId, refreshedDirectLineToken);
dialogServiceConnector.connect();
}, DIRECT_LINE_TOKEN_RENEWAL_INTERVAL);
}
Expand Down
11 changes: 10 additions & 1 deletion packages/directlinespeech/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,16 @@ let config = {
filename: 'stats.json',
transform: (_, opts) => JSON.stringify(opts.compiler.getStats().toJson({ chunkModules: true }), null, 2)
})
]
],
resolve: {
alias: {
// TODO: [P1] #3575 Remove the following line when bumping to Speech SDK 1.14.0 or higher
'microsoft-cognitiveservices-speech-sdk/distrib/lib/src/common.browser/MicAudioSource': resolve(
__dirname,
'node_modules/microsoft-cognitiveservices-speech-sdk/distrib/lib/src/common.browser/MicAudioSource.js'
)
}
}
};

// VSTS always emits uppercase environment variables.
Expand Down

0 comments on commit 88e3a8f

Please sign in to comment.