Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
197 changes: 156 additions & 41 deletions ResearchStudio-Reel/skills/paper2video/SKILL.md

Large diffs are not rendered by default.

168 changes: 168 additions & 0 deletions ResearchStudio-Reel/skills/paper2video/ppt2video/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
---
name: ppt2video
description: Render any local PowerPoint PPTX into a fresh narrated video bundle with native or script-timed object animations, Notes-first and Alt-Text-fallback narration, optional user script overrides, spotlight cues, bottom-band subtitles, editable source delivery, timeline metadata, and strict QA. Use for ordinary presentations as well as Paper2Video decks, when a user has edited a PPTX, needs to rerender an animated deck without an LLM or ppt-master, or needs the Author Notes and Alt Text protocol.
---

# Convert an edited PPTX to video

This is a general-purpose PowerPoint-to-video tool embedded in `paper2video` so
both skills can share one deterministic rendering engine. It is not limited to
research papers or to a previously delivered `video.pptx`. Use any local PPTX
as the visual source. Prefer canonical Author Notes for precise narration and
marker timing. When canonical Notes are absent, read explicit Shape Alt Text
`Script:` fields. Do not reuse audio, video, or cache files from an older
bundle.

## Authoring contract

For precise control, write a Notes block whose handle matches a top-level shape
or group:

```text
## [latency-card] latency-card
[[Fly In]] A new latency card appears. [[Spotlight]] It reports lower latency.
```

Use the same bracketed handle as the first Alt Text line. Alt Text stays compact
so a PowerPoint user sees only the editable handle and script:

```text
[latency-card]
Script: [[Fly In]] A new latency card appears. [[Spotlight]] It reports lower latency.
```

The baseline hash and generated ordering provenance live inside the PPTX shape
OOXML. Native effect, target, trigger, and delay data stay in PowerPoint's
`p:timing` tree. They do not appear in Alt Text. Older verbose
`[Paper2Video]` blocks remain readable and migrate to this two-line form on the
next writeback. Keep Author Notes clean. Read
[../references/editable_pptx.md](../references/editable_pptx.md) for the
hidden provenance contract.

The stable handle resolves the target directly, so Notes order controls spoken
order and does not need to copy Animation Pane order. Marker positions determine
their Edge word-boundary times. A system-generated Notes block is inserted by
row-aware canvas order: top-to-bottom between rows and left-to-right within one
row. A Notes marker may add an MP4 effect even when the shape has no matching
native row.

For a PPT-native workflow without canonical Notes, put an explicit script in
the shape's Alt Text and use the native Animation Pane for effects:

```text
[latency-card]
Script: A new latency card appears and reports lower latency.
```

Read [../references/animations.md](../references/animations.md) before changing
effect names or resolving a protocol conflict.

## Authority and conflict rules

Apply this precedence:

1. An explicitly selected user `script.json` owns narration for that render.
2. Canonical Author Notes own handles. For narration, compare Notes and Alt Text
with the last system-synchronized script hash stored in shape OOXML. A change
on only one surface wins; if both changed differently, Notes wins and the
authority report records the conflict.
3. Explicit Alt Text `Script:` fields provide narration when Notes are absent or
when their script alone differs from the stored baseline.
A new animated target with only plain pre-protocol Alt Text uses that text
once as its initial script and is normalized to compact `Script:` metadata.
4. Explicit Author Notes order wins. System-generated Notes blocks follow
row-aware spatial order, independent of Animation Pane order.
5. Animation Pane supplies native effects plus `On Click`, `With Previous`,
`After Previous`, and
delay relationships when an explicit Notes marker does not own timing. These
dependencies are recomputed after Notes timing: sequential rows wait for the
prior Notes block's narration and effects, while `With Previous` explicitly
permits overlap.
6. Shape OOXML stores `orderSource` and canonical `orderIndex` beside the script
hash. An explicit Notes reorder promotes the visible sequence to
`author_notes`; otherwise generated blocks remain `geometry`.
7. The PowerPoint canvas owns all visible pixels and geometry.

When Notes and Alt Text both changed differently, Notes wins and the delivered
PPTX Alt Text is refreshed. When a Notes effect conflicts with a native effect
of the same kind, use the Notes name and time for MP4; preserve non-conflicting native effects.
Fail when a Notes handle cannot be resolved safely or an effect name is
unsupported.

## One-command render

```bash
python ResearchStudio-Reel/skills/paper2video/scripts/render_edited_pptx.py \
path/to/edited.pptx \
path/to/new_video_bundle \
--resolution 1080p
```

Input and output may be arbitrary local paths. Add
`--script-json path/to/edited-script.json` only when a user-edited external
script should override PPTX narration. This command must:

1. Normalize compact Alt Text from authoritative Notes when present.
2. Generate handles and compact two-line Alt Text for new animation targets.
3. Backfill canonical Notes when the source has only Alt Text or native rows.
4. Extract narration using user script, Notes, then Alt Text precedence.
5. Generate fresh Edge TTS and word timings, or deterministic silent audio for
a native-only silent slide.
6. Build Notes word timing and Animation Pane trigger/delay mappings.
7. Align every subtitle cue to its actual first and last Edge TTS word
boundaries. Never use proportional timing in a final render.
8. Render PPTX pixels, animations, audio, spotlight, and bottom-band subtitles.
9. Write `timeline.json`, subtitle-alignment evidence, mapping reports, and
strict QA evidence.

Do not pass `--prebuilt-audio-dir` for a final render. Do not pass `--no-qa`.

For a change-aware rerender, ordinary users choose whether to keep existing
narration or regenerate only changed elements. The latter requires a previous
PPTX baseline and an OpenAI API key:

```bash
python ResearchStudio-Reel/skills/paper2video/scripts/render_edited_pptx.py \
edited.pptx new-bundle \
--baseline-pptx previous-video.pptx \
--narration-mode regenerate
```

Regenerated scripts are written back into both Author Notes and compact Alt
Text in the delivered PPTX. `script.json` remains an Advanced override, not the
normal editing surface.

## Ordinary animated PPTX

If the deck does not yet contain canonical Notes and Alt Text, bootstrap a copy
from an existing narration script, then edit that copy:

```bash
python ResearchStudio-Reel/skills/paper2video/scripts/bootstrap_editable_pptx.py \
path/to/animated-source.pptx \
--script-json path/to/script.json \
--out path/to/editable-video.pptx \
--report-out path/to/bootstrap-report.json
```

## Completion gate

Require these deliverables:

```text
new_video_bundle/
video.mp4
video_no_subtitles.mp4
video.pptx
manifest.json
assets/audio/
assets/captions/
assets/meta/timeline.json
assets/meta/reports/author_notes_authority.json
assets/meta/reports/subtitle_timing_alignment.json
assets/meta/reports/video_qa_report.json
```

Confirm the subtitle timing report has `status: word_aligned`, then confirm
`video_qa_report.json` has `passed: true`, `error: 0`, and `warning: 0`.
Do not claim completion until the strict renderer exits 0.
195 changes: 195 additions & 0 deletions ResearchStudio-Reel/skills/paper2video/references/animations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
# Author Notes animations in Paper2Video

Paper2Video uses PowerPoint animation metadata as an authoring contract. The
production editable route renders the current PPTX itself; the legacy/source
authoring route can still render equivalent SVG groups. Neither route records a
PowerPoint playback window.

## Ownership and timing

| Layer | Owner | What it stores |
|---|---|---|
| Editable object animation | PPT Master / PPTX OOXML | Shape target, native effect, pane order, duration, trigger |
| Optional authoring overrides | `animations.json` in PPT Master | Per-slide/group effect, order, delay, duration, trigger |
| Named narration mapping | PowerPoint Author Notes | Stable handle, supported MP4 effect name, marker position, transcript block |
| Video timing | `animation_manifest.json` | Stable handle, PPTX shape id or SVG locator, and Edge word-aligned start/duration |
| Render evidence | `animation_render_report.json` | Strategy, global MP4 time, layer bbox, pixel sample times |
| Subtitle timing | SRT/VTT | Caption cues on the same audio clock |

`svg_to_pptx.py -a auto` writes native object animations into the PPTX. The
optional `animations.json` controls that export but is not a subtitle or video
script. PPT Master's native animation schedule is presentation-oriented; it
does not by itself align every object entrance to a spoken word.

