Skip to content

[Epic] Embedded Media Playback — audio + video playback config #24

@MHoroszowski

Description

@MHoroszowski

Problem

add_movie() exists but is half-built: it embeds the video blob and creates the picture poster, but the playback configuration that PowerPoint exposes through Video Tools → Playback (Trim, Volume, Start Automatically vs On Click, Loop, Rewind After Playing, Hide While Not Playing) is unauthorable — those live in <p:cMediaNode> inside <p:timing>, and the timing tree is unmodelled (overlaps with Animations epic). Audio is worse: there is no audio API at all. Issues track auto-play (scanny/python-pptx#427, 16c), trim/start-time (#811, 6c), animated GIFs (#501), narration (#622), audio replacement (#784, #805), and corrupted-on-removal (#974, 6c). YouTube embeds (#839) and HTML embeds (#777, 12c) are PowerPoint features that should at minimum round-trip without corruption.

Sub-features

  • Slide.shapes.add_audio(audio_file, x, y, cx, cy) — parallel to add_movie
  • Movie.playback.start = MSO_MEDIA_START.AUTO|ON_CLICK|IN_CLICK_SEQUENCE
  • Movie.playback.loop_until_stopped, .rewind_after, .hide_while_not_playing, .volume (0.0–1.0)
  • Movie.playback.trim_start_ms / .trim_end_ms for video trimming
  • Audio narration: Slide.notes_audio / Slide.narration setter
  • Animated GIF support: add_picture("file.gif") preserves animation (currently shows first frame only)
  • Audio/video replace API: Movie.replace_media(new_file) parallel to Picture.replace_image()
  • Safe removal: shape.delete() on a Movie/Audio drops the rels and cMediaNode without corrupting timing tree
  • Online video round-trip preservation (YouTube <a:videoFile> + <p15:linkRel>)
  • HTML/Web Object preservation (read+round-trip; write opt-in Phase B)

Prior art

  • Open PRs: none directly on the playback-configuration surface.
  • User issues this would close: #322, #323, #427, #430, #501, #622, #752, #767, #777, #782, #784, #802, #805, #811, #839, #847, #926, #974.
  • OOXML: PresentationML §19.3.1.4 <p:audioFile>, <p:videoFile>; §19.5.10 <p:cMediaNode> (playback config inside timing tree); <p:nvSpPr>/<p:nvPr> carries <a:audioFile> / <a:videoFile> rel; online video uses <p15:linkRel> extension.
  • Code paths: src/pptx/parts/media.py, src/pptx/shapes/picture.py (Movie subclass), src/pptx/oxml/shapes/picture.py. Cross-cuts with Animations epic on cMediaNode.

Acceptance criteria

  • A pptx authored with movie.playback.start = MSO_MEDIA_START.AUTO; movie.playback.loop_until_stopped = True plays automatically and loops in PowerPoint.
  • Audio shapes round-trip and play.
  • Removing a Movie via shape.delete() produces a saveable, openable deck (no corruption).
  • Animated GIF preserves animation on round-trip.
  • 25+ unit tests + 8 behave scenarios.

Effort: L

Phase A: audio API + safe removal + replace (M). Phase B: playback configuration (depends on Animations epic Phase B for cMediaNode, M). Phase C: GIF / online-video / HTML embed preservation (S).

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:mediaFeature area: mediaepicMulti-feature roadmap epicprior-art:noneNo known prior art — greenfieldpriority:P1Important but not urgent

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions