← SpeechRecognitionResult Timestamps (WebSpeech API)
v153 · dev trial · attribute
SpeechRecognitionResult.audioStartTime
A nullable DOMHighResTimeStamp reporting the start of the source-audio segment that produced this recognition result, in milliseconds relative to the time origin, quantized to 2 ms precision. null when the recognition engine does not supply segment timestamps. Developer trial in Chrome 153 behind the WebSpeechTimestamps flag.
Behind --enable-blink-features=WebSpeechTimestamps (flag experimental, not public — no chrome://flags entry, no origin trial). The defining spec change, WICG/speech-api PR #192, is open; the attribute can change in review. Detect with 'audioStartTime' in SpeechRecognitionResult.prototype. See the overview warn-block.
syntax
readonly attribute DOMHighResTimeStamp? audioStartTime;
Proposed spec text (PR #192, quoted verbatim): “A nullable DOMHighResTimeStamp representing the start of the audio segment corresponding to this recognition result, in milliseconds relative to the time origin. Returns null if the underlying recognition engine does not support audio segment start timestamps.”
The shipping Chromium IDL gates the same member on the runtime feature (speech_recognition_result.idl):
[RuntimeEnabled=WebSpeechTimestamps] readonly attribute DOMHighResTimeStamp? audioStartTime;
Source: PR #192 diff; speech_recognition_result.idl
value
| Type | DOMHighResTimeStamp? (nullable double; milliseconds per High Resolution Time) |
|---|---|
| Meaning | Start of the audio segment this result was transcribed from, relative to the time origin — the same clock as performance.now() and Event.timeStamp, so values compare directly |
| Null case | null when the underlying recognition engine does not support audio segment start timestamps (per spec PR) — in Chromium, when the engine's TimingInformation.audio_start_time was absent (getter returns std::nullopt) |
| Precision | Floored to a multiple of 2 ms (FuzzTimestamp, kFuzzInterval = base::Milliseconds(2)) — an anti-fingerprinting quantization required by the spec PR's privacy clause |
| Engine semantics | In Chromium's pipeline the value originates as “start time in audio time from the start of the SODA session” — the amount of audio input into the on-device engine when the segment begins (speech_recognition.mojom) |
inputs
None. This is a read-only attribute: no setter, no parameters, no options. What the engine supplies is what the getter returns (after quantization); script cannot influence the value other than by choosing a recognition engine/backend that supports segment timestamps.
Source: PR #192 (readonly attribute, no associated setter or algorithm inputs)errors
No error surface. The getter never throws: unsupported engines yield null, not an exception. Reading the attribute on a browser without the runtime flag fails earlier — the member does not exist on the prototype at all — so feature-detection ('audioStartTime' in SpeechRecognitionResult.prototype) is the correct guard, not try/catch.
context and exposure
- Exposed on every
SpeechRecognitionResult— the objects inSpeechRecognitionEvent.resultsdelivered toresultevent handlers — when theWebSpeechTimestampsruntime feature is enabled. - The host Web Speech API requires a secure context and microphone permission (or a
MediaStreamTracksource); these attributes add no new requirements of their own. - Both interim (
isFinal === false) and final results can carry the value: Chromium's aggregation path constructs provisional and final results from the same engine struct (speech_recognition.cc).
lifecycle
- The recognition engine emits a result with timing information (
TimingInformation.audio_start_timein the mojom struct). - Blink stores it on the result object at construction (
SpeechRecognitionResult::Create). - Each getter call returns the stored value floored to 2 ms, or
nullif unset. The value for a given result object does not change afterwards — results are immutable snapshots delivered through the event. - Interim results for the same utterance may be replaced by later interim/final results with updated bounds as the engine refines its hypothesis; read the value from the result object you are actually rendering.
examples
if (!('audioStartTime' in SpeechRecognitionResult.prototype)) {
// Flag off or engine too old — fall back to untimed captions.
}
recognition.onresult = (event) => {
const result = event.results[event.resultIndex];
if (result.audioStartTime !== null) {
// Same clock as performance.now(): position the caption on the timeline.
showCaptionAt(result.audioStartTime / 1000, result[0].transcript);
}
};
Source: gendn-derived from the documented semantics (PR #192); the feature-detect pattern is from the overview
browser compatibility
Interim table. No BCD key exists for this member (verified 2026-07-29); rows compiled from primary sources.
| Browser | Support | Evidence |
|---|---|---|
| Chrome / Edge (Chromium) | Dev trial 153 — WebSpeechTimestamps flag (experimental, not public) | listing; flag record |
| Firefox | No signal | ChromeStatus API record |
| Safari | No signal | ChromeStatus API record |
security and privacy
- High-precision timing is a hardware-fingerprinting vector; the spec PR requires fuzzing/precision reduction before script exposure (“e.g. by rounding to 2ms precision”) and Chromium floors values to 2 ms multiples in the getter.
- The attribute reveals nothing beyond timing metadata about audio the page already submitted for recognition under the existing permission model — no new audio, device, or engine access.
- A
nullresult distinguishes “engine cannot time segments” from “segment starts at 0”, preventing fabricated-zero misreads.
see also
- SpeechRecognitionResult Timestamps — overview (feature page)
audioEndTime— the segment end, and the latency-computation input- Explainer — SpeechRecognitionResult timestamps (motivation + usage patterns)
- Chrome Platform Status — feature 5811907077472256
- MDN — SpeechRecognitionResult (no coverage of this member, 2026-07-29)
- Showcase — caption timeline demo (HEAD-checked 200, 2026-07-29)