The Author Notes bridge supplies that missing link. Marker position identifies
the corresponding transcript block and `word_timings.json` supplies Edge TTS
word boundaries. The renderer reconciles Notes blocks with Animation Pane
targets, then writes compact Alt Text containing only the first-line `[handle]`
and `Script:`. The accepted script hash and generated ordering provenance live
in the shape's `p2v:scriptBaseline` OOXML extension, while native animation
target, effect, trigger, delay, and grouping remain in PowerPoint's `p:timing`
tree. Subtitles, spotlight/laser cues, and animations therefore share the same
audio clock without exposing generated metadata in Alt Text or borrowing
timestamps from one another.

Spotlight has two marker forms:

| Form | Spoken/captioned text | Video duration |
|---|---|---|
| `[[Spotlight]]` | Text after the marker | Native emphasis duration or 2.4 s default |
| `[[Spotlight] spoken phrase]` | The enclosed phrase | First enclosed Edge word start through last enclosed Edge word end |

The spoken-span form is preferred when a human editor wants direct duration
control without editing JSON. Its enclosed phrase remains ordinary narration
and subtitle text. It is valid only for `Spotlight`; empty scopes, partial-word
boundaries, and sequence-gated scopes that end before their resolved start fail
closed. The manifest and cue plan record `duration_source: script_scope`, the
scope text, and its resolved word range. Point markers remain backward
compatible.

For an ordinary user-added animated target that has only plain pre-protocol Alt
Text, normalization promotes that sentence to the target's initial narration
and writes it back as managed `Script:` plus canonical Notes. This gives the
block a real speech window, so the following sequential target cannot begin
after only the short entrance transition.

After Notes markers are word-aligned, editable rendering recomputes all native
dependencies on that final clock. Each Notes block releases the next `On Click`
or `After Previous` row only after both its narration and effects finish.
`With Previous` remains the explicit overlap control. The pipeline pads the
fresh audio tail when the resolved sequence ends after spoken narration, and
strict QA rejects a sequential effect that starts before its block gate.

When canonical Notes cover only part of a slide, a user-added native animated
target that is absent from Notes is inserted at its Animation Pane position
relative to the Notes-owned native targets. Explicit Notes blocks still keep
their relative order when Notes and Pane conflict. A new first Pane row
therefore remains first instead of being appended after all existing Notes
blocks. Only scripted targets outside the Animation Pane use top-to-bottom,
left-to-right geometry fallback.

Author Notes are authoritative for handles, narration, supported MP4 entrance
names, marker positions, and `Spotlight` intent. The Animation Pane is
authoritative for target shapes, target order, and entrance/emphasis row kind.
A supported Notes entrance name may override a different recognized native
entrance name; the protocol report records both. Counts, order, and row kind
remain strict and fail when they cannot be reconciled safely.

## Support matrix

PPT Master currently registers 22 native entrance effects. Paper2Video renders
the following strict subset into MP4 pixels:

| PPT Master key | Author Notes name | PPTX preset | MP4 strategy | Default duration |
|---|---|---|---|---:|
| `appear` | `Appear` | `1 / 0` | instant reveal | 0.12 s |
| `fade` | `Fade In` | `10 / 0` | alpha fade | 0.48 s |
| `fly` | `Fly In` | `2 / 4` | left-to-right motion and fade | 0.56 s |
| `zoom` | `Zoom In` | `23 / 0` | center scale and fade | 0.48 s |
| `wipe` | `Wipe In` | `22 / 1` | left-to-right reveal | 0.52 s |
| `dissolve` | `Dissolve In` | `9 / 0` | alpha dissolve | 0.48 s |
| `circle` | `Circle In` | `6 / 0` | circular mask reveal | 0.52 s |
| `diamond` | `Diamond In` | `8 / 0` | diamond mask reveal | 0.52 s |

The remaining native presets are recognized but do not have an MP4 strategy:

| PPT Master key | PowerPoint name | PPTX preset |
|---|---|---|
| `cut` | `Cut In` | `42 / 8` |
| `split` | `Split In` | `16 / 21` |
| `blinds` | `Blinds In` | `3 / 10` |
| `checkerboard` | `Checkerboard In` | `5 / 6` |
| `random_bars` | `Random Bars In` | `14 / 10` |
| `peek` | `Peek In` | `12 / 4` |
| `wheel` | `Wheel In` | `21 / 0` |
| `box` | `Box In` | `4 / 0` |
| `plus` | `Plus In` | `13 / 0` |
| `strips` | `Strips In` | `18 / 12` |
| `wedge` | `Wedge In` | `20 / 0` |
| `stretch` | `Stretch In` | `17 / 0` |
| `expand` | `Expand In` | `50 / 0` |
| `swivel` | `Swivel In` | `19 / 0` |

