Skip to content

Commit

Permalink
Fix oppia#3790: Add automatic text-to-speech audio to explorations (o…
Browse files Browse the repository at this point in the history
…ppia#3818)

* Add automatics text to speech

* lint

* Minor refactoring in AudioControlsDirective.

* Suggested changes

* Making Links and LateX speakable

* lint

* Add language object factories; update LaTeX formatting for speakable text; add tests for LaTeX conversion to speakable text

* lint

* lint

* Change variable name; add dependencies to collection editor
  • Loading branch information
tjiang11 authored and seanlip committed Sep 18, 2017
1 parent a0a5b0f commit aecb981
Show file tree
Hide file tree
Showing 19 changed files with 750 additions and 80 deletions.
9 changes: 8 additions & 1 deletion assets/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ var constants = {
"text": "中文(繁體)"
}],

"//" : [
"//": [
"Related languages are used to prioritize an exploration's language when ",
"setting the default audio language."
],
Expand All @@ -280,5 +280,12 @@ var constants = {
"id": "es",
"text": "Spanish",
"related_languages": ["es"]
}],

"AUTOGENERATED_AUDIO_LANGUAGES": [{
"id": "en-auto",
"text": "English (autogenerated)",
"exploration_language": "en",
"speech_synthesis_code": "en-GB"
}]
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright 2017 The Oppia Authors. All Rights Reserved.
//
// Licensed 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.

/**
* @fileoverview Object factory for creating audio languages.
*/

