Files
gnommoeditor/glitchplayer-integration-insights.md
T

13 KiB

GlitchPlayer Integration Insights For GnommoEditor

This note is based on reading the current GnommoEditor frontend and backend, and comparing it to the current GlitchPlayer public API and data contracts.

Short Version

GnommoEditor and GlitchPlayer are already close enough to integrate cleanly, but there are two different integration cases and they should not be solved with the exact same component:

  1. Full presentation playback / slide-targeted preview inside the editor
  2. Lightweight slide thumbnails inside the slide list and editing UI

The full player case is almost ready now.

The thumbnail case should get its own dedicated exported component from GlitchPlayer instead of embedding the full video player at tiny sizes.

What Already Lines Up Well

On the editor side

These files already create a strong seam for player integration:

The editor already stores:

  • component_key
  • props
  • display_mode
  • presenter_notes
  • start_time_sec
  • end_time_sec
  • ordered narration segments

That is fundamentally the right shape.

On the player side

These files define the reusable runtime surface:

The player already supports:

  • full playback mode
  • mode="slide-preview"
  • targetSlideId
  • shared slide contract types
  • registry-driven slide rendering

That means the full preview case is mostly a data-shaping and packaging task, not a product rethink.

Main Mismatches Right Now

1. Editor template keys do not match player template keys

The editor currently uses older local template definitions in src/data/slideTemplates.js, including keys like:

  • TitleSlide
  • ContentSlide
  • BulletSlide
  • ImageSlide
  • QuoteSlide

The player currently uses shared contract keys from packages/slide-contracts/src/templates.ts:

  • SquareYellow
  • FullscreenSplit
  • EquationFocus
  • QuoteImage
  • ChartSingle
  • ProcessFlow
  • DefinitionCard

This is the most important mismatch to fix first.

2. The editor export route is close, but not rich enough yet

The current export route in backend/src/routes/videos.js at GET /api/videos/:id/export already builds a GlitchPlayer-style payload, but it is still missing some fields the player will want for deeper integration:

  • slide id
  • segment id
  • glitch slide id
  • orientation
  • variant arrays beyond a single score-1 candidate
  • latexString on equation slides as first-class data

Right now the route mostly emits one synthetic candidate per slide:

  • componentKey: s.component_key
  • props: s.props || {}
  • score: 1

That is enough for a first playback integration, but not enough for a mature editor + player loop.

3. The thumbnail use case is not the same thing as slide preview mode

mode="slide-preview" in GlitchPlayer is useful for previewing a chosen slide in context, but it is still fundamentally a player runtime with:

  • stage layout
  • video region
  • scrubber and chrome behavior
  • gesture state

For editor thumbnails, that is too heavy.

What the editor really needs is a dedicated slide-only renderer.

Case 1: Full player integration inside GnommoEditor

Use GlitchPlayer inside the editor for:

  • a presentation preview panel
  • a slide-targeted preview panel
  • a “play current presentation” mode
  • a “jump to this slide in player” editing workflow

In GnommoEditor, add a React wrapper component such as:

  • src/components/GlitchPlayerPanel.jsx

That wrapper should:

  • fetch a player-ready presentation JSON object from the backend
  • pass the presentation into GlitchPlayer
  • supply the default slide registry
  • own any editor-specific surrounding chrome

Keep the current export route as the starting point, but rename or mirror it to a more intentional player route:

  • GET /api/presentations/:presentationId

or

  • GET /api/videos/:id/player

That keeps the seam aligned with GlitchPlayer naming and makes later migration into GnommoWeb or other runtimes easier.

Required payload upgrades

The backend route should emit this minimum shape consistently:

{
  id: string;
  title: string;
  version: string;
  durationSec: number;
  segments: Array<{
    id: string;
    src: string;
    startTimeSec: number;
    durationSec: number;
  }>;
  slides: Array<{
    id: string;
    startTimeSec: number;
    endTimeSec?: number;
    displayMode: "square" | "fullscreen";
    glitchSlides: Array<{
      id: string;
      score: number;
      componentKey: SlideTemplateKey;
      props: SlideTemplateProps;
      latexString?: string;
      orientation?: "any" | "mobile-portrait" | "mobile-landscape" | "desktop";
    }>;
  }>;
}

Important detail: stable ids

For editor integration, stable ids matter more than they do in the demo app.

Use:

  • presentation id: videos.gnommo_id if available
  • slide id: ideally slides.gnommo_slide_id
  • glitch slide id: for now ${slide_id}:default
  • segment id: narration_segments.segment_key

The current export route does not include those stable ids yet. It should.

Best first embedding point in the editor

The best initial place to integrate GlitchPlayer is src/pages/VideoEditorPage.jsx.

Why:

  • it already loads the video, slides, and narration segments
  • it is where slide timing and component selection happen
  • it is where “preview current slide” is most useful

Concrete editor workflow

Recommended behavior:

  1. User edits slides in the left/main editor UI
  2. Editor fetches player-ready presentation JSON
  3. Right-side preview panel mounts GlitchPlayer
  4. Clicking a slide card sets targetSlideId
  5. The preview panel mounts:
