Home

Settings

Customize player settings, captions, and global preferences with the RIXL Media SDK

The @rixl/media package exposes a settingsStore that powers the player's global preferences: volume, playback speed, and caption appearance. Settings are automatically persisted to localStorage.

Reading and Updating Settings

import {settingsStore, defaultSettings} from "@rixl/media";

// Current settings
const current = settingsStore.getSettings();

// Update global volume
settingsStore.setVolume(0.8);

// Update playback speed
settingsStore.setPlaybackSpeed(1.25);

// Toggle captions
settingsStore.setAllowCaptions(true);

// Reset caption appearance to defaults
settingsStore.resetCaptionSettings();

Each setter updates the nanostore state, persists the new state to localStorage, and returns the clamped/normalized value that was actually stored.

Caption Customization

settingsStore.setCaptionFontFamily("proportional_serif");
settingsStore.setCaptionFontSize(150); // one of 50, 100, 150, 200
settingsStore.setCaptionFontColor("#ffff00"); // one of the supported colors
settingsStore.setCaptionBGColor("#000000");
settingsStore.setCaptionBGOpacity(75); // 0 - 100
settingsStore.setCaptionCharacterEdgeStyle("drop-shadow");

Validation and Storage

For custom settings panels, you can load and validate raw objects against the SDK schema:

import {loadSettings, saveSettings, validateSettings} from "@rixl/media";

const restored = loadSettings();
const validated = validateSettings({volume: 2.5}); // clamped to valid range
saveSettings(validated);

Constants

Use these constants when building a settings UI:

const FONT_FAMILIES: Record<string, string> = {
  monospace_serif: '"Courier New", Courier, ...',
  proportional_serif: '"Times New Roman", Times, ...',
  monospace_sans: '"Deja Vu Sans Mono", "Lucida Console", ...',
  proportional_sans: "Roboto, Arial, Helvetica, ...",
  casual: '"Comic Sans MS", Impact, ...',
  cursive: '"Monotype Corsiva", "URW Chancery L", ...',
  small_caps: 'Arial, Helvetica, Verdana, "Marcellus SC", ...',
};

const FONT_SIZES: number[] = [50, 100, 150, 200];

const COLORS: Record<string, string> = {
  white: "#ffffff",
  yellow: "#ffff00",
  green: "#00ff00",
  cyan: "#00ffff",
  blue: "#0000ff",
  magenta: "#ff00ff",
  red: "#ff0000",
  black: "#000000",
};

const EDGE_STYLES: string[] = ["none", "drop-shadow", "raised", "depressed", "outline"];

const PLAYBACK_SPEEDS: number[] = [0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0];

const LANG_TYPES: string[] = ["off", "eng", "auto"];

SettingsState Interface

interface SettingsState {
  volume: number;
  playbackSpeed: number;
  customPlayback: number;
  allowCaptions: boolean;
  captionPosition: {x: number; y: number};
  captionLang: "off" | "eng" | "auto";

  captionFontFamily: string;
  captionFontSize: number;
  captionFontColor: string;
  captionFontOpacity: number;

  captionBGColor: string;
  captionBGOpacity: number;

  captionWindowColor: string;
  captionWindowOpacity: number;

  captionCharacterEdgeStyle: string;
  selectedLanguageCode?: string;
  globalMutedPreference: boolean;
  preferredQuality?: number;
  preferredAudioLanguage?: string;
  preferredSubtitleLanguage?: string;
}

Default Values

const defaultSettings: SettingsState = {
  volume: 1.0,
  playbackSpeed: 1.0,
  customPlayback: 1.0,
  allowCaptions: false,
  captionPosition: {x: 20, y: 90},
  captionLang: "off",
  captionFontFamily: "proportional_sans",
  captionFontSize: 100,
  captionFontColor: "#ffffff",
  captionFontOpacity: 100,
  captionBGColor: "#000000",
  captionBGOpacity: 75,
  captionWindowColor: "#000000",
  captionWindowOpacity: 0,
  captionCharacterEdgeStyle: "none",
  globalMutedPreference: false,
};