Skip to content

Commit

Permalink
Merge branch 'master' into version-5.0.0-51
Browse files Browse the repository at this point in the history
  • Loading branch information
nsharma123 authored Dec 22, 2022
2 parents 383c3f0 + f01790f commit df79801
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 3 deletions.
23 changes: 21 additions & 2 deletions src/plugins/tts/WebTTSEngine.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,22 @@ export default class WebTTSEngine extends AbstractTTSEngine {
}

/** @override */
getVoices() { return speechSynthesis.getVoices(); }
getVoices() {
const voices = speechSynthesis.getVoices();
if (voices.filter(v => v.default).length != 1) {
// iOS bug where the default system voice is sometimes
// missing from the list
voices.unshift({
voiceURI: 'bookreader.SystemDefault',
name: 'System Default',
// Not necessarily true, but very likely
lang: navigator.language,
default: true,
localService: true,
});
}
return voices;
}

/** @override */
createSound(chunk) {
Expand Down Expand Up @@ -122,7 +137,11 @@ export class WebTTSSound {
this.started = false;

this.utterance = new SpeechSynthesisUtterance(this.text.slice(this._charIndex));
this.utterance.voice = this.voice;
// iOS bug where the default system voice is sometimes
// missing from the list
if (this.voice?.voiceURI !== 'bookreader.SystemDefault') {
this.utterance.voice = this.voice;
}
// Need to also set lang (for some reason); won't set voice on Chrome@Android otherwise
if (this.voice) this.utterance.lang = this.voice.lang;
this.utterance.rate = this.rate;
Expand Down
48 changes: 47 additions & 1 deletion tests/jest/plugins/tts/WebTTSEngine.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import sinon from 'sinon';
import { WebTTSSound } from '@/src/plugins/tts/WebTTSEngine.js';
import WebTTSEngine, { WebTTSSound } from '@/src/plugins/tts/WebTTSEngine.js';
import { afterEventLoop, eventTargetMixin } from '../../utils.js';

beforeEach(() => {
Expand All @@ -8,6 +8,7 @@ beforeEach(() => {
speak: sinon.stub(),
pause: sinon.stub(),
resume: sinon.stub(),

...eventTargetMixin(),
};
window.SpeechSynthesisUtterance = function (text) {
Expand All @@ -21,6 +22,51 @@ afterEach(() => {
delete window.SpeechSynthesisUtterance;
});

describe('WebTTSEngine', () => {
test('getVoices should include default voice when no actual default', () => {
// iOS devices set all the voices to default -_-
speechSynthesis.getVoices = () => [
{
default: true,
lang: "ar-001",
localService: true,
name: "Majed",
voiceURI: "com.apple.voice.compact.ar-001.Maged",
},
{
default: true,
lang: "bg-BG",
localService: true,
name: "Daria",
voiceURI: "com.apple.voice.compact.bg-BG.Daria",
}
];
const voices = WebTTSEngine.prototype.getVoices();
expect(voices.length).toBe(3);
expect(voices[0].voiceURI).toBe('bookreader.SystemDefault');
});

test('getVoices should not include default voice when there is a default', () => {
speechSynthesis.getVoices = () => [
{
default: true,
lang: "ar-001",
localService: true,
name: "Majed",
voiceURI: "com.apple.voice.compact.ar-001.Maged",
},
{
default: false,
lang: "bg-BG",
localService: true,
name: "Daria",
voiceURI: "com.apple.voice.compact.bg-BG.Daria",
}
];
const voices = WebTTSEngine.prototype.getVoices();
expect(voices.length).toBe(2);
});
});

describe('WebTTSSound', () => {
describe('setPlaybackRate', () => {
Expand Down

0 comments on commit df79801

Please sign in to comment.