<GlitchPlayer
  presentation={presentation}
  slideRegistry={defaultSlideRegistry}
  mode="slide-preview"
  targetSlideId={selectedSlideId}
/>

This gives the editor a live preview of the exact runtime, not an approximation.

Case 2: Slide thumbnails inside GnommoEditor

Recommendation

Do not use the full GlitchPlayer for thumbnails.

Instead, add a dedicated GlitchPlayer export such as:

  • GlitchSlideThumbnail

or

  • GlitchSlideRenderer

Why this should be separate

Thumbnails need to be:

  • cheap to render
  • deterministic
  • slide-only
  • independent from video playback
  • easy to render many times in a list

The full player is optimized for:

  • timeline playback
  • stitched video
  • gestures
  • pause states
  • scrubber chrome

That makes it the wrong abstraction for a slide list with 20 to 100 items.

Suggested thumbnail component API

<GlitchSlideThumbnail
  slide={slide}
  slideRegistry={defaultSlideRegistry}
  viewportMode="desktop"
  preferredGlitchSlideId={optionalSelectedVariantId}
  aspectRatio="square"
/>

or more generally:

<GlitchSlideRenderer
  slide={slide}
  slideRegistry={defaultSlideRegistry}
  viewportMode="desktop"
  renderMode="thumbnail"
/>

What the thumbnail component should do

  • resolve the correct active glitch slide for a viewport
  • render only the chosen slide surface
  • render no video
  • render no scrubber
  • render no play/pause chrome
  • render no vote UI
  • avoid autoplay and interaction state

Where thumbnails should be used in the editor

The first places:

Data source for thumbnails

The editor does not need the full presentation to render thumbnails.

It only needs:

  • the slide data
  • the chosen or default glitch slide
  • the desired viewport mode

So the thumbnail renderer can use the same slide contracts, but with a much smaller data dependency than the full player.

Shared Contract Strategy

This should be the foundation of the integration.

GnommoEditor should stop owning its own slide template definitions as freeform local config.

Instead:

  • @gnommo/slide-contracts becomes the single source of truth
  • both repos import template keys and payload interfaces from it
  • editor field forms are generated from contract metadata
  • player rendering trusts the same contract

Practical consequence

src/data/slideTemplates.js should eventually be replaced by a shared metadata layer derived from the contract package.

That shared metadata should include:

  • componentKey
  • display mode
  • field definitions
  • content budgets
  • editor labels
  • placeholders

That gives one definition of each slide type for:

  • AI generation
  • editor forms
  • backend validation
  • player rendering

Phase 1: Full preview integration

Goal: mount GlitchPlayer in GnommoEditor with minimal risk.

  1. Add GlitchPlayer as a local workspace dependency or sibling package dependency
  2. Add @gnommo/slide-contracts to the editor too
  3. Upgrade GET /api/videos/:id/export to include stable ids and player-complete fields
  4. Add a preview panel to src/pages/VideoEditorPage.jsx
  5. Wire slide-card click to targetSlideId

This gives immediate value with very little duplicated logic.

Phase 2: Shared slide schema adoption

Goal: make editor and player speak exactly the same slide language.

  1. Replace local editor template keys with shared keys
  2. Add per-template form metadata to the shared contracts package
  3. Make editor slide creation and editing use shared contract names
  4. Validate slide payloads before save

This is the phase that prevents long-term drift.

Phase 3: Thumbnail renderer

Goal: make the slide list visually accurate and lightweight.

  1. Export GlitchSlideThumbnail or GlitchSlideRenderer from GlitchPlayer
  2. Reuse player slide registry and resolution logic
  3. Render only the slide surface
  4. Drop all playback chrome and video dependencies
  5. Use it in the editor slide list and detail pages

This will make the editor feel much more aligned with the actual player runtime.

Phase 4: Variant-aware editing

Goal: prepare for many candidate glitch slides per logical slide.

  1. Extend editor data model from “one component_key + props per slide” to:
    • one logical slide
    • many glitch slide variants
  2. Add score, orientation, and variant id
  3. Let thumbnails preview the highest-scoring or selected variant
  4. Let full player preview the exact runtime behavior

This is where GlitchPlayer and GnommoEditor become a true shared system.

My Strong Recommendations

Recommendation 1

Treat full player preview and slide thumbnails as two separate exported surfaces.

That keeps both integrations simple and prevents the editor from trying to use a playback runtime as a list cell.

Recommendation 2

Use the editor backend export route as the canonical bridge, but strengthen it.

The route in backend/src/routes/videos.js is already the right place to centralize this mapping.

Recommendation 3

Replace local editor slide template config with shared contract-driven metadata as soon as possible.

That is the most important architectural step if you want AI agents, human editors, and GlitchPlayer to all agree on what a slide is.

Suggested Next Tasks

If we want to execute this plan incrementally, I would do these next in order:

  1. Upgrade the editor export route to emit stable ids and proper glitch slide objects
  2. Mount GlitchPlayer in VideoEditorPage as a slide-targeted preview panel
  3. Add a new exported GlitchSlideThumbnail component in GnommoPlayer
  4. Replace editor-local slide template definitions with shared metadata from @gnommo/slide-contracts

That sequence gives fast value first, while keeping the long-term architecture clean.