# OpenMAIC Playback Engine State Machine: The Four Core EngineMode States

> Explore the OpenMAIC Playback Engine state machine and its four core states idle playing paused and live Understand how these engine modes manage lecture streaming and live discussions

- Repository: [MAIC/OpenMAIC](https://github.com/THU-MAIC/OpenMAIC)
- Tags: internals
- Published: 2026-09-03

---

**The OpenMAIC Playback Engine state machine operates through four primary states—`idle`, `playing`, `paused`, and `live`—defined in [`lib/playback/types.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/playback/types.ts) to manage transitions between lecture streaming and live discussions.**

The OpenMAIC repository implements a deterministic state machine to orchestrate AI-driven lecture playback and real-time user interactions. Understanding the **Playback Engine state machine** is critical for developers extending the platform, as it governs all transitions from pre-recorded content delivery to interactive discussion modes.

## Core States in the Playback Engine State Machine

The state definitions reside in [`lib/playback/types.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/playback/types.ts) as the **`EngineMode`** type. These four states represent the complete lifecycle of a playback session.

### Idle State

The **`idle`** state indicates no active playback is running. In this mode, the engine awaits initialization commands while maintaining loaded scene data and action engines in memory. The engine enters this state immediately upon instantiation and returns to it after discussions conclude via `handleEndDiscussion()`.

### Playing State

The **`playing`** state represents active streaming of lecture actions, including speech synthesis, visual effects, and avatar animations. When the engine transitions to `playing`, the `AudioPlayer` and `ActionEngine` begin executing scheduled scene content. This state supports interruption handlers that can pivot the system into live discussion mode.

### Paused State

The **`paused`** state suspends playback activity while preserving the current session context. Transitions into `paused` occur when users explicitly pause content or when the system awaits discussion responses. From `paused`, the engine can resume to `playing` or transition to `live` depending on pending interaction flags.

### Live State

The **`live`** state activates when the engine switches from passive playback to active discussion mode, typically triggered by `handleUserInterrupt()`. In this state, the engine maintains bidirectional communication with users, tracking **`TopicState`** sub-states (`pending`, `active`, `closed`) while retaining the ability to pause and resume the underlying lecture context.

## State Machine Transitions and Methods

State transitions in [`lib/playback/engine.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/playback/engine.ts) follow explicit rules implemented through public methods. The file contains a detailed ASCII state diagram documenting these flows.

```text
                  start()                  pause()
   idle ──────────────────→ playing ──────────────→ paused
     ▲                         ▲                       │
     │                         │  resume()             │
     │                         └───────────────────────┘
     │
     │  handleEndDiscussion()
     │                         confirmDiscussion()
     │                         / handleUserInterrupt()
     │                              │
     │                              ▼         pause()
     └──────────────────────── live ──────────────→ paused
                                 ▲                    │
                                 │ resume / user msg  │
                                 └────────────────────┘

```

### Primary Transition Methods

- **`start()`**: Transitions `idle` → `playing` to begin lecture streaming.
- **`continuePlayback()`**: Alternative entry from `idle` → `playing` used when resuming after discussions.
- **`pause()`**: Moves `playing` or `live` → `paused` to halt active processing.
- **`resume()`**: Returns `paused` → `playing` (or `live` if discussion was pending).
- **`handleUserInterrupt()`**: Switches `playing`/`paused` → `live` when users initiate proactive discussions.
- **`handleEndDiscussion()`**: Terminates `live` mode and returns to `idle`.

## Internal Sub-States: TopicState

During `live` or `paused` modes, the engine tracks **`TopicState`** to manage discussion lifecycle. This comprises three internal values—`pending`, `active`, and `closed`—that operate beneath the top-level `EngineMode`. While `TopicState` dictates UI rendering and conversation flow in [`components/edit/PlaybackChromeRoot.tsx`](https://github.com/THU-MAIC/OpenMAIC/blob/main/components/edit/PlaybackChromeRoot.tsx), it does not alter the primary engine state machine.

## Implementation Files and Architecture

The complete state machine implementation spans four critical files:

| File | Primary Role |
|------|--------------|
| [`lib/playback/types.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/playback/types.ts) | Defines `EngineMode` type (`idle`, `playing`, `paused`, `live`) and `TopicState`. |
| [`lib/playback/engine.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/playback/engine.ts) | Contains state-machine logic, transition methods, and state-diagram documentation. |
| [`lib/playback/derived-state.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/playback/derived-state.ts) | Derives UI-visible playback views from current `EngineMode`. |
| [`components/edit/PlaybackChromeRoot.tsx`](https://github.com/THU-MAIC/OpenMAIC/blob/main/components/edit/PlaybackChromeRoot.tsx) | UI component instantiating `PlaybackEngine` and handling `onModeChange` callbacks. |

## Practical Code Examples

The following TypeScript snippets demonstrate driving the engine through its complete state lifecycle:

```typescript
import { PlaybackEngine } from 'lib/playback/engine';

// Initialize with scenes, action engine, audio, and callbacks
const engine = new PlaybackEngine(scenes, actionEngine, audioPlayer, callbacks);

// 1️⃣ Start playback: idle → playing
engine.start();

// 2️⃣ Pause playback: playing → paused
engine.pause();

// 3️⃣ Resume playback: paused → playing
engine.resume();

// 4️⃣ User initiates discussion: playing → live
engine.handleUserInterrupt('User asks a question');

// 5️⃣ End discussion and reset: live → idle
engine.handleEndDiscussion();

```

## Summary

- The **Playback Engine state machine** in OpenMAIC utilizes four primary states (`idle`, `playing`, `paused`, `live`) defined in [`lib/playback/types.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/playback/types.ts).
- State transitions occur through explicit methods in [`lib/playback/engine.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/playback/engine.ts): `start()`, `pause()`, `resume()`, `handleUserInterrupt()`, and `handleEndDiscussion()`.
- The **`live`** mode supports interactive discussions while maintaining internal **`TopicState`** tracking.
- UI components react to state changes via callbacks defined in [`components/edit/PlaybackChromeRoot.tsx`](https://github.com/THU-MAIC/OpenMAIC/blob/main/components/edit/PlaybackChromeRoot.tsx).

## Frequently Asked Questions

### What is the difference between the idle and paused states in the Playback Engine?

The **`idle`** state indicates the engine is completely inactive with no loaded playback context, typically occurring after initialization or after `handleEndDiscussion()` completes. The **`paused`** state preserves active playback context including current timestamp and scene data, allowing seamless resumption without reloading content.

### How does the engine transition from playing to live mode?

The engine transitions from **`playing`** to **`live`** via the `handleUserInterrupt()` method, which is triggered when users join proactive discussions or send messages requiring real-time response. This transition maintains the lecture's paused position in memory while switching processing priority to the discussion handler.

### What is TopicState and how does it relate to EngineMode?

**`TopicState`** is an internal sub-state (`pending`, `active`, `closed`) tracked during discussions while the engine remains in **`live`** or **`paused`** modes. Unlike `EngineMode`, which controls the top-level playback behavior, `TopicState` manages conversation lifecycle and UI rendering without affecting the core state machine transitions.

### Which file contains the state machine transition logic?

The complete state machine implementation, including all transition methods and the ASCII state diagram, resides in **[`lib/playback/engine.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/playback/engine.ts)**. This file orchestrates mode changes while [`lib/playback/types.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/playback/types.ts) provides the type definitions for `EngineMode` and related state interfaces.