LectureLight

pending

by Greg Baker

Professional presentation and teleprompter integration.

1 starsUpdated 1mo agoMITDiscovered via Obsidian Unofficial Plugins
View on GitHub

LectureLight

Professional presentation console for Obsidian. Turn any Markdown note into a slide deck with a built-in teleprompter, traffic-light timer, film strip, speaker notes, and audience-facing stage window.


Authorship and contributors

This plugin was conceptualized by Greg Baker, who also wrote parts of the implementation. The majority of production code was co-developed with AI coding assistants, with Codex and Gemini acting as principal co-contributors. Claude is not credited as a code contributor on this project, though some early defects originated from Claude-generated suggestions that were later fixed.


Features

Slide authoring

Write slides directly in any Markdown note using fenced :::slide blocks. The plugin parses them live as you edit — no save or reload required.

:::slide Introduction
# Hello, world

Opening remarks go here.
:::

:::slide Key points
- First point
- Second point
:::

Speaker notes

Add presenter-only notes to any slide using :::notes blocks. Notes appear in the teleprompter in a distinct teal callout and are never transmitted to the stage window.

Positional — attaches to the slide immediately above:

:::slide [Intro]
# Hello, world
:::

:::notes
Remember to pause here and ask if anyone has questions.
Start with the story about the conference in Austin.
:::

Label-matched — can appear anywhere in the document, matched by slide label:

:::notes [Key points]
Emphasize the third bullet. The audience usually pushes back here — have the Q4 data ready.
:::

Presenter console

A dedicated side panel with everything you need to run a talk:

PanelWhat it does
Navigation← → buttons + slide counter; keyboard ← → and Page Up/Down also work
TeleprompterFull script with "Slide X of Y" markers; click any marker to jump; speaker notes shown below each trigger
Stage preview16:9 thumbnail of the current slide in the sidebar
Film stripCollapsible thumbnail row of every slide at the bottom

Keyboard shortcuts (presenter console)

KeyAction
/ Page UpPrevious slide
/ Page DownNext slide
to slide 1 (timer running)Resets elapsed time to zero

Microphone permission

The recording feature requires microphone access. Obsidian will prompt for permission the first time you click Start or Test mic. If you deny access, click the permission icon in your browser/OS menu bar to re-allow it, then click Test mic again.

Session recording

Start a session with Start to record your microphone alongside the presentation. When you click Stop, the plugin:

  1. Assembles the audio into a single file (WebM/Opus preferred, MP4 fallback).
  2. Writes a .session.json sidecar containing every slide-change event with wall-clock timestamps and elapsed time.
  3. Saves both files to LectureLight/Recordings/ inside your vault (configurable in Settings → LectureLight).
  4. Appends a ## LectureLight session — {date} section to the active note with Obsidian links to both files so you can play back the audio and open the log without leaving the vault.

Use Test mic to check your microphone level (shown as a live bar in the recording panel) without starting a session. The mic is released automatically when the test ends or the pane is closed.

If microphone permission is denied, a clear error message is shown in the recording panel and the session timer continues without audio.

Traffic-light timer

Counts down from your target time. Color changes signal how you're tracking:

ColorStateTrigger
NeutralReadyTimer not started
Green #059669On trackTimer running, above warning threshold
Orange #fc7e14Warning≤ warning minutes remaining
Red #dc3444Wrap up≤ wrapup minutes remaining
Red ↔ Orange pulseOvertimePast zero

Configure per note with a :::lecturelight block, or set defaults in Settings → LectureLight:

:::lecturelight
target: 45
warning: 40
wrapup: 43
:::

Values are in minutes. The block is optional — plugin settings are used when it is absent. Navigating back to slide 1 while the timer is running resets it automatically.

Stage window

Click ⊡ Stage in the presenter console header to open a separate audience-facing window.

  • Opens as a native Obsidian popout at 1280 × 720
  • Scales to any resolution up to 4K via GPU-accelerated CSS transforms
  • Slides update in real time as you navigate (via BroadcastChannel — no network required)
  • ⊡ Go fullscreen · F button is always visible when windowed; disappears in fullscreen
  • Press Esc to exit fullscreen — button reappears so you can re-enter on any display
  • Press F to toggle fullscreen from the keyboard
  • The ⊡ Stage button pulses amber while the stage is live; returns to inactive when the window closes

Stage theme

The button in the presenter console header switches the stage between dark (default) and light backgrounds. The theme is applied instantly and is re-sent automatically when a new stage window opens.


Installation

  1. Download main.js, manifest.json, and styles.css from the latest release.
  2. Create a folder named lecturelight inside your vault's .obsidian/plugins/ directory.
  3. Copy the three files into that folder.
  4. Reload Obsidian and enable LectureLight in Settings → Community plugins.

Development

npm install
npm run dev      # watch mode (rebuilds on save)
npm run build    # production build
npm test         # 53 Vitest unit tests (parser + wikilinks)
npm run lint     # ESLint (0 errors expected)

Copy main.js, manifest.json, and styles.css into your vault's plugin folder after each build to test live.


Architecture

src/
  main.ts                      # Plugin lifecycle, view and command registration
  view.tsx                     # LectureLightView — Obsidian ItemView wrapper for the console
  stageView.tsx                # LectureLightStageView — audience-facing popout window
  presenterStyles.ts           # All console CSS, injected programmatically at load
  settings.ts                  # Settings interface, defaults, settings tab
  types.ts                     # ParseResult, Slide, TimerSettings
  components/
    PresenterConsole.tsx        # Root console component — layout, state, stage/recording control
    TrafficLightTimer.tsx       # Countdown timer with color states
    FilmStrip.tsx               # Thumbnail row
    Teleprompter.tsx            # Scrollable script with slide triggers and speaker notes
  hooks/
    useAudioRecorder.ts         # MediaRecorder + Web Audio level meter hook
  lib/
    parser.ts                   # :::slide / :::lecturelight / :::notes block parser
    logger.ts                   # Session event log (slide timestamps, start/stop events)
    vaultSave.ts                # Save audio + session JSON to vault; append note links
    wikilinks.ts                # [[wikilink]] resolver
  __tests__/
    parser.test.ts              # 40 parser unit tests
    wikilinks.test.ts           # 8 wikilink unit tests
    setup.test.ts               # Environment sanity check

BroadcastChannel message protocol

All inter-window communication uses BroadcastChannel('lecturelight-stage'). No network required.

Message typePayloadSent when
slide-change{ htmlContent, index, total, label }Slide advances; stage window first opens
theme-change{ light: boolean }☀ button toggled; stage window first opens

Roadmap

Backlog

ItemDescription
Slide transitionsOptional CSS transition between slides on the stage (fade, slide-left) controlled by a per-deck :::lecturelight setting
Remote clicker supportMap HID presentation remote buttons (Next, Back, Black screen) to plugin commands via Obsidian's hotkey system
Presenter notes on secondary displayA mirror of the presenter console (timer + notes only) sized for a laptop screen while the stage runs fullscreen on the projector
PDF exportPrint each slide as a page to a PDF using Electron's webContents.printToPDF API
Community plugin submissionPrepare manifest, icon, and changelog for the official Obsidian community plugin registry

License

MIT

For plugin developers

Search results and similarity scores are powered by semantic analysis of your plugin's README. If your plugin isn't appearing for searches you'd expect, try updating your README to clearly describe your plugin's purpose, features, and use cases.