• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<p id="classSummary">
2Use the <code>chrome.experimental.tts</code> module to play synthesized
3text-to-speech (TTS) from your extension or packaged app, or to register
4as a speech provider for other extensions and packaged apps that want to speak.
5</p>
6
7<p class="note"><b>Give us feedback:</b> If you have suggestions,
8especially changes that should be made before stabilizing the first
9version of this API, please send your ideas to the
10<a href="http://groups.google.com/a/chromium.org/group/chromium-extensions">chromium-extensions</a>
11group.</p>
12
13<h2 id="overview">Overview</h2>
14
15<p>To enable this experimental API, visit
16<b>chrome://flags</b> and enable <b>Experimental Extension APIs</b>.
17
18<p>Chrome provides native support for speech on Windows (using SAPI
195), Mac OS X, and Chrome OS, using speech synthesis capabilities
20provided by the operating system. On all platforms, the user can
21install extensions that register themselves as alternative speech
22synthesis providers.</p>
23
24<h2 id="generating_speech">Generating speech</h2>
25
26<p>Call <code>speak()</code> from your extension or
27packaged app to speak. For example:</p>
28
29<pre>chrome.experimental.tts.speak('Hello, world.');</pre>
30
31<p>You can provide options that control various properties of the speech,
32such as its rate, pitch, and more. For example:</p>
33
34<pre>chrome.experimental.tts.speak('Hello, world.', {'rate': 0.8});</pre>
35
36<p>It's also a good idea to specify the locale so that a synthesizer
37supporting that language (and regional dialect, if applicable) is chosen.</p>
38
39<pre>chrome.experimental.tts.speak(
40    'Hello, world.',
41    {
42      'locale': 'en-US',
43      'rate': 0.8
44    });</pre>
45
46<p>Not all speech engines will support all options.</p>
47
48<p>You can also pass a callback function that will be called when the
49speech has finished. For example, suppose we have an image on our page
50displaying a picture of a face with a closed mouth. We could open the mouth
51while speaking, and close it when done.</p>
52
53<pre>faceImage.src = 'open_mouth.png';
54chrome.experimental.tts.speak(
55    'Hello, world.', null, function() {
56      faceImage.src = 'closed_mouth.png';
57    });
58</pre>
59
60<p>To stop speaking immediately, just call <code>stop()</code>. Call
61<code>isSpeaking()</code> to find out if a TTS engine is currently speaking.</p>
62
63<p>You can check to see if an error occurred by checking
64<code>chrome.extension.lastError</code> inside the callback function.</p>
65
66<h2 id="ssml">SSML markup</h2>
67
68<p>Utterances used in this API may include markup using the
69<a href="http://www.w3.org/TR/speech-synthesis">Speech Synthesis Markup
70Language (SSML)</a>. For example:
71
72<pre>chrome.experimental.tts.speak('The &lt;emphasis&gt;second&lt;/emphasis&gt; word of this sentence was emphasized.');</pre>
73
74<p>Not all speech engines will support all SSML tags, and some may not support
75SSML at all, but all engines are expected to ignore any SSML they don't
76support and still speak the underlying text.</p>
77
78<h2 id="provider">Implementing a speech provider</h2>
79
80<p>An extension can register itself as a speech provider. By doing so, it
81can intercept some or all calls to functions such as
82<code>speak()</code> and <code>stop()</code> and provide an alternate
83implementation. Extensions are free to use any available web technology
84to provide speech, including streaming audio from a server, HTML5 audio,
85Native Client, or Flash. An extension could even do something different
86with the utterances, like display closed captions in a pop-up window or
87send them as log messages to a remote server.</p>
88
89<p>To provide TTS, an extension must first declare all voices it provides
90in the extension manifest, like this:</p>
91
92<pre>{
93  "name": "My TTS Provider",
94  "version": "1.0",
95  <b>"permissions": ["experimental"]
96  "tts": {
97    "voices": [
98      {
99        "voiceName": "Alice",
100        "locale": "en-US",
101        "gender": "female"
102      },
103      {
104        "voiceName": "Pat",
105        "locale": "en-US"
106      }
107    ]
108  },</b>
109  "background_page": "background.html",
110}</pre>
111
112<p>An extension can specify any number of voices. The three
113parameters&mdash;<code>voiceName</code>, <code>locale</code>,
114and <code>gender</code>&mdash;are all optional. If they are all unspecified,
115the extension will handle all speech from all clients. If any of them
116are specified, they can be used to filter speech requests. For
117example, if a voice only supports French, it should set the locale to
118'fr' (or something more specific like 'fr-FR') so that only utterances
119in that locale are routed to that extension.</p>
120
121<p>To handle speech calls, the extension should register listeners
122for <code>onSpeak</code> and <code>onStop</code>, like this:</p>
123
124<pre>var speakListener = function(utterance, options, callback) {
125  ...
126  callback();
127};
128var stopListener = function() {
129  ...
130};
131chrome.experimental.tts.onSpeak.addListener(speakListener);
132chrome.experimental.tts.onStop.addListener(stopListener);</pre>
133
134<p class="warning"><b>Important:</b> Don't forget to call the callback
135function from your speak listener!</p>
136
137<p>If an extension does not register listeners for both
138<code>onSpeak</code> and <code>onStop</code>, it will not intercept any
139speech calls, regardless of what is in the manifest.
140
141<p>The decision of whether or not to send a given speech request to an
142extension is based solely on whether the extension supports the given voice
143parameters in its manifest and has registered listeners
144for <code>onSpeak</code> and <code>onStop</code>. In other words,
145there's no way for an extension to receive a speech request and
146dynamically decide whether to handle it or not.</p>
147