Repository navigation
Expand file tree
/
Copy pathindex.bs
More file actions
1485 lines (1188 loc) · 100 KB
/
Copy pathindex.bs
File metadata and controls
1485 lines (1188 loc) · 100 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<pre class='metadata'>
Title: Web Speech API
Level:
Status: CG-DRAFT
Group: audiocg
TR:
URL: https://webaudio.github.io/web-speech-api/
Repository: WebAudio/web-speech-api
Shortname: speech-api
Editor: Evan Liu, Google
Former Editor: André Natal, Mozilla
Former Editor: Glen Shires, Google
Former Editor: Philip Jägenstedt, Google
Former Editor: Hans Wennborg, Google
!Tests: <a href=https://github.com/web-platform-tests/wpt/tree/master/speech-api>web-platform-tests speech-api/</a> (<a href=https://github.com/web-platform-tests/wpt/labels/speech-api>ongoing work</a>)
Abstract: This specification defines a JavaScript API to enable web developers to incorporate speech recognition and synthesis into their web pages.
Abstract: It enables developers to use scripting to generate text-to-speech output and to use speech recognition as an input for forms, continuous dictation and control.
Abstract: The JavaScript API allows web pages to control activation and timing and to handle results and alternatives.
Markup Shorthands:css no, markdown yes, dfn yes
Complain about:accidental-2119 yes, missing-example-ids yes
</pre>
<pre class=biblio>
{
"HTMLSPEECH": {
"authors": [
"Michael Bodell",
"Björn Bringert",
"Robert Brown",
"Daniel C. Burnett",
"Deborah Dahl",
"Dan Druta",
"Patrick Ehlen",
"Charles Hemphill",
"Michael Johnston",
"Olli Pettay",
"Satish Sampath",
"Marc Schröder",
"Glen Shires",
"Raj Tumuluri",
"Milan Young"
],
"href": "https://www.w3.org/2005/Incubator/htmlspeech/XGR-htmlspeech-20111206/",
"title": "HTML Speech Incubator Group Final Report"
}
}
</pre>
<pre class=link-defaults>
spec:storage; type:dfn; text:storage key
</pre>
<h2 id=introduction>Introduction</h2>
<p><em>This section is non-normative.</em></p>
<p>The Web Speech API aims to enable web developers to provide, in a web browser, speech-input and text-to-speech output features that are typically not available when using standard speech-recognition or screen-reader software.
The API itself is agnostic of the underlying speech recognition and synthesis implementation and can support both server-based and client-based/embedded recognition and synthesis.
The API is designed to enable both brief (one-shot) speech input and continuous speech input.
Speech recognition results are provided to the web page as a list of hypotheses, along with other relevant information for each hypothesis.</p>
<p>This specification is a subset of the API defined in the [[HTMLSPEECH|HTML Speech Incubator Group Final Report]].
That report is entirely informative since it is not a standards track document.
All portions of that report may be considered informative with regards to this document, and provide an informative background to this document.
This specification is a fully-functional subset of that report.
Specifically, this subset excludes the underlying transport protocol, the proposed additions to HTML markup, and it defines a simplified subset of the JavaScript API.
This subset supports the majority of use-cases and sample code in the Incubator Group Final Report.
This subset does not preclude future standardization of additions to the markup, API or underlying transport protocols, and indeed the Incubator Report defines a potential roadmap for such future work.</p>
<h2 id=use_cases>Use Cases</h2>
<p><em>This section is non-normative.</em></p>
<p>This specification supports the following use cases, as defined in [[HTMLSPEECH#use-cases|Section 4 of the Incubator Report]].</p>
<ul>
<li>Voice Web Search</li>
<li>Speech Command Interface</li>
<li>Continuous Recognition of Open Dialog</li>
<li>Speech UI present when no visible UI need be present</li>
<li>Voice Activity Detection</li>
<li>Temporal Structure of Synthesis to Provide Visual Feedback</li>
<li>Hello World</li>
<li>Speech Translation</li>
<li>Speech Enabled Email Client</li>
<li>Dialog Systems</li>
<li>Multimodal Interaction</li>
<li>Speech Driving Directions</li>
<li>Multimodal Video Game</li>
<li>Multimodal Search</li>
</ul>
<p>To keep the API to a minimum, this specification does not directly support the following use case.
This does not preclude adding support for this as a future API enhancement, and indeed the Incubator report provides a roadmap for doing so.</p>
<ul>
<li>Rerecognition</li>
</ul>
<h2 id=security>Security and privacy considerations</h2>
<ol>
<li>User agents must only start speech input sessions with explicit, informed user consent.
User consent can include, for example:
<ul>
<li>User click on a visible speech input element which has an obvious graphical representation showing that it will start speech input.</li>
<li>Accepting a permission prompt shown as the result of a call to {{SpeechRecognition/start()}}.</li>
<li>Consent previously granted to always allow speech input for this web page.</li>
</ul>
</li>
<li>User agents must give the user an obvious indication when audio is being recorded.
<ul>
<li>In a graphical user agent, this could be a mandatory notification displayed by the user agent as part of its chrome and not accessible by the web page.
This could for example be a pulsating/blinking record icon as part of the browser chrome/address bar, an indication in the status bar, an audible notification, or anything else relevant and accessible to the user.
This UI element must also allow the user to stop recording.<br>
<img src="ui-example.png" alt="Example UI recording notification."></li>
<li>In a speech-only user agent, the indication may for example take the form of the system speaking the label of the speech input element, followed by a short beep.</li>
</ul>
</li>
<li>The user agent may also give the user a longer explanation the first time speech input is used, to let the user know what it is and how they can tune their privacy settings to disable speech recording if required.</li>
<li>To mitigate the risk of fingerprinting, user agents MUST NOT personalize speech recognition when performing speech recognition on a {{MediaStreamTrack}}.</li>
</ol>
<h3 id="implementation-considerations">Implementation considerations</h3>
<p><em>This section is non-normative.</em></p>
<ol>
<li>Spoken password inputs can be problematic from a security perspective, but it is up to the user to decide if they want to speak their password.</li>
<li>Speech input could potentially be used to eavesdrop on users.
Malicious webpages could use tricks such as hiding the input element or otherwise making the user believe that it has stopped recording speech while continuing to do so.
They could also potentially style the input element to appear as something else and trick the user into clicking them.
An example of styling the file input element can be seen at <a href="https://www.quirksmode.org/dom/inputfile.html">https://www.quirksmode.org/dom/inputfile.html</a>.
The above recommendations are intended to reduce this risk of such attacks.</li>
</ol>
<div class="non-normative">
<h3 id=on-device-model-privacy>On-Device Model Privacy Considerations</h3>
<p><em>This section is non-normative.</em></p>
<h4 id="on-device-model-privacy-availability">Language Pack Availability</h4>
For on-device speech recognition, the exact download status of language packs can present a fingerprinting vector. How many bits this vector provides depends on the options provided to {{SpeechRecognition/available()}} or {{SpeechRecognition/install()}}, and how they influence the download (e.g., if different language packs have different availability statuses).
<h5 id="on-device-model-privacy-availability-masking">Download Masking</h5>
To prevent cross-origin fingerprinting and site collusion, the specification requires user agents to partition language pack availability by [=storage key=] and mask the current download status by returning {{"downloadable"}} from {{SpeechRecognition/available()}} by default, even if the underlying language pack is {{"available"}} or {{"downloading"}} on the user's device (see <a href="#req-download-masking">the download masking requirements</a> for the [=download masking state=] under {{SpeechRecognition/available()}} and <a href="#step-availability-masking">this step</a> of the [=availability algorithm=]).
Because the [=download masking state=] for a given (<var>options</var>, [=storage key=]) tuple is only unmasked after a web page within that [=storage key=] explicitly calls {{SpeechRecognition/install()}} (see <a href="#step-install-unmask">this step</a> of {{SpeechRecognition/install()}})—and because {{SpeechRecognition/start()}} also treats masked language packs as unavailable for local speech recognition (see <a href="#step-start-local-availability">this step</a> of the [=start session algorithm=])—web pages only gain access to the true download status after taking a more costly action, such as consuming a user activation or triggering a user permission prompt (see <a href="#on-device-model-privacy-availability-installation">Installation-Time Friction</a>).
The requirement to <a href="#req-download-masking">clear the download masking state</a> whenever other storage for that [=storage key=] is cleared prevents the unmasked state from persisting across storage resets.
<h5 id="on-device-model-privacy-availability-installation">Installation-Time Friction</h5>
The mitigation described in <a href="#on-device-model-privacy-availability-masking">Download Masking</a> works against attempts to silently fingerprint using {{SpeechRecognition/available()}}. The specification also contains requirements to prevent {{SpeechRecognition/install()}} from being easily used for fingerprinting, by introducing friction:
* The {{SpeechRecognition/install()}} method both requires and consumes [=transient activation=] when, as far as the calling web page can observe, it would initiate a download (see <a href="#step-install-transient-activation">this step</a> of the {{SpeechRecognition/install()}} algorithm).
* The {{SpeechRecognition/install()}} method allows the user agent to prompt the user for permission, or to implicitly reject download attempts based on previous signals (such as an observed pattern of abuse; see <a href="#step-install-download-permission">this step</a> of the {{SpeechRecognition/install()}} algorithm).
* Access to {{SpeechRecognition/install()}} and {{SpeechRecognition/available()}} is gated behind the [=policy-controlled feature=] "on-device-speech-recognition", which means that only top-level origins and their delegates can use these methods.
Additionally, initiating the download process via {{SpeechRecognition/install()}} is more or less a one-time operation for a given language. The availability status will only transition from {{"downloadable"}} to {{"downloading"}} to {{"available"}} via these guarded installation operations. That is, while {{SpeechRecognition/install()}} can be used to read some of these fingerprinting bits (by observing the resolution of its promise and subsequent calls to {{SpeechRecognition/available()}}), doing so will effectively "destroy" those bits by changing the state.
(For details on cases where downloading might happen more than once, and how privacy and security are preserved in those cases, see <a href="#on-device-model-privacy-availability-cancelation">Download Cancelation</a>, <a href="#on-device-model-privacy-availability-eviction">Download Eviction</a>, and <a href="#on-device-model-security-disk-space">Disk Space for Language Packs</a>.)
<h5 id="on-device-model-privacy-availability-cancelation">Download Cancelation</h5>
Because the availability of a language pack is strictly partitioned by [=storage key=] (see <a href="#on-device-model-privacy-availability-masking">Download Masking</a>), a web page can only observe the download state within its own partition.
Therefore, if a user agent cancels an ongoing download due to page-controlled actions (e.g., navigation, page unload, or an iframe being destroyed) as permitted by <a href="#req-download-cancelation">the cancelation rules</a> for {{SpeechRecognition/install()}}, the resulting change in state (e.g., reverting from {{"downloading"}} to {{"downloadable"}}) is only visible to that specific [=storage key=], as long as canceling does not alter the availability status observable by other [=storage keys=]. This prevents the cancelation behavior from being used as a cross-origin fingerprinting vector.
<h5 id="on-device-model-privacy-availability-eviction">Download Eviction</h5>
Another ingredient in ensuring that websites cannot toggle the availability state back and forth is to ensure that user agents don't use a quota-based eviction system for downloaded language packs that web pages can indirectly control. For example, if a user agent evicted less-recently-used language packs when new ones are installed, a web page could trigger such evictions to toggle the state of a target language pack.
To avoid this, <a href="#req-download-eviction">the download eviction rules</a> for {{SpeechRecognition/install()}} discourage systems that allow web pages to control the eviction of downloaded language packs, including via indirect triggers such as further subsequent downloads. One way to fulfill this is to never evict downloaded material in response to web page-initiated storage pressure, instead refusing to download new material (e.g., {{SpeechRecognition/install()}} resolving to `false`) if doing so would cause storage pressure.
Evicting downloads in response to user-controlled actions (e.g., via a browser settings UI) is not problematic.
<h4 id="on-device-model-privacy-sensitive-language">Sensitive Language Information</h4>
Even if fingerprinting risks from availability status are mitigated, knowing a user has downloaded a specific language pack (e.g., for a minority language) can be sensitive.
For this reason, on top of installation-time friction, <a href="#step-install-fake-download">this step</a> of the {{SpeechRecognition/install()}} algorithm allows user agents to artificially fake a download (e.g., by adding a delay to the resolution of the {{SpeechRecognition/install()}} promise while reporting {{"downloading"}} for that [=storage key=]) if they believe it would be helpful for privacy reasons, instead of having {{SpeechRecognition/install()}} resolve instantly if the language pack is already present. This provides plausible deniability: if {{SpeechRecognition/install()}} takes a few seconds to resolve `true`, it could be a fake delay or a quick real download.
Such fake delays are not foolproof but offer some privacy benefit, especially when combined with other mitigations like prompts.
<h4 id="on-device-model-privacy-model-version">Model Version</h4>
The specific version or behavior of an on-device speech recognition model can also be a fingerprinting vector. This API does not expose model versions directly.
The best way to prevent the model version from becoming a fingerprinting vector is to tie it to the user agent's version, such that the model's version (and behavior) only updates alongside already-exposed information (like the User-Agent string). Accordingly, <a href="#req-model-version">the model version rules</a> under {{SpeechRecognition/available()}} encourage limiting the number of possible model versions that a single user agent version can be paired with when determining if a language pack is {{"available"}} via {{SpeechRecognition/available()}}. This might involve not providing model updates to older user agent versions or ignoring already-downloaded models below a minimum version threshold after a user agent update (instead, {{SpeechRecognition/available()}} might report {{"downloadable"}} for a newer version).
There is a tradeoff: aggressively locking new user agent versions to new model versions can increase transitions between {{"available"}} and {{"downloadable"}}. This can be mitigated by allowing older models with newer user agent versions while a new model downloads, keeping the status {{"available"}} but briefly allowing identification of users with older-model/newer-user-agent combinations.
<h4 id="on-device-model-privacy-user-input">User Input and Speech Data</h4>
Speech data is inherently sensitive. <a href="#req-user-input-training">The user input retention rules</a> under {{SpeechRecognition/processLocally}} prohibit implementations from training or fine-tuning on-device speech recognition models on user speech input obtained through this API, or otherwise storing user speech input in a way that models can consult in the future (e.g., for personalization beyond the current session or across origins).
Using user speech input in such a way would be a significant privacy leak, potentially exposing user information or information derived from interactions with one site to another.
This reinforces the existing requirement in <a href="#security">Security and privacy considerations</a> against personalizing speech recognition when performing speech recognition on a {{MediaStreamTrack}}, and applies broadly to any speech processed by on-device models via this API.
<h4 id="on-device-model-privacy-cloud-implementations">Cloud-Based vs. On-Device Implementations</h4>
The Web Speech API can support both server-based (cloud) and client-based/embedded (on-device) recognition and synthesis. The {{SpeechRecognition/processLocally}} attribute allows developers to indicate a requirement for on-device processing.
When {{SpeechRecognition/processLocally}} is `false` (the default), user speech data might be sent to a remote server for processing. Web developers need to be aware of this possibility and the associated privacy implications if they do not explicitly request local processing, and <a href="#req-cloud-transparency">user agents are encouraged to be transparent</a> with users about where speech processing occurs.
When {{SpeechRecognition/processLocally}} is `true`, the considerations in this "On-Device Model Privacy Considerations" section are paramount.
<h3 id=on-device-model-security>On-Device Model Security Considerations</h3>
<p><em>This section is non-normative.</em></p>
<h4 id="on-device-model-security-disk-space">Disk Space for Language Packs</h4>
Downloading language packs for on-device speech recognition via {{SpeechRecognition/install()}} could use significant amounts of the user's disk space.
As specified in <a href="#req-disk-space">the storage pressure rules</a> for {{SpeechRecognition/install()}}, in the event of storage pressure, user agents are expected to balance the utility of on-device speech recognition with the disk space its language packs take up—possibly by having {{SpeechRecognition/install()}} resolve to `false` for new downloads or by freeing up disk space in other ways, while remaining mindful of the privacy impacts discussed in <a href="#on-device-model-privacy-availability-eviction">Download Eviction</a> and potentially involving the user via download-time prompts or a browser UI for managing downloaded language packs.
If a previously installed language pack is evicted (e.g., by the user or due to extreme storage pressure) while it might be in use or expected to be available, ongoing sessions or subsequent sessions while the model remains in memory might continue to work; however, once the evicted language pack is no longer usable, attempts to use it (e.g., via {{SpeechRecognition/start()}} with {{SpeechRecognition/lang}} set to that language and {{SpeechRecognition/processLocally}} set to `true`) are expected to <a href="#req-eviction-graceful-failure">fail gracefully</a>. This might involve {{SpeechRecognition/available()}} returning {{"downloadable"}} (or {{"unavailable"}} if no longer supported), and {{SpeechRecognition/start()}} firing a {{SpeechRecognitionErrorEvent}} with an appropriate error code like {{SpeechRecognitionErrorCode/service-not-allowed}} or {{SpeechRecognitionErrorCode/language-not-supported}}.
<h4 id="on-device-model-security-runtime-resources">Runtime Shared Resources</h4>
On-device speech recognition can consume significant runtime resources like CPU, memory, and potentially specialized hardware accelerators.
As described in <a href="#req-runtime-resources">the runtime resource requirements</a> of the [=start session algorithm=], user agents are expected to ensure that one web page's use of on-device speech recognition does not overly interfere with another web page's use of the API, another web page's general operation, or overall system stability.
This specification does not mandate any particular mitigation strategy, but possible approaches include queuing requests, rate limiting, or detecting abusive behavior, and failing speech recognition operations (e.g., by firing a {{SpeechRecognitionErrorEvent}} with {{SpeechRecognitionErrorCode/service-not-allowed}}) when necessary to prevent resource exhaustion or instability.
<h4 id="on-device-model-security-os-models">OS-Provided Models</h4>
One implementation strategy for on-device speech recognition is to delegate to models or capabilities provided by the underlying operating system. This can offer benefits like a consistent user experience and efficient resource usage.
However, this approach comes with the usual considerations of exposing OS capabilities to the web. As specified in <a href="#req-os-models">the requirements for OS-provided models</a> under {{SpeechRecognition/processLocally}}, user agents still need to ensure that all privacy and security requirements of this specification are met when using OS-provided models, even if the user agent has less control over the model's behavior. Particularly notable requirements to watch out for are <a href="#req-user-input-training">not training on user speech input</a> (see <a href="#on-device-model-privacy-user-input">User Input and Speech Data</a>) and <a href="#req-runtime-resources">fair and stable resource sharing</a> (see <a href="#on-device-model-security-runtime-resources">Runtime Shared Resources</a>).
</div>
<h2 id="api_description">API Description</h2>
<p><em>This section is normative.</em></p>
<h3 id="speechreco-section">The SpeechRecognition Interface</h3>
<p>The speech recognition interface is the scripted web API for controlling a given recognition.</p>
The term "final result" indicates a {{SpeechRecognitionResult}} in which the {{SpeechRecognitionResult/isFinal}} attribute is true.
The term "interim result" indicates a {{SpeechRecognitionResult}} in which the {{SpeechRecognitionResult/isFinal}} attribute is false.
{{SpeechRecognition}} has the following internal slots:
<dl dfn-type=attribute dfn-for="SpeechRecognition">
: <dfn>[[started]]</dfn>
::
A boolean flag representing whether the speech recognition started. The initial value is <code>false</code>.
</dl>
<dl dfn-type=attribute dfn-for="SpeechRecognition">
: <dfn>[[processLocally]]</dfn>
::
A boolean flag indicating whether recognition <em class="rfc2119" title="MUST">MUST</em> be performed locally. The initial value is <code>false</code>.
</dl>
<dl dfn-type=attribute dfn-for="SpeechRecognition">
: <dfn>[[phrases]]</dfn>
::
An {{ObservableArray}} of {{SpeechRecognitionPhrase}} objects representing a list of phrases for contextual biasing. The initial value is a new empty {{ObservableArray}}.
</dl>
<xmp class="idl">
[SecureContext, Exposed=Window]
interface SpeechRecognition : EventTarget {
constructor();
// recognition parameters
attribute SpeechGrammarList grammars;
attribute DOMString lang;
attribute boolean continuous;
attribute boolean interimResults;
attribute boolean unspokenPunctuation;
attribute unsigned long maxAlternatives;
attribute boolean processLocally;
attribute ObservableArray<SpeechRecognitionPhrase> phrases;
// methods to drive the speech interaction
undefined start();
undefined start(MediaStreamTrack audioTrack);
undefined stop();
undefined abort();
static Promise<SpeechRecognitionAvailabilityStatus> available(SpeechRecognitionOptions options);
static Promise<boolean> install(SpeechRecognitionOptions options);
// event methods
attribute EventHandler onaudiostart;
attribute EventHandler onsoundstart;
attribute EventHandler onspeechstart;
attribute EventHandler onspeechend;
attribute EventHandler onsoundend;
attribute EventHandler onaudioend;
attribute EventHandler onresult;
attribute EventHandler onnomatch;
attribute EventHandler onerror;
attribute EventHandler onstart;
attribute EventHandler onend;
};
enum SpeechRecognitionQuality {
"command",
"dictation",
"conversation"
};
dictionary SpeechRecognitionOptions {
required sequence<DOMString> langs;
boolean processLocally = false;
SpeechRecognitionQuality quality = "command";
};
enum SpeechRecognitionErrorCode {
"no-speech",
"aborted",
"audio-capture",
"network",
"not-allowed",
"service-not-allowed",
"language-not-supported",
"phrases-not-supported"
};
enum SpeechRecognitionAvailabilityStatus {
"unavailable",
"downloadable",
"downloading",
"available"
};
[SecureContext, Exposed=Window]
interface SpeechRecognitionErrorEvent : Event {
constructor(DOMString type, SpeechRecognitionErrorEventInit eventInitDict);
readonly attribute SpeechRecognitionErrorCode error;
readonly attribute DOMString message;
};
dictionary SpeechRecognitionErrorEventInit : EventInit {
required SpeechRecognitionErrorCode error;
DOMString message = "";
};
// Item in N-best list
[SecureContext, Exposed=Window]
interface SpeechRecognitionAlternative {
readonly attribute DOMString transcript;
readonly attribute float confidence;
};
// A complete one-shot simple response
[SecureContext, Exposed=Window]
interface SpeechRecognitionResult {
readonly attribute unsigned long length;
getter SpeechRecognitionAlternative? item(unsigned long index);
readonly attribute boolean isFinal;
readonly attribute double speechStartTime;
readonly attribute double speechEndTime;
};
// A collection of responses (used in continuous mode)
[SecureContext, Exposed=Window]
interface SpeechRecognitionResultList {
readonly attribute unsigned long length;
getter SpeechRecognitionResult? item(unsigned long index);
};
// A full response, which could be interim or final, part of a continuous response or not
[SecureContext, Exposed=Window]
interface SpeechRecognitionEvent : Event {
constructor(DOMString type, SpeechRecognitionEventInit eventInitDict);
readonly attribute unsigned long resultIndex;
readonly attribute SpeechRecognitionResultList results;
};
dictionary SpeechRecognitionEventInit : EventInit {
unsigned long resultIndex = 0;
required SpeechRecognitionResultList results;
};
// The object representing a speech grammar. This interface has been deprecated and exists in this spec for the sole purpose of maintaining backwards compatibility.
[Exposed=Window]
interface SpeechGrammar {
attribute DOMString src;
attribute float weight;
};
// The object representing a speech grammar collection. This interface has been deprecated and exists in this spec for the sole purpose of maintaining backwards compatibility.
[Exposed=Window]
interface SpeechGrammarList {
constructor();
readonly attribute unsigned long length;
getter SpeechGrammar? item(unsigned long index);
undefined addFromUri(DOMString src,
optional float weight = 1.0);
undefined addFromString(DOMString string,
optional float weight = 1.0);
};
// The object representing a phrase for contextual biasing.
[SecureContext, Exposed=Window]
interface SpeechRecognitionPhrase {
constructor(DOMString phrase, optional float boost = 1.0);
readonly attribute DOMString phrase;
readonly attribute float boost;
};
</xmp>
<h4 id="speechreco-attributes">SpeechRecognition Attributes</h4>
<dl>
<dt><dfn attribute for=SpeechRecognition>grammars</dfn> attribute</dt>
<dd>The grammars attribute stores the collection of SpeechGrammar objects which represent the grammars that are active for this recognition.
This attribute does nothing and exists in this spec for the sole purpose of maintaining backwards compatibility.</dd>
<dt><dfn attribute for=SpeechRecognition>lang</dfn> attribute</dt>
<dd>This attribute will set the language of the recognition for the request, using a valid BCP 47 language tag. [[!BCP47]]
If unset it remains unset for getting in script, but will default to use the language of the html document root element and associated hierarchy.
This default value is computed and used when the input request opens a connection to the recognition service.</dd>
<dt><dfn attribute for=SpeechRecognition>continuous</dfn> attribute</dt>
<dd>When the continuous attribute is set to false, the user agent must return no more than one final result in response to starting recognition,
for example a single turn pattern of interaction.
When the continuous attribute is set to true, the user agent must return zero or more final results representing multiple consecutive recognitions in response to starting recognition,
for example a dictation.
The default value must be false. Note, this attribute setting does not affect interim results.</dd>
<dt><dfn attribute for=SpeechRecognition>interimResults</dfn> attribute</dt>
<dd>Controls whether interim results are returned.
When set to true, interim results should be returned.
When set to false, interim results must not be returned.
The default value must be false. Note, this attribute setting does not affect final results.</dd>
<dt><dfn attribute for=SpeechRecognition>unspokenPunctuation</dfn> attribute</dt>
<dd>This attribute controls whether the speech recognition engine automatically infers and inserts punctuation marks (such as periods, commas, and question marks) based on natural pauses, grammatical structure, and prosody, without requiring the user to explicitly speak the punctuation commands.
The default value must be false.</dd>
<dt><dfn attribute for=SpeechRecognition>maxAlternatives</dfn> attribute</dt>
<dd>This attribute will set the maximum number of {{SpeechRecognitionAlternative}}s per result.
The default value is 1.</dd>
<dt><dfn attribute for=SpeechRecognition>processLocally</dfn> attribute</dt>
<dd>This attribute, when set to true, indicates a requirement that the speech recognition process <em class="rfc2119" title="MUST">MUST</em> be performed locally on the user's device.
If set to false, the user agent can choose between local and remote processing.
The default value is false.
<p id="req-cloud-transparency">
When {{SpeechRecognition/processLocally}} is `false`, user speech data might be sent to a remote server for processing; user agents <em class="rfc2119">SHOULD</em> be transparent with users about where speech processing occurs (see <a href="#on-device-model-privacy-cloud-implementations">Cloud-Based vs. On-Device Implementations</a>).
</p>
<p id="req-user-input-training">
Regardless of the value of {{SpeechRecognition/processLocally}}, implementations <em class="rfc2119">MUST NOT</em> train or fine-tune on-device speech recognition models on user speech input obtained through this API, or otherwise store user speech input in a way that models can consult in the future (e.g., for personalization beyond the current session or across origins; see <a href="#on-device-model-privacy-user-input">User Input and Speech Data</a>).
</p>
<p id="req-os-models">
When delegating on-device speech recognition to models or capabilities provided by the underlying operating system, user agents <em class="rfc2119">MUST</em> ensure that all privacy and security requirements of this specification are met, even if the user agent has less control over the model's behavior (see <a href="#on-device-model-security-os-models">OS-Provided Models</a>).
</p>
</dd>
<dt><dfn attribute for=SpeechRecognition>phrases</dfn> attribute</dt>
<dd>
The `phrases` attribute provides a list of {{SpeechRecognitionPhrase}} objects to be used for contextual biasing. This is an {{ObservableArray}}, which can be modified like a JavaScript `Array` (e.g., using `push()`).
</dd>
<dd>
The getter steps are to return the value of {{SpeechRecognition/[[phrases]]}}.
</dd>
</dl>
<p class=issue>The group has discussed whether WebRTC might be used to specify selection of audio sources and remote recognizers.
See <a href="https://lists.w3.org/Archives/Public/public-speech-api/2012Sep/0072.html">Interacting with WebRTC, the Web Audio API and other external sources</a> thread on public-speech-api@w3.org.</p>
<h4 id="speechreco-methods">SpeechRecognition Methods</h4>
<dl>
<dt><dfn method for=SpeechRecognition>start()</dfn> method</dt>
<dd>
Start the speech recognition process, directly from a microphone on the device.
When invoked, run the following steps:
1. Let |requestMicrophonePermission| be a boolean variable set to `true`.
1. Run the [=start session algorithm=] with |requestMicrophonePermission|.
</dd>
<dt><dfn method for=SpeechRecognition>start({{MediaStreamTrack}} audioTrack)</dfn> method</dt>
<dd>
Start the speech recognition process, using a {{MediaStreamTrack}}
When invoked, run the following steps:
1. Let |audioTrack| be the first argument.
1. If |audioTrack|'s {{MediaStreamTrack/kind}} attribute is NOT `"audio"`,
throw an {{InvalidStateError}} and abort these steps.
1. If |audioTrack|'s {{MediaStreamTrack/readyState}} attribute is NOT
`"live"`, throw an {{InvalidStateError}} and abort these steps.
1. Let |requestMicrophonePermission| be `false`.
1. Run the [=start session algorithm=] with |requestMicrophonePermission| and |audioTrack|.
</dd>
<dt><dfn method for=SpeechRecognition>stop()</dfn> method</dt>
<dd>The stop method represents an instruction to the recognition service to stop listening to more audio, and to try and return a result using just the audio that it has already received for this recognition.
A typical use of the stop method might be for a web application where the end user is doing the end pointing, similar to a walkie-talkie.
The end user might press and hold the space bar to talk to the system and on the space down press the start call would have occurred and when the space bar is released the stop method is called to ensure that the system is no longer listening to the user.
Once the stop method is called the speech service must not collect additional audio and must not continue to listen to the user.
The speech service must attempt to return a recognition result (or a nomatch) based on the audio that it has already collected for this recognition.
If the stop method is called on an object which is already stopped or being stopped (that is, start was never called on it, the <a event for=SpeechRecognition>end</a> or <a event for=SpeechRecognition>error</a> event has fired on it, or stop was previously called on it), the user agent must ignore the call.</dd>
<dt><dfn method for=SpeechRecognition>abort()</dfn> method</dt>
<dd>The abort method is a request to immediately stop listening and stop recognizing and do not return any information but that the system is done.
When the abort method is called, the speech service must stop recognizing.
The user agent must raise an <a event for=SpeechRecognition>end</a> event once the speech service is no longer connected.
If the abort method is called on an object which is already stopped or aborting (that is, start was never called on it, the <a event for=SpeechRecognition>end</a> or <a event for=SpeechRecognition>error</a> event has fired on it, or abort was previously called on it), the user agent must ignore the call.</dd>
<dt><dfn method for=SpeechRecognition>available({{SpeechRecognitionOptions}} options)</dfn> method</dt>
<dd>
The {{SpeechRecognition/available}} method returns a {{Promise}} that resolves to a {{SpeechRecognitionAvailabilityStatus}} indicating the recognition availability matching the {{SpeechRecognitionOptions}} argument, including the requested {{SpeechRecognitionOptions/quality}} level.
Access to this method is gated behind the [=policy-controlled feature=] "on-device-speech-recognition", which has a [=policy-controlled feature/default allowlist=] of <code>[=default allowlist/'self'=]</code>.
<p id="req-download-masking">
To prevent cross-origin fingerprinting and site collusion, user agents <em class="rfc2119">MUST</em> partition on-device language pack availability by [=storage key=]. User agents <em class="rfc2119">MUST</em> mask the current download status by returning {{"downloadable"}} from {{SpeechRecognition/available()}} by default when {{SpeechRecognitionOptions/processLocally}} is `true`, even if the actual underlying language pack is {{"available"}} or {{"downloading"}} on the user's device (see <a href="#step-availability-masking">this step</a> of the [=availability algorithm=] and <a href="#on-device-model-privacy-availability-masking">Download Masking</a>).
This <dfn>download masking state</dfn> is established for each (<var>options</var>, [=storage key=]) tuple (specifically, per language in {{SpeechRecognitionOptions/langs}} and {{SpeechRecognitionOptions/quality}} of <var>options</var> for a given [=storage key=], ignoring {{SpeechRecognitionOptions/processLocally}}). The user agent <em class="rfc2119">MUST</em> only set the state to "unmasked" for a specific (<var>options</var>, [=storage key=]) tuple after a web page within that key explicitly calls {{SpeechRecognition/install()}} with a given set of options, and that call either successfully initiates (or joins an ongoing) download or resolves to `true` (indicating the language pack is ready; see <a href="#step-install-unmask">this step</a> of {{SpeechRecognition/install()}}).
Implementations <em class="rfc2119">MUST</em> ensure that this [=storage key=]-based [=download masking state=] is cleared whenever other storage for that [=storage key=] is cleared.
</p>
<p id="req-model-version">
User agents <em class="rfc2119">SHOULD</em> limit the number of possible on-device model versions that a single user agent version can be paired with when determining if a language pack is {{"available"}} via {{SpeechRecognition/available()}} (for example, by tying model updates to user agent updates or ignoring already-downloaded models below a minimum version threshold after a user agent update and reporting {{"downloadable"}} for a newer version instead; see <a href="#on-device-model-privacy-model-version">Model Version</a>).
</p>
When invoked, run these steps:
1. Let <var>promise</var> be <a>a new promise</a>.
1. Run the <a>availability algorithm</a> with <var>options</var> and <var>promise</var>.
1. Return <var>promise</var>.
</dd>
<dt><dfn method for=SpeechRecognition>install({{SpeechRecognitionOptions}} options)</dfn> method</dt>
<dd>
The {{SpeechRecognition/install}} method attempts to install speech recognition language packs for all languages specified in `options.langs` matching the requested {{SpeechRecognitionOptions/quality}} level floor.
It returns a {{Promise}} that resolves to a {{boolean}}.
The promise resolves to `true` when all installation attempts for requested and supported languages succeed (or the languages were already installed).
The promise resolves to `false` if `options.langs` is empty, if not all of the requested languages are supported, or if any installation attempt for a supported language fails.
The promise is rejected with a {{NotAllowedError}} if the call would initiate a download but the calling {{Window}} does not have [=transient activation=].
Access to this method is gated behind the [=policy-controlled feature=] "on-device-speech-recognition", which has a [=policy-controlled feature/default allowlist=] of <code>[=default allowlist/'self'=]</code>.
When invoked, run these steps:
1. Let <var>promise</var> be <a>a new promise</a>.
1. If the [=current settings object=]'s [=relevant global object=]'s [=associated Document=] is NOT [=fully active=], reject <var>promise</var> with an {{InvalidStateError}}, abort these steps, returning <var>promise</var>.
1. If {{SpeechRecognitionOptions/langs}} of <var>options</var> is an empty sequence, resolve <var>promise</var> with <code>false</code>, abort these steps, returning <var>promise</var>.
1. If any <var>lang</var> in {{SpeechRecognitionOptions/langs}} of <var>options</var> is not a valid [[!BCP47]] language tag, reject <var>promise</var> with a {{SyntaxError}}, abort these steps, returning <var>promise</var>.
1. If the on-device speech recognition language pack for any <var>lang</var> in {{SpeechRecognitionOptions/langs}} of <var>options</var> is unsupported, resolve <var>promise</var> with <code>false</code>, abort these steps, returning <var>promise</var>.
1. <span id="step-install-transient-activation"></span>If {{SpeechRecognition/available()}} would resolve to {{"downloadable"}} for <var>options</var> (evaluated as if {{SpeechRecognitionOptions/processLocally}} of <var>options</var> were <code>true</code>), that is, if, as far as the calling web page can observe, this call would initiate a download, then:
1. If the [=current settings object=]'s [=relevant global object=] does not have [=transient activation=], reject <var>promise</var> with a {{NotAllowedError}}, abort these steps, returning <var>promise</var>.
1. [=Consume user activation=] given the [=current settings object=]'s [=relevant global object=].
<p class=note>
Note: Because {{SpeechRecognition/available()}} is subject to [=download masking state=] rules, this check is based on the masked availability status rather than on the true download status. As a result, whether {{SpeechRecognition/install()}} requires [=transient activation=] does not reveal the true download status to a web page for which it is still masked.
</p>
1. [=In parallel=], run the following steps:
1. <span id="step-install-download-permission"></span>The user agent <em class="rfc2119">MAY</em> prompt the user for explicit permission to download the on-device speech recognition language pack(s), or <em class="rfc2119">MAY</em> decline to initiate the download based on implicit signals (such as an observed pattern of abuse; see <a href="#on-device-model-privacy-availability-installation">Installation-Time Friction</a>) or storage pressure. <span id="req-disk-space"></span>In the event of storage pressure, user agents <em class="rfc2119">SHOULD</em> balance the utility of on-device speech recognition with the disk space its language packs take up (possibly by declining new downloads or freeing up disk space in other ways, subject to <a href="#req-download-eviction">the eviction requirements below</a>; see <a href="#on-device-model-security-disk-space">Disk Space for Language Packs</a>), and <em class="rfc2119">MAY</em> involve the user in these decisions (e.g., via the download-time permission prompt or a browser UI for managing downloaded language packs). If the download is not permitted, [=queue a task=] on the [=relevant global object=]'s [=task queue=] to resolve <var>promise</var> with <code>false</code>, and abort these steps.
1. For each <var>lang</var> in {{SpeechRecognitionOptions/langs}} of <var>options</var>, initiate the download of the on-device speech recognition language pack for <var>lang</var> matching the requested {{SpeechRecognitionOptions/quality}} level floor (if not already installed or downloading).
1. <span id="step-install-unmask"></span>If the download was successfully initiated (or the language pack is already installed or downloading) for every <var>lang</var> in {{SpeechRecognitionOptions/langs}} of <var>options</var>, set the [=download masking state=] for (<var>options</var>, [=storage key=]) to "unmasked".
1. <span id="step-install-fake-download"></span>Wait for the download of all languages specified by {{SpeechRecognitionOptions/langs}} of <var>options</var> to either succeed or fail. User agents <em class="rfc2119">MAY</em> artificially fake a download (e.g., by adding a delay before resolving <var>promise</var>) if they believe it would be helpful for privacy reasons, instead of resolving instantly if the language pack is already present (see <a href="#on-device-model-privacy-sensitive-language">Sensitive Language Information</a>). During such a fake download, the user agent <em class="rfc2119">MUST</em> report the availability status for that [=storage key=] as {{"downloading"}} (and treat the language pack as not yet installed for other purposes observable by that [=storage key=], including in the [=start session algorithm=] and the {{SpeechRecognitionOptions/processLocally}} `false` branch of the [=availability algorithm=]) so that the web page cannot distinguish a fake delay from a real download.
1. If the download of all those languages succeeded, let <var>result</var> be <code>true</code>, otherwise let <var>result</var> be <code>false</code>.
1. [=Queue a task=] on the [=relevant global object=]'s [=task queue=] to resolve <var>promise</var> with <var>result</var>.
<p class="note">
Note: The <code>false</code> resolution of the Promise does not indicate the specific cause of failure. User agents are encouraged to provide more detailed information about the failure in developer tools console messages. However, this detailed error information is not exposed to the script.
</p>
1. Return <var>promise</var>.
<p class=note>
The value of {{SpeechRecognitionOptions/processLocally}} of <var>options</var> is not used in this algorithm: {{SpeechRecognition/install()}} always concerns on-device language packs, which is why the availability check above treats it as <code>true</code>.
</p>
<p id="req-download-cancelation">
User agents <em class="rfc2119">MAY</em> cancel ongoing language pack downloads when the requesting document is destroyed or navigated away from, in accordance with their standard resource management policies, provided that doing so does not change the availability status observable by any other [=storage key=] (e.g., not canceling an underlying download that another [=storage key=] is also waiting on; see <a href="#on-device-model-privacy-availability-cancelation">Download Cancelation</a>).
</p>
<p id="req-download-eviction">
User agents <em class="rfc2119">SHOULD NOT</em> implement systems which allow web pages to control the eviction of downloaded language packs, including via indirect triggers such as further subsequent downloads (for example, quota-based or least-recently-used eviction in response to web page-initiated storage pressure; see <a href="#on-device-model-privacy-availability-eviction">Download Eviction</a>). Evicting downloads in response to user-controlled actions (e.g., via a browser settings UI) is permitted.
</p>
</dd>
</dl>
<h4 id="availability-status-values">SpeechRecognitionAvailabilityStatus Enum Values</h4>
<p>The {{SpeechRecognitionAvailabilityStatus}} enum indicates the availability of speech recognition capabilities. Its values are:</p>
<dl>
<dt><dfn enum-value for="SpeechRecognitionAvailabilityStatus">"unavailable"</dfn></dt>
<dd>Indicates that speech recognition is not available for the specified language(s) and processing preference.
If {{SpeechRecognitionOptions/processLocally}} of <var>options</var> is `true`, this means on-device recognition for the language is not supported by the user agent.
If {{SpeechRecognitionOptions/processLocally}} of <var>options</var> is `false`, it means neither local nor remote recognition is available for at least one of the specified languages.</dd>
<dt><dfn enum-value for="SpeechRecognitionAvailabilityStatus">"downloadable"</dfn></dt>
<dd>Indicates that on-device speech recognition for the specified language(s) is supported by the user agent but not yet installed. It can potentially be installed using the {{SpeechRecognition/install()}} method. This status is primarily relevant when {{SpeechRecognitionOptions/processLocally}} of <var>options</var> is true.</dd>
<dt><dfn enum-value for="SpeechRecognitionAvailabilityStatus">"downloading"</dfn></dt>
<dd>Indicates that on-device speech recognition for the specified language(s) is currently in the process of being downloaded. This status is primarily relevant when {{SpeechRecognitionOptions/processLocally}} of <var>options</var> is true.</dd>
<dt><dfn enum-value for="SpeechRecognitionAvailabilityStatus">"available"</dfn></dt>
<dd>Indicates that speech recognition is available for all specified language(s) and the given processing preference.
If {{SpeechRecognitionOptions/processLocally}} of <var>options</var> is true, this means on-device recognition is installed and ready.
If {{SpeechRecognitionOptions/processLocally}} of <var>options</var> is false, it means recognition (which could be local or remote) is available.</dd>
</dl>
<h4 id="speech-recognition-quality-values">SpeechRecognitionQuality Enum Values</h4>
<p>The {{SpeechRecognitionQuality}} enum indicates the semantic capability and quality level floor requested for the speech recognition model. Its values are:</p>
<dl>
<dt><dfn enum-value for="SpeechRecognitionQuality">"command"</dfn></dt>
<dd>Level 1: Short phrases, single speaker, limited vocabulary (e.g., voice commands for smart home or simple apps).</dd>
<dt><dfn enum-value for="SpeechRecognitionQuality">"dictation"</dfn></dt>
<dd>Level 2: Continuous speech, moderate background noise, single primary speaker (e.g., long-form text input like SMS/Email).</dd>
<dt><dfn enum-value for="SpeechRecognitionQuality">"conversation"</dfn></dt>
<dd>Level 3: Multi-speaker, complex vocabulary, high noise tolerance (e.g., meeting transcripts and continuous captioning).</dd>
</dl>
<p>When the <dfn>availability algorithm</dfn> with <var>options</var> and <var>promise</var> is invoked, the user agent MUST run the following steps:
1. If the [=current settings object=]'s [=relevant global object=]'s [=associated Document=] is NOT [=fully active=], reject <var>promise</var> with an {{InvalidStateError}} and abort these steps.
1. Let <var>langs</var> be {{SpeechRecognitionOptions/langs}} of <var>options</var>.
1. If any <var>lang</var> in <var>langs</var> is not a valid [[!BCP47]] language tag, reject <var>promise</var> with a {{SyntaxError}} and abort these steps.
1. If {{SpeechRecognitionOptions/processLocally}} of <var>options</var> is `false`:
1. If <var>langs</var> is an empty sequence, let <var>status</var> be {{SpeechRecognitionAvailabilityStatus/unavailable}}.
1. Else if speech recognition (which may be remote, or on-device if its [=download masking state=] is "unmasked" for the caller's [=storage key=]) is available for all <var>language</var> in <var>langs</var>, let <var>status</var> be {{SpeechRecognitionAvailabilityStatus/available}}.
1. Else, let <var>status</var> be {{SpeechRecognitionAvailabilityStatus/unavailable}}.
1. If {{SpeechRecognitionOptions/processLocally}} of <var>options</var> is `true`:
<ol type=a>
<li>If <var>langs</var> is an empty sequence, let <var>status</var> be {{SpeechRecognitionAvailabilityStatus/unavailable}}.</li>
<li>Else:
<ol type=i>
<li>Let <var>finalStatus</var> be {{SpeechRecognitionAvailabilityStatus/available}}.</li>
<li>For each <var>language</var> in <var>langs</var>:
<ol>
<li>Let <var>currentLanguageStatus</var>.</li>
<li>If on-device speech recognition for <var>language</var> matching the requested {{SpeechRecognitionOptions/quality}} of <var>options</var> is installed (taking into account <a href="#req-model-version">model version limits</a>) and no fake download is in progress for the caller's [=storage key=] per <a href="#step-install-fake-download">the `install()` algorithm</a>, set <var>currentLanguageStatus</var> to {{SpeechRecognitionAvailabilityStatus/available}}.</li>
<li>Else if on-device speech recognition for <var>language</var> matching the requested {{SpeechRecognitionOptions/quality}} of <var>options</var> is currently being downloaded (including a fake download for the caller's [=storage key=] per <a href="#step-install-fake-download">the `install()` algorithm</a>), set <var>currentLanguageStatus</var> to {{SpeechRecognitionAvailabilityStatus/downloading}}.</li>
<li>Else if on-device speech recognition for <var>language</var> matching the requested {{SpeechRecognitionOptions/quality}} of <var>options</var> is supported by the user agent but not yet installed, set <var>currentLanguageStatus</var> to {{SpeechRecognitionAvailabilityStatus/downloadable}}.</li>
<li>Else (on-device speech recognition for <var>language</var> is not supported), set <var>currentLanguageStatus</var> to {{SpeechRecognitionAvailabilityStatus/unavailable}}.</li>
<li><span id="step-availability-masking"></span>If <var>currentLanguageStatus</var> is {{SpeechRecognitionAvailabilityStatus/available}} or {{SpeechRecognitionAvailabilityStatus/downloading}}, and the [=download masking state=] for (<var>options</var>, [=storage key=]) is not "unmasked" for <var>language</var>, set <var>currentLanguageStatus</var> to {{SpeechRecognitionAvailabilityStatus/downloadable}}.</li>
<li>If <var>currentLanguageStatus</var> comes after <var>finalStatus</var> in the ordered list `[{{SpeechRecognitionAvailabilityStatus/available}}, {{SpeechRecognitionAvailabilityStatus/downloading}}, {{SpeechRecognitionAvailabilityStatus/downloadable}}, {{SpeechRecognitionAvailabilityStatus/unavailable}}]`, set <var>finalStatus</var> to <var>currentLanguageStatus</var>.</li>
</ol>
</li>
<li>Let <var>status</var> be <var>finalStatus</var>.</li>
</ol>
</li>
</ol>
1. [=Queue a task=] on the [=relevant global object=]'s [=task queue=] to run the following step:
- Resolve <var>promise</var> with <var>status</var>.
When the <dfn>start session algorithm</dfn> with
|requestMicrophonePermission| and |audioTrack| (if provided) is invoked, the user agent MUST run the
following steps:
1. If the [=current settings object=]'s [=relevant global object=]'s
[=associated Document=] is NOT [=fully active=], throw an {{InvalidStateError}}
and abort these steps.
1. If {{SpeechRecognition/[[started]]}} is `true` and no <a event
for=SpeechRecognition>error</a> event or <a event for=SpeechRecognition>end</a> event
has fired on it, throw an {{InvalidStateError}} and abort these steps.
1. If this.{{SpeechRecognition/phrases}}'s `length` is greater than 0 and the user agent does not support contextual biasing:
1. [=Queue a task=] to [=fire an event=] named <a event for=SpeechRecognition>error</a> at [=this=] using {{SpeechRecognitionErrorEvent}} with its {{SpeechRecognitionErrorEvent/error}} attribute initialized to `phrases-not-supported` and its {{SpeechRecognitionErrorEvent/message}} attribute set to an implementation-defined string detailing the reason.
1. Abort these steps.
1. <span id="step-start-local-availability"></span>Regardless of the value of this.{{SpeechRecognition/[[processLocally]]}}, the user agent <em class="rfc2119">MUST</em> treat an on-device language pack whose [=download masking state=] is not "unmasked" for the caller's [=storage key=] as not available for local speech recognition. If this.{{SpeechRecognition/[[processLocally]]}} is `true`, or if the user agent otherwise attempts to perform local speech recognition (for example, when remote speech recognition is not supported or not used):
1. If the user agent determines that local speech recognition is not available for this.{{SpeechRecognition/lang}} (including when its [=download masking state=] is not "unmasked" for the caller's [=storage key=] or when a previously installed language pack was evicted and is no longer usable; see <a href="#req-download-masking">the download masking requirements</a> and <a href="#req-eviction-graceful-failure">the eviction failure requirements below</a>), or if it cannot fulfill local processing for other reasons (such as <a href="#req-runtime-resources">preventing resource exhaustion</a>):
1. [=Queue a task=] to [=fire an event=] named <a event for=SpeechRecognition>error</a> at [=this=] using {{SpeechRecognitionErrorEvent}} with its {{SpeechRecognitionErrorEvent/error}} attribute initialized to {{SpeechRecognitionErrorCode/service-not-allowed}} and its {{SpeechRecognitionErrorEvent/message}} attribute set to an implementation-defined string detailing the reason, which <em class="rfc2119">MUST NOT</em> reveal whether a language pack whose [=download masking state=] is not "unmasked" for the caller's [=storage key=] is installed or being downloaded.
1. Abort these steps.
1. Set {{[[started]]}} to `true`.
1. If |requestMicrophonePermission| is `true` and [=request
permission to use=] "`microphone`" is [=permission/"denied"=]:
1. [=Queue a task=] to [=fire an event=] named <a event for=SpeechRecognition>error</a> at [=this=] using {{SpeechRecognitionErrorEvent}} with its {{SpeechRecognitionErrorEvent/error}} attribute initialized to {{SpeechRecognitionErrorCode/not-allowed}} and its {{SpeechRecognitionErrorEvent/message}} attribute set to an implementation-defined string detailing the reason.
1. Abort these steps.
1. Begin consuming audio from the audio source (the {{MediaStreamTrack}} if one was provided, or the microphone otherwise), buffering frames if the recognition service is not yet ready.
This establishes the recognition session's <dfn>session audio timeline</dfn>, which measures elapsed audio duration in seconds starting at `0.0` at the first audio frame consumed and advancing with the duration of each subsequent audio frame consumed.
1. Once the system is successfully listening to the recognition, queue a task to
[=fire an event=] named <a event for=SpeechRecognition>start</a> at [=this=].
<p id="req-eviction-graceful-failure">
If a previously installed language pack is evicted (e.g., by the user or due to extreme storage pressure) while it might be in use or expected to be available, ongoing sessions or subsequent sessions while the model remains in memory <em class="rfc2119">MAY</em> continue to work; once the evicted language pack is no longer usable, attempts to use it (e.g., via {{SpeechRecognition/start()}} with {{SpeechRecognition/lang}} set to that language and {{SpeechRecognition/processLocally}} set to `true`) <em class="rfc2119">SHOULD</em> fail gracefully (such as {{SpeechRecognition/available()}} returning {{"downloadable"}} (or {{"unavailable"}} if no longer supported), and {{SpeechRecognition/start()}} firing a {{SpeechRecognitionErrorEvent}} with an appropriate error code like {{SpeechRecognitionErrorCode/service-not-allowed}} (or {{SpeechRecognitionErrorCode/language-not-supported}} if no longer supported); see <a href="#on-device-model-security-disk-space">Disk Space for Language Packs</a>).
</p>
<p id="req-runtime-resources">
User agents <em class="rfc2119">SHOULD</em> ensure that one web page's use of on-device speech recognition does not overly interfere with another web page's use of the API, or another web page's general operation, or the overall system stability (for example, by queuing requests, rate limiting, or detecting abusive behavior; see <a href="#on-device-model-security-runtime-resources">Runtime Shared Resources</a>). If necessary to prevent resource exhaustion or instability, the user agent <em class="rfc2119">MAY</em> cause speech recognition operations to fail (e.g., by firing a {{SpeechRecognitionErrorEvent}} with {{SpeechRecognitionErrorCode/service-not-allowed}}). On-device speech recognition sessions are also subject to <a href="#req-user-input-training">the user input retention rules</a> and <a href="#req-os-models">the OS-provided model rules</a> under {{SpeechRecognition/processLocally}}.
</p>
<h4 id="speechreco-events">SpeechRecognition Events</h4>
<p>The DOM Level 2 Event Model is used for speech recognition events.
The methods in the EventTarget interface should be used for registering event listeners.
The SpeechRecognition interface also contains convenience attributes for registering a single event handler for each event type.
These events do not bubble and are not cancelable.</p>
<p>For all these events, the timeStamp attribute defined in the DOM Level 2 Event interface must be set to the best possible estimate of when the real-world event which the event object represents occurred.
This timestamp must be represented in the user agent's view of time, even for events where the timestamps in question could be raised on a different machine like a remote recognition service (i.e., in a <a event for=SpeechRecognition>speechend</a> event with a remote speech endpointer).</p>
<p>Unless specified below, the ordering of the different events is undefined.
For example, some implementations may fire <a event for=SpeechRecognition>audioend</a> before <a event for=SpeechRecognition>speechstart</a> or <a event for=SpeechRecognition>speechend</a> if the audio detector is client-side and the speech detector is server-side.</p>
<dl>
<dt><dfn event for=SpeechRecognition>audiostart</dfn> event</dt>
<dd>Fired when the user agent has started to capture audio.</dd>
<dt><dfn event for=SpeechRecognition>soundstart</dfn> event</dt>
<dd>Fired when some sound, possibly speech, has been detected.
This must be fired with low latency, e.g. by using a client-side energy detector.
The <a event for=SpeechRecognition>audiostart</a> event must always have been fired before the soundstart event.</dd>
<dt><dfn event for=SpeechRecognition>speechstart</dfn> event</dt>
<dd>Fired when the speech that will be used for speech recognition has started.
The <a event for=SpeechRecognition>audiostart</a> event must always have been fired before the speechstart event.</dd>
<dt><dfn event for=SpeechRecognition>speechend</dfn> event</dt>
<dd>Fired when the speech that will be used for speech recognition has ended.
The <a event for=SpeechRecognition>speechstart</a> event must always have been fired before speechend.</dd>
<dt><dfn event for=SpeechRecognition>soundend</dfn> event</dt>
<dd>Fired when some sound is no longer detected.
This must be fired with low latency, e.g. by using a client-side energy detector.
The <a event for=SpeechRecognition>soundstart</a> event must always have been fired before soundend.</dd>
<dt><dfn event for=SpeechRecognition>audioend</dfn> event</dt>
<dd>Fired when the user agent has finished capturing audio.
The <a event for=SpeechRecognition>audiostart</a> event must always have been fired before audioend.</dd>
<dt><dfn event for=SpeechRecognition>result</dfn> event</dt>
<dd>Fired when the speech recognizer returns a result.
The event must use the {{SpeechRecognitionEvent}} interface.
The <a event for=SpeechRecognition>audiostart</a> event must always have been fired before the result event.</dd>
<dt><dfn event for=SpeechRecognition>nomatch</dfn> event</dt>
<dd>Fired when the speech recognizer returns a final result with no recognition hypothesis that meet or exceed the confidence threshold.
The event must use the {{SpeechRecognitionEvent}} interface.
The {{SpeechRecognitionEvent/results}} attribute in the event may contain speech recognition results that are below the confidence threshold or may be null.
The {{audiostart}} event must always have been fired before the nomatch event.</dd>
<dt><dfn event for=SpeechRecognition>error</dfn> event</dt>
<dd>Fired when a speech recognition error occurs.
The event must use the {{SpeechRecognitionErrorEvent}} interface.</dd>
<dt><dfn event for=SpeechRecognition>start</dfn> event</dt>
<dd>Fired when the recognition service has begun to listen to the audio with the intention of recognizing.
</dd><dt><dfn event for=SpeechRecognition>end</dfn> event</dt>
<dd>Fired when the service has disconnected.
The event must always be generated when the session ends no matter the reason for the end.</dd>
</dl>
<h4 id="speechreco-error">SpeechRecognitionErrorEvent</h4>
<p>The {{SpeechRecognitionErrorEvent}} interface is used for the <a event for=SpeechRecognition>error</a> event.</p>
<dl>
<dt><dfn attribute for=SpeechRecognitionErrorEvent>error</dfn> attribute</dt>
<dd>The errorCode is an enumeration indicating what has gone wrong.
The values are:
<dl>
<dt><dfn enum-value for=SpeechRecognitionErrorCode>"no-speech"</dfn></dt>
<dd>No speech was detected.</dd>
<dt><dfn enum-value for=SpeechRecognitionErrorCode>"aborted"</dfn></dt>
<dd>Speech input was aborted somehow, maybe by some user-agent-specific behavior such as UI that lets the user cancel speech input.</dd>
<dt><dfn enum-value for=SpeechRecognitionErrorCode>"audio-capture"</dfn></dt>
<dd>Audio capture failed.</dd>
<dt><dfn enum-value for=SpeechRecognitionErrorCode>"network"</dfn></dt>
<dd>Some network communication that was required to complete the recognition failed.</dd>
<dt><dfn enum-value for=SpeechRecognitionErrorCode>"not-allowed"</dfn></dt>
<dd>The user agent is not allowing any speech input to occur for reasons of security, privacy or user preference.</dd>
<dt><dfn enum-value for=SpeechRecognitionErrorCode>"service-not-allowed"</dfn></dt>
<dd>The user agent is not allowing the web application requested speech service, but would allow some speech service, to be used either because the user agent doesn't support the selected one or because of reasons of security, privacy or user preference.</dd>
<dt><dfn enum-value for=SpeechRecognitionErrorCode>"language-not-supported"</dfn></dt>
<dd>The language was not supported.</dd>
<dt><dfn enum-value for=SpeechRecognitionErrorCode>"phrases-not-supported"</dfn></dt>
<dd>The speech recognition model does not support phrases for contextual biasing.</dd>
</dl>
</dd>
<dt><dfn attribute for=SpeechRecognitionErrorEvent>message</dfn> attribute</dt>
<dd>The message content is implementation specific.
This attribute is primarily intended for debugging and developers should not use it directly in their application user interface.</dd>
</dl>
<h4 id="speechreco-alternative">SpeechRecognitionAlternative</h4>
<p>The SpeechRecognitionAlternative represents a simple view of the response that gets used in a n-best list.
<dl>
<dt><dfn attribute for=SpeechRecognitionAlternative>transcript</dfn> attribute</dt>
<dd>The transcript string represents the raw words that the user spoke.
For continuous recognition, leading or trailing whitespace MUST be included where necessary such that concatenation of consecutive SpeechRecognitionResults produces a proper transcript of the session.</dd>
<dt><dfn attribute for=SpeechRecognitionAlternative>confidence</dfn> attribute</dt>
<dd>The confidence represents a numeric estimate between 0 and 1 of how confident the recognition system is that the recognition is correct.
A higher number means the system is more confident.
<p class=issue>The group has discussed whether confidence can be specified in a speech-recognition-engine-independent manner and whether confidence threshold and nomatch should be included, because this is not a dialog API.
See <a href="https://lists.w3.org/Archives/Public/public-speech-api/2012Jun/0143.html">Confidence property</a> thread on public-speech-api@w3.org.</p></dd>
</dl>
<h4 id="speechreco-result">SpeechRecognitionResult</h4>
<p>The SpeechRecognitionResult object represents a single one-shot recognition match, either as one small part of a continuous recognition or as the complete return result of a non-continuous recognition.</p>
<dl>
<dt><dfn attribute for=SpeechRecognitionResult>length</dfn> attribute</dt>
<dd>The long attribute represents how many n-best alternatives are represented in the item array.</dd>
<dt><dfn method for=SpeechRecognitionResult>item(<var>index</var>)</dfn> getter</dt>
<dd>The item getter returns a SpeechRecognitionAlternative from the index into an array of n-best values.
If index is greater than or equal to length, this returns null.
The user agent must ensure that the length attribute is set to the number of elements in the array.
The user agent must ensure that the n-best list is sorted in non-increasing confidence order (each element must be less than or equal to the confidence of the preceding elements).</dd>
<dt><dfn attribute for=SpeechRecognitionResult>isFinal</dfn> attribute</dt>
<dd>The final boolean must be set to true if this is the final time the speech service will return this particular index value.
If the value is false, then this represents an interim result that could still be changed.</dd>
<dt><dfn attribute for=SpeechRecognitionResult>speechStartTime</dfn> attribute</dt>
<dd>A {{double}} representing the start of the speech segment corresponding to this recognition result, as an offset in seconds on the [=session audio timeline=].</dd>
<dt><dfn attribute for=SpeechRecognitionResult>speechEndTime</dfn> attribute</dt>
<dd>A {{double}} representing the end of the speech segment corresponding to this recognition result, as an offset in seconds on the [=session audio timeline=].</dd>
</dl>
<p class=note>
{{SpeechRecognitionResult/speechStartTime}} and {{SpeechRecognitionResult/speechEndTime}} are offsets on the [=session audio timeline=], not readings of a system clock.
They are therefore unaffected by audio output latency or by drift between an audio device clock and the system clock, and are identical whether recognition runs in real time or faster than real time.
Their precision is implementation-defined.
</p>
<h4 id="speechreco-resultlist">SpeechRecognitionResultList</h4>
<p>The SpeechRecognitionResultList object holds a sequence of recognition results representing the complete return result of a continuous recognition.
For a non-continuous recognition it will hold only a single value.</p>
<dl>
<dt><dfn attribute for=SpeechRecognitionResultList>length</dfn> attribute</dt>
<dd>The length attribute indicates how many results are represented in the item array.</dd>
<dt><dfn method for=SpeechRecognitionResultList>item(<var>index</var>)</dfn> getter</dt>
<dd>The item getter returns a SpeechRecognitionResult from the index into an array of result values.
If index is greater than or equal to length, this returns null.
The user agent must ensure that the length attribute is set to the number of elements in the array.</dd>
</dl>
<h4 id="speechreco-event">SpeechRecognitionEvent</h4>
<p>The SpeechRecognitionEvent is the event that is raised each time there are any changes to interim or final results.</p>
<dl>
<dt><dfn attribute for=SpeechRecognitionEvent>resultIndex</dfn> attribute</dt>
<dd>The resultIndex must be set to the lowest index in the "results" array that has changed.</dd>
<dt><dfn attribute for=SpeechRecognitionEvent>results</dfn> attribute</dt>
<dd>The array of all current recognition results for this session.
Specifically all final results that have been returned, followed by the current best hypothesis for all interim results.
It must consist of zero or more final results followed by zero or more interim results.
On subsequent SpeechRecognitionResultEvent events, interim results may be overwritten by a newer interim result or by a final result or may be removed (when at the end of the "results" array and the array length decreases).
Final results must not be overwritten or removed.
All entries for indexes less than resultIndex must be identical to the array that was present when the last SpeechRecognitionResultEvent was raised.
All array entries (if any) for indexes equal or greater than resultIndex that were present in the array when the last SpeechRecognitionResultEvent was raised are removed and overwritten with new results.
The length of the "results" array may increase or decrease, but must not be less than resultIndex.
Note that when resultIndex equals results.length, no new results are returned, this may occur when the array length decreases to remove one or more interim results.</dd>
</dl>
<h4 id="speechreco-phrase">SpeechRecognitionPhrase</h4>
<p>The SpeechRecognitionPhrase object represents a phrase for contextual biasing and has the following internal slots:</p>
<dl dfn-type=attribute dfn-for="SpeechRecognitionPhrase">
: <dfn>[[phrase]]</dfn>
::
A {{DOMString}} representing the text string to be boosted. The initial value is null.
An empty value is allowed but should be ignored by the speech recognition model.
</dl>
<dl dfn-type=attribute dfn-for="SpeechRecognitionPhrase">
: <dfn>[[boost]]</dfn>
::
A float representing approximately the natural log of the number of times more likely the website thinks this phrase is
than what the speech recognition model knows.
A valid boost must be a float value inside the range [0.0, 10.0], with a default value of 1.0 if not specified.
A boost of 0.0 means the phrase is not boosted at all, and a higher boost means the phrase is more likely to appear.
A boost of 10.0 means the phrase is extremely likely to appear and should be rarely set.
</dl>
<dl>
<dt><dfn constructor for=SpeechRecognitionPhrase>SpeechRecognitionPhrase(|phrase|, |boost|)</dfn> constructor</dt>
<dd>
When this constructor is invoked, run the following steps:
1. If |boost| is smaller than 0.0 or greater than 10.0, throw a {{SyntaxError}} and abort these steps.
1. Let |phr| be a new object of type {{SpeechRecognitionPhrase}}.
1. Set |phr|.{{[[phrase]]}} to be the value of |phrase|.
1. Set |phr|.{{[[boost]]}} to be the value of |boost|.
1. Return |phr|.
</dd>
<dt><dfn attribute for=SpeechRecognitionPhrase>phrase</dfn> attribute</dt>
<dd>This attribute returns the value of {{[[phrase]]}}.</dd>
<dt><dfn attribute for=SpeechRecognitionPhrase>boost</dfn> attribute</dt>
<dd>This attribute returns the value of {{[[boost]]}}.</dd>
</dl>
<h4 id="speechreco-speechgrammar">SpeechGrammar</h4>
<p>The SpeechGrammar object represents a container for a grammar.</p>
<p class=note>Grammar support has been deprecated and removed. The grammar objects remain in the spec for backwards compatibility purposes only and do not affect speech recognition.</p>
<p>This structure has the following attributes:</p>
<dl>
<dt><dfn attribute for=SpeechGrammar>src</dfn> attribute</dt>
<dd>The required src attribute is the URI for the grammar.</dd>
<dt><dfn attribute for=SpeechGrammar>weight</dfn> attribute</dt>
<dd>The optional weight attribute controls the weight that the speech recognition service should use with this grammar.
By default, a grammar has a weight of 1.
Larger weight values positively weight the grammar while smaller weight values make the grammar weighted less strongly.</dd>
</dl>
<h4 id="speechreco-speechgrammarlist">SpeechGrammarList</h4>
<p>The SpeechGrammarList object represents a collection of SpeechGrammar objects.
This structure has the following attributes:</p>
<p class=note>Grammar support has been deprecated and removed. The grammar objects remain in the spec for backwards compatibility purposes only and do not affect speech recognition.</p>
<dl>
<dt><dfn attribute for=SpeechGrammarList>length</dfn> attribute</dt>
<dd>The length attribute represents how many grammars are currently in the array.</dd>
<dt><dfn method for=SpeechGrammarList>item(<var>index</var>)</dfn> getter</dt>
<dd>The item getter returns the SpeechGrammar at <var>index</var> in the array of grammars, or null if <var>index</var> is greater than or equal to the length attribute.
The user agent must ensure that the length attribute is set to the number of elements in the array.
The user agent must ensure that the index order from smallest to largest matches the order in which grammars were added to the array.</dd>
<dt><dfn method for=SpeechGrammarList>addFromURI(<var>src</var>, <var>weight</var>)</dfn> method</dt>
<dd>This method appends a grammar to the grammars array parameter based on URI.
The URI for the grammar is specified by the <var>src</var> parameter, which represents the URI for the grammar.
Note, some services may support builtin grammars that can be specified by URI.
The <var>weight</var> parameter represents this grammar's weight relative to the other grammar.
<dt><dfn method for=SpeechGrammarList>addFromString(<var>string</var>, <var>weight</var>)</dfn> method</dt>
<dd>This method appends a grammar to the grammars array parameter based on text.
The content of the grammar is specified by the <var>string</var> parameter.
This content should be encoded into a data: URI when the SpeechGrammar object is created.
The <var>weight</var> parameter represents this grammar's weight relative to the other grammar.
</dl>
<h3 id="tts-section">The SpeechSynthesis Interface</h3>
<p>The SpeechSynthesis interface is the scripted web API for controlling a text-to-speech output.</p>
<pre class="idl">
[Exposed=Window]
interface SpeechSynthesis : EventTarget {
readonly attribute boolean pending;
readonly attribute boolean speaking;
readonly attribute boolean paused;
attribute EventHandler onvoiceschanged;
undefined speak(SpeechSynthesisUtterance utterance);
undefined cancel();
undefined pause();
undefined resume();
sequence<SpeechSynthesisVoice> getVoices();
};
partial interface Window {
[SameObject] readonly attribute SpeechSynthesis speechSynthesis;
};
[Exposed=Window]
interface SpeechSynthesisUtterance : EventTarget {
constructor(optional DOMString text);
attribute DOMString text;
attribute DOMString lang;
attribute SpeechSynthesisVoice? voice;
attribute float volume;
attribute float rate;
attribute float pitch;
attribute EventHandler onstart;
attribute EventHandler onend;
attribute EventHandler onerror;
attribute EventHandler onpause;
attribute EventHandler onresume;
attribute EventHandler onmark;
attribute EventHandler onboundary;
};
[Exposed=Window]
interface SpeechSynthesisEvent : Event {
constructor(DOMString type, SpeechSynthesisEventInit eventInitDict);