Skip to main content

Inclusion (Audio Guide / TTS)

Hosanna provides an audio guide pipeline with priorities and flushing, backed by an ITextToSpeechManager that proxies the Roku system and adds queueing and debug support.

Overview

info

Accessibility ensures your TV app is usable by everyone, including users who rely on screen readers or audio cues. Hosanna UI integrates accessibility patterns inspired by platforms like SwiftUI (tvOS) and React Native for TV.

By default, non-semantic views (like containers or spacers) do not announce anything to avoid clutter. Meaningful elements like text labels, buttons, and media items can provide spoken feedback through a dedicated accessibility label.

Getting Speech in Dev (Web)

  • Run with ?textToSpeech=true to enable TTS in the browser emulator.
  • The debug extension shows the queue, current item, and timings; it also provides tools to flush/inspect.

View Fields & Labels

Views expose two fields for the audio guide:

  • audioGuideHint: a brief suffix used by components to construct spoken text.
  • audioGuideItem: an optional IAudioGuideItem you can set directly.

For simple labels, provide a short, human-readable string via audioGuideHint.

Example

Button({ text: 'Rent', audioGuideHint: 'Rent this movie' })

Default Fallback Behavior

If audioGuideLabel is not provided:

  • Text: falls back to "Button [text field]".
  • Button: falls back to "Button [text field]".
  • ComboBox: falls back to "ComboBox [value field]".
  • Image: falls back to "Image [id field]".
  • Non-semantic containers: speak nothing by default.

Custom Views

You can override the default behavior by implementing getAudioGuideItem() in your view to return an IAudioGuideItem.

This provides full control over what your component announces when focused.

Priorities, Flushing, and Timing

To avoid rapid, repetitive speech while navigating quickly between controls:

  • The focus manager introduces a short delay (typically 250–400ms) before announcing a label.
  • If the user moves focus before the delay completes, the previous label is cancelled.

Internally, items are queued with a priority (default 10). Higher priority interrupts equal-or-lower priority items. When flushPrevious is true (default at the manager unless overridden), the manager flushes queued items with priority ≥ the incoming item’s priority and interrupts the current item at or below that level.

Programmatic speech helper:

static sayText(text: string, priority?: number, origin?: IHosannaView<ViewState>, flushPrevious?: boolean): void {
if (priority === undefined) priority = 10;
if (flushPrevious === undefined) flushPrevious = false;
const tts = AppUtils.resolve<ITextToSpeechManager>('textToSpeechManager');
tts.sayAudioItem({ text, priority, flushPrevious });
}

Advanced Enhancements

You can further improve accessibility by supporting:

  • Localization of spoken strings
  • Semantic roles (e.g. "button", "image") for internal prioritization
  • Focus zones (e.g. rows or grids that announce a group label before items)
  • Live region updates to announce dynamic changes in content

Best Practices

  • Don’t rely on internal IDs or variable names as spoken text.
  • Provide a meaningful audioGuideHint for buttons and actions.
  • Keep labels concise, clear, and user-facing.
  • Use structured override methods for complex or dynamic views.

Summary

Element TypeSpoken Label Defaults
Textsupply audioGuideHint
Buttonuses text + audioGuideHint
Custom Componentsoverride getAudioGuideItem()
ContainersReturn "" unless explicitly labeled
tip

You can preview and debug spoken labels in your app using Hosanna’s focus manager logs or audio simulation tools.