oppia.factory('AudioLanguageObjectFactory', function() {
var AudioLanguage = function(id, description, relatedLanguages) {
this.id = id;
this.description = description;
this.relatedLanguages = relatedLanguages;
};

AudioLanguage.createFromDict = function(audioLanguageDict) {
return new AudioLanguage(
audioLanguageDict.id,
audioLanguageDict.text,
audioLanguageDict.related_languages);
};

return AudioLanguage;
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright 2017 The Oppia Authors. All Rights Reserved.
//
// Licensed 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.

/**
* @fileoverview Object factory for creating autogenerated audio languages.
*/

oppia.factory('AutogeneratedAudioLanguageObjectFactory', function() {
var AutogeneratedAudioLanguage =
function(id, description, explorationLanguage, speechSynthesisCode) {
this.id = id;
this.description = description;
this.explorationLanguage = explorationLanguage;
this.speechSynthesisCode = speechSynthesisCode;
};

AutogeneratedAudioLanguage.createFromDict = (
function(autogeneratedAudioLanguageDict) {
return new AutogeneratedAudioLanguage(
autogeneratedAudioLanguageDict.id,
autogeneratedAudioLanguageDict.text,
autogeneratedAudioLanguageDict.exploration_language,
autogeneratedAudioLanguageDict.speech_synthesis_code);
});

return AutogeneratedAudioLanguage;
});
48 changes: 48 additions & 0 deletions core/templates/dev/head/domain/utilities/BrowserCheckerService.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright 2017 The Oppia Authors. All Rights Reserved.
//
// Licensed 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.

/**
* @fileoverview Utility service for checking web browser type.
*/

oppia.factory('BrowserCheckerService', function() {
var isChromium = window.chrome;
var winNav = window.navigator;
var vendorName = winNav.vendor;
var isOpera = winNav.userAgent.indexOf('OPR') > -1;
var isIEedge = winNav.userAgent.indexOf('Edge') > -1;
var isIOSChrome = winNav.userAgent.match('CriOS');

var _isChrome = function() {
// For details on the reliability of this check, see
// https://stackoverflow.com/questions/4565112/
// javascript-how-to-find-out-if-the-user-browser-is-chrome
if (isIOSChrome ||
(isChromium !== null &&
isChromium !== undefined &&
vendorName === 'Google Inc.' &&
isOpera == false &&
isIEedge == false)) {
return true;
} else {
return false;
}
};

return {
isChrome: function() {
return _isChrome();
}
};
});
107 changes: 70 additions & 37 deletions core/templates/dev/head/domain/utilities/LanguageUtilService.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,42 +16,75 @@
* @fileoverview Utility service for language operations.
*/

oppia.factory('LanguageUtilService', [function() {
var supportedAudioLanguages = constants.SUPPORTED_AUDIO_LANGUAGES;

var allAudioLanguageCodes = (
supportedAudioLanguages.map(function(audioLanguage) {
return audioLanguage.id;
}));
var audioLanguagesCount = allAudioLanguageCodes.length;

var audioLanguageCodesToDescriptions = {};
supportedAudioLanguages.forEach(function(audioLanguage) {
audioLanguageCodesToDescriptions[audioLanguage.id] = audioLanguage.text;
});

var audioLanguageCodesToRelatedLanguageCodes = {};
supportedAudioLanguages.forEach(function(audioLanguage) {
audioLanguageCodesToRelatedLanguageCodes[audioLanguage.id] =
audioLanguage.related_languages;
});

return {
getAudioLanguagesCount: function() {
return audioLanguagesCount;
},
getAudioLanguageDescription: function(audioLanguageCode) {
return audioLanguageCodesToDescriptions[audioLanguageCode];
},
// Given a list of audio language codes, returns the complement list, i.e.
// the list of audio language codes not in the input list.
getComplementAudioLanguageCodes: function(audioLanguageCodes) {
return allAudioLanguageCodes.filter(function(languageCode) {
return audioLanguageCodes.indexOf(languageCode) === -1;
});
},
getLanguageCodesRelatedToAudioLanguageCode: function(audioLanguageCode) {
return audioLanguageCodesToRelatedLanguageCodes[audioLanguageCode];
oppia.factory('LanguageUtilService', [
'AudioLanguageObjectFactory', 'AutogeneratedAudioLanguageObjectFactory',
function(
AudioLanguageObjectFactory, AutogeneratedAudioLanguageObjectFactory) {
var supportedAudioLanguageList = constants.SUPPORTED_AUDIO_LANGUAGES;
var autogeneratedAudioLanguageList =
constants.AUTOGENERATED_AUDIO_LANGUAGES;

var supportedAudioLanguages = {};
var autogeneratedAudioLanguagesByExplorationLanguageCode = {};
var autogeneratedAudioLanguagesByAutogeneratedLanguageCode = {};

var allAudioLanguageCodes = (
supportedAudioLanguageList.map(function(audioLanguage) {
return audioLanguage.id;
}));

supportedAudioLanguageList.forEach(function(audioLanguageDict) {
supportedAudioLanguages[audioLanguageDict.id] =
AudioLanguageObjectFactory.createFromDict(audioLanguageDict);
});

autogeneratedAudioLanguageList.forEach(
function(autogeneratedAudioLanguageDict) {
autogeneratedAudioLanguage =
AutogeneratedAudioLanguageObjectFactory.createFromDict(
autogeneratedAudioLanguageDict);

autogeneratedAudioLanguagesByExplorationLanguageCode[
autogeneratedAudioLanguage.explorationLanguage] =
autogeneratedAudioLanguage;

autogeneratedAudioLanguagesByAutogeneratedLanguageCode[
autogeneratedAudioLanguage.id] =
autogeneratedAudioLanguage;
}
);

var audioLanguagesCount = allAudioLanguageCodes.length;

return {
getAudioLanguagesCount: function() {
return audioLanguagesCount;
},
getAudioLanguageDescription: function(audioLanguageCode) {
return supportedAudioLanguages[audioLanguageCode].description;
},
// Given a list of audio language codes, returns the complement list, i.e.
// the list of audio language codes not in the input list.
getComplementAudioLanguageCodes: function(audioLanguageCodes) {
return allAudioLanguageCodes.filter(function(languageCode) {
return audioLanguageCodes.indexOf(languageCode) === -1;
});
},
getLanguageCodesRelatedToAudioLanguageCode: function(audioLanguageCode) {
return supportedAudioLanguages[audioLanguageCode].relatedLanguages;
},
supportsAutogeneratedAudio: function(explorationLanguageCode) {
return autogeneratedAudioLanguagesByExplorationLanguageCode
.hasOwnProperty(explorationLanguageCode);
},
isAutogeneratedAudioLanguage: function(audioLanguageCode) {
return autogeneratedAudioLanguagesByAutogeneratedLanguageCode
.hasOwnProperty(audioLanguageCode);
},
getAutogeneratedAudioLanguage: function(explorationLanguageCode) {
return autogeneratedAudioLanguagesByExplorationLanguageCode[
explorationLanguageCode];
}
}
}
}]);
]);
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@
<script src="{{TEMPLATE_DIR_PREFIX}}/pages/exploration_player/LearnerParamsService.js"></script>

<script src="{{TEMPLATE_DIR_PREFIX}}/domain/utilities/LanguageUtilService.js"></script>
<script src="{{TEMPLATE_DIR_PREFIX}}/domain/utilities/AudioLanguageObjectFactory.js"></script>
<script src="{{TEMPLATE_DIR_PREFIX}}/domain/utilities/AutogeneratedAudioLanguageObjectFactory.js"></script>

<script src="{{TEMPLATE_DIR_PREFIX}}/components/loading/LoadingDotsDirective.js"></script>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,8 @@
<script src="{{TEMPLATE_DIR_PREFIX}}/services/messengerService.js"></script>
<script src="{{TEMPLATE_DIR_PREFIX}}/services/AudioPlayerService.js"></script>
<script src="{{TEMPLATE_DIR_PREFIX}}/services/AssetsBackendApiService.js"></script>
<script src="{{TEMPLATE_DIR_PREFIX}}/services/AutogeneratedAudioPlayerService.js"></script>
<script src="{{TEMPLATE_DIR_PREFIX}}/services/SpeechSynthesisChunkerService.js"></script>

<script src="{{TEMPLATE_DIR_PREFIX}}/pages/exploration_editor/EditorNavbarBreadcrumbDirective.js"></script>
<script src="{{TEMPLATE_DIR_PREFIX}}/pages/exploration_editor/EditorNavigationDirective.js"></script>
Expand Down Expand Up @@ -275,6 +277,9 @@
<script src="{{TEMPLATE_DIR_PREFIX}}/domain/exploration/ParamChangesObjectFactory.js"></script>
<script src="{{TEMPLATE_DIR_PREFIX}}/domain/utilities/StopwatchObjectFactory.js"></script>
<script src="{{TEMPLATE_DIR_PREFIX}}/domain/utilities/LanguageUtilService.js"></script>
<script src="{{TEMPLATE_DIR_PREFIX}}/domain/utilities/AudioLanguageObjectFactory.js"></script>
<script src="{{TEMPLATE_DIR_PREFIX}}/domain/utilities/AutogeneratedAudioLanguageObjectFactory.js"></script>
<script src="{{TEMPLATE_DIR_PREFIX}}/domain/utilities/BrowserCheckerService.js"></script>

<script src="{{TEMPLATE_DIR_PREFIX}}/pages/exploration_player/TutorCardDirective.js"></script>
<script src="{{TEMPLATE_DIR_PREFIX}}/pages/exploration_player/SupplementalCardDirective.js"></script>
Expand Down
Loading

0 comments on commit aecb981

Please sign in to comment.