← SpeechRecognitionResult Timestamps (WebSpeech API)

v153 · dev trial · attribute

SpeechRecognition­Result.audio­StartTime

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.

Developer trial

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

TypeDOMHighResTimeStamp? (nullable double; milliseconds per High Resolution Time)
MeaningStart 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 casenull 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)
PrecisionFloored to a multiple of 2 ms (FuzzTimestamp, kFuzzInterval = base::Milliseconds(2)) — an anti-fingerprinting quantization required by the spec PR's privacy clause
Engine semanticsIn 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)
Source: PR #192; speech_recognition_result.cc; 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.

Source: PR #192 (null contract); getter implementation

context and exposure

Source: speech_recognition.cc; Web Speech API

lifecycle

  1. The recognition engine emits a result with timing information (TimingInformation.audio_start_time in the mojom struct).
  2. Blink stores it on the result object at construction (SpeechRecognitionResult::Create).
  3. Each getter call returns the stored value floored to 2 ms, or null if unset. The value for a given result object does not change afterwards — results are immutable snapshots delivered through the event.
  4. 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.
Source: speech_recognition_result.cc; speech_recognition.cc

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.

BrowserSupportEvidence
Chrome / Edge (Chromium)Dev trial 153 — WebSpeechTimestamps flag (experimental, not public)listing; flag record
FirefoxNo signalChromeStatus API record
SafariNo signalChromeStatus API record
Source: as linked per row

security and privacy

Source: PR #192 privacy clause; speech_recognition_result.cc

see also