An unknown native preset tuple fails during extraction. A recognized native
entrance without an MP4 strategy may be mapped only when Author Notes explicitly
choose one of the eight supported MP4 names; that override is recorded rather
than silently changed to Fade. An unsupported or misspelled Notes name fails.
PPT Master's seven page transitions (`fade`, `push`, `wipe`, `split`, `strips`,
`cover`, `random`) are a separate slide-level layer and are not part of the
object-animation manifest.

## Build and render

Editable PPTX route, recommended after a user changes the deck:

```bash
python skills/paper2video/scripts/build_animation_manifest.py \
--pptx "$VIDEO_OUT/video.pptx" \
--word-timings "$VIDEO_AUDIO/word_timings.json" \
--protocol-report-out "$VIDEO_META/reports/editable_pptx_protocol.json" \
--out "$VIDEO_META/animation_manifest.json"

python skills/paper2video/scripts/render_video.py "$VIDEO_OUT" \
--pptx "$VIDEO_OUT/video.pptx" \
--audio-dir "$VIDEO_AUDIO" \
--script-json "$VIDEO_AUDIO/script.json" \
--frame-source pptx \
--animation-source pptx \
--animation-manifest "$VIDEO_META/animation_manifest.json" \
--animation-report-out "$VIDEO_META/reports/animation_render_report.json" \
--require-animations \
--out "$VIDEO_CLIPS/video_raw.mp4"
```

The renderer creates cumulative PPTX reveal states with LibreOffice and derives
each animation layer from adjacent pixel states. Text, color, position, image,
style, addition, and deletion edits therefore come from the current deck, not
from an earlier SVG export. The manifest records the PPTX SHA-256; rendering
and strict QA fail if the deck changes after the mapping is built.

SVG authoring route:

```bash
python skills/paper2video/scripts/build_animation_manifest.py \
--author-notes-report "$VIDEO_META/reports/author_notes_report.json" \
--word-timings "$VIDEO_AUDIO/word_timings.json" \
--svg-dir "$PPT_MASTER_PROJECT/svg_final" \
--out "$VIDEO_META/animation_manifest.json"

python skills/paper2video/scripts/render_video.py "$PPT_MASTER_PROJECT" \
--pptx "$VIDEO_OUT/video.pptx" \
--audio-dir "$VIDEO_AUDIO" \
--script-json "$VIDEO_AUDIO/script.json" \
--frame-source svg \
--svg-dir "$PPT_MASTER_PROJECT/svg_final" \
--animation-manifest "$VIDEO_META/animation_manifest.json" \
--animation-report-out "$VIDEO_META/reports/animation_render_report.json" \
--require-animations \
--out "$VIDEO_CLIPS/video_raw.mp4"
```

Final QA must receive the same manifest and report plus the raw MP4:

```bash
python skills/paper2video/scripts/check_video_package.py "$VIDEO_OUT" \
... \
--raw-mp4 "$VIDEO_OUT/video_no_subtitles.mp4" \
--animation-manifest "$VIDEO_META/animation_manifest.json" \
--animation-report "$VIDEO_META/reports/animation_render_report.json" \
--require-animations \
--strict
```

The strict animation gate checks exact slide/order/locator/name coverage,
Edge timing provenance, strategy mapping, valid layer bboxes, and transition
pixel changes inside every mapped bbox. For `source_kind: pptx`, it also checks
the delivered PPTX, manifest, and render report all carry the same SHA-256 and
shape ids.

## Is PPT Master required?

PPT Master is not a runtime dependency after the first native PPTX exists. It
remains the preferred upstream authoring tool because it gives each Group a real
Animation Pane effect. A user can then edit that PPTX and run
`render_edited_pptx.py` locally with no LLM and no ppt-master checkout. See
`editable_pptx.md` for the exact mutation contract.
Loading
Loading