Movie

PowerPoint allows a video to be inserted into a slide and run in slide show mode. In the PowerPoint UI, a shape of this type is called a movie.

A movie is implemented as a variant form of a p:pic element, which makes it closely related to a Picture object. This close relationship makes sense, because a movie acts very much like an image when it is not playing and the two shapes therefore share much of their behavior. When not playing, a movie shape displays a static image, called a poster frame.

Candidate Protocol

A video can be added to a slide by specifying a video file, position, size, and optional poster frame:

>>> movie = shapes.add_movie(
...     movie_file, left, top, width, height, poster_frame_image,
...     mime_type
... )

>>> movie
<pptx.shape.picture.Movie object @ 0x12345678>

>>> movie.shape_type
MSO.MEDIA

>>> movie.media_type
PP_MEDIA_TYPE.MOVIE

>>> movie.media_format
<pptx.shape.picture.MediaFormat object @ 0x123456ab>

Animation/timing resources

Enumerations

PP_MEDIA_TYPE - https://msdn.microsoft.com/en-us/library/office/ff746008.aspx

PP_MEDIA_TYPE.MOVIE 3 Movie
PP_MEDIA_TYPE.SOUND 2 Sound
PP_MEDIA_TYPE.OTHER 1 Others
PP_MEDIA_TYPE.MIXED -2 Mixed

Click Behavior

The video’s “play on click” behavior in slideshow mode is implemented by the use of a <p:timing> element in the <p:sld> element. No “play” button or slider control appears when this element is not present.

Poster Frame

A poster frame is the static image displayed in the video location when the video is not playing. Each image that appears on the YouTube home page representing a video is an example of a poster frame.

The poster frame is perhaps most frequently a frame from the video itself. In some contexts, the first frame is used by default. The poster frame can be undefined, or empty, and it can also be an unrelated image.

Some of the example videos for this feature get a poster frame upon insertion; however at least one does not. In that case, a media “speaker” icon (stretched to fit) is shown instead.

XML Semantics

  • id= of p:cTn element just needs to be unique among p:cTn elements, apparently.

Example XML

Inserted MPEG-4 H.264 video:

<!--slide{n}.xml-->

<p:pic>
  <p:nvPicPr>
    <p:cNvPr id="6" name="video-filename.mp4">
      <a:hlinkClick r:id="" action="ppaction://media"/>
    </p:cNvPr>
    <p:cNvPicPr>
      <a:picLocks noChangeAspect="1"/>
    </p:cNvPicPr>
    <p:nvPr>
      <a:videoFile r:link="rId2"/>
      <p:extLst>
        <p:ext uri="{DAA4B4D4-6D71-4841-9C94-3DE7FCFB9230}">
          <p14:media
              xmlns:p14="http://schemas.microsoft.com/office/powerpoint/2010/main"
              r:embed="rId1"/>
        </p:ext>
      </p:extLst>
    </p:nvPr>
  </p:nvPicPr>
  <p:blipFill>
    <a:blip r:embed="rId4"/>
    <a:stretch>
      <a:fillRect/>
    </a:stretch>
  </p:blipFill>
  <p:spPr>
    <a:xfrm>
      <a:off x="5059279" y="876300"/>
      <a:ext cx="2390526" cy="5184274"/>
    </a:xfrm>
    <a:prstGeom prst="rect">
      <a:avLst/>
    </a:prstGeom>
  </p:spPr>
</p:pic>

Regular picture shape, for comparison:

<p:pic>
  <p:nvPicPr>
    <p:cNvPr id="6" name="Picture 5" descr="python-logo.gif"/>
    <p:cNvPicPr>
      <a:picLocks noChangeAspect="1"/>
    </p:cNvPicPr>
    <p:nvPr/>
  </p:nvPicPr>
  <p:blipFill>
    <a:blip r:embed="rId2"/>
    <a:stretch>
      <a:fillRect/>
    </a:stretch>
  </p:blipFill>
  <p:spPr>
    <a:xfrm>
      <a:off x="5580112" y="1988840"/>
      <a:ext cx="2679700" cy="901700"/>
    </a:xfrm>
    <a:prstGeom prst="rect">
      <a:avLst/>
    </a:prstGeom>
  </p:spPr>
</p:pic>


<!--minimal (I think) p:video element-->

<p:sld
    xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
    xmlns:p="http://schemas.openxmlformats.org/presentationml/2006/main"
    xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
    >
  <p:cSld>
    <!-- ... -->
  </p:cSld>
  <p:clrMapOvr>
    <a:masterClrMapping/>
  </p:clrMapOvr>
  <p:timing>
    <p:tnLst>
      <p:par>
        <p:cTn xmlns:p14="http://schemas.microsoft.com/office/powerpoint/2010/main" id="1" dur="indefinite" restart="never" nodeType="tmRoot">
          <p:childTnLst>
            <p:video>
              <p:cMediaNode vol="80000">
                <p:cTn id="7" fill="hold" display="0">
                  <p:stCondLst>
                    <p:cond delay="indefinite"/>
                  </p:stCondLst>
                </p:cTn>
                <p:tgtEl>
                  <p:spTgt spid="3"/>
                </p:tgtEl>
              </p:cMediaNode>
            </p:video>
          </p:childTnLst>
        </p:cTn>
      </p:par>
    </p:tnLst>
  </p:timing>
</p:sld>


<!--p:timing element for two videos in slide, as added by PowerPoint-->

<p:timing>
  <p:tnLst>
    <p:par>
      <p:cTn xmlns:p14="http://schemas.microsoft.com/office/powerpoint/2010/main" id="1" dur="indefinite" restart="never" nodeType="tmRoot">
        <p:childTnLst>
          <p:seq concurrent="1" nextAc="seek">
            <p:cTn id="2" restart="whenNotActive" fill="hold" evtFilter="cancelBubble" nodeType="interactiveSeq">
              <p:stCondLst>
                <p:cond evt="onClick" delay="0">
                  <p:tgtEl>
                    <p:spTgt spid="3"/>
                  </p:tgtEl>
                </p:cond>
              </p:stCondLst>
              <p:endSync evt="end" delay="0">
                <p:rtn val="all"/>
              </p:endSync>
              <p:childTnLst>
                <p:par>
                  <p:cTn id="3" fill="hold">
                    <p:stCondLst>
                      <p:cond delay="0"/>
                    </p:stCondLst>
                    <p:childTnLst>
                      <p:par>
                        <p:cTn id="4" fill="hold">
                          <p:stCondLst>
                            <p:cond delay="0"/>
                          </p:stCondLst>
                          <p:childTnLst>
                            <p:par>
                              <p:cTn id="5" presetID="2" presetClass="mediacall" presetSubtype="0" fill="hold" nodeType="clickEffect">
                                <p:stCondLst>
                                  <p:cond delay="0"/>
                                </p:stCondLst>
                                <p:childTnLst>
                                  <p:cmd type="call" cmd="togglePause">
                                    <p:cBhvr>
                                      <p:cTn id="6" dur="1" fill="hold"/>
                                      <p:tgtEl>
                                        <p:spTgt spid="3"/>
                                      </p:tgtEl>
                                    </p:cBhvr>
                                  </p:cmd>
                                </p:childTnLst>
                              </p:cTn>
                            </p:par>
                          </p:childTnLst>
                        </p:cTn>
                      </p:par>
                    </p:childTnLst>
                  </p:cTn>
                </p:par>
              </p:childTnLst>
            </p:cTn>
            <p:nextCondLst>
              <p:cond evt="onClick" delay="0">
                <p:tgtEl>
                  <p:spTgt spid="3"/>
                </p:tgtEl>
              </p:cond>
            </p:nextCondLst>
          </p:seq>
          <p:video>
            <p:cMediaNode vol="80000">
              <p:cTn id="7" fill="hold" display="0">
                <p:stCondLst>
                  <p:cond delay="indefinite"/>
                </p:stCondLst>
              </p:cTn>
              <p:tgtEl>
                <p:spTgt spid="3"/>
              </p:tgtEl>
            </p:cMediaNode>
          </p:video>
          <p:seq concurrent="1" nextAc="seek">
            <p:cTn id="8" restart="whenNotActive" fill="hold" evtFilter="cancelBubble" nodeType="interactiveSeq">
              <p:stCondLst>
                <p:cond evt="onClick" delay="0">
                  <p:tgtEl>
                    <p:spTgt spid="4"/>
                  </p:tgtEl>
                </p:cond>
              </p:stCondLst>
              <p:endSync evt="end" delay="0">
                <p:rtn val="all"/>
              </p:endSync>
              <p:childTnLst>
                <p:par>
                  <p:cTn id="9" fill="hold">
                    <p:stCondLst>
                      <p:cond delay="0"/>
                    </p:stCondLst>
                    <p:childTnLst>
                      <p:par>
                        <p:cTn id="10" fill="hold">
                          <p:stCondLst>
                            <p:cond delay="0"/>
                          </p:stCondLst>
                          <p:childTnLst>
                            <p:par>
                              <p:cTn id="11" presetID="2" presetClass="mediacall" presetSubtype="0" fill="hold" nodeType="clickEffect">
                                <p:stCondLst>
                                  <p:cond delay="0"/>
                                </p:stCondLst>
                                <p:childTnLst>
                                  <p:cmd type="call" cmd="togglePause">
                                    <p:cBhvr>
                                      <p:cTn id="12" dur="1" fill="hold"/>
                                      <p:tgtEl>
                                        <p:spTgt spid="4"/>
                                      </p:tgtEl>
                                    </p:cBhvr>
                                  </p:cmd>
                                </p:childTnLst>
                              </p:cTn>
                            </p:par>
                          </p:childTnLst>
                        </p:cTn>
                      </p:par>
                    </p:childTnLst>
                  </p:cTn>
                </p:par>
              </p:childTnLst>
            </p:cTn>
            <p:nextCondLst>
              <p:cond evt="onClick" delay="0">
                <p:tgtEl>
                  <p:spTgt spid="4"/>
                </p:tgtEl>
              </p:cond>
            </p:nextCondLst>
          </p:seq>
          <p:video>
            <p:cMediaNode vol="80000">
              <p:cTn id="13" fill="hold" display="0">
                <p:stCondLst>
                  <p:cond delay="indefinite"/>
                </p:stCondLst>
              </p:cTn>
              <p:tgtEl>
                <p:spTgt spid="4"/>
              </p:tgtEl>
            </p:cMediaNode>
          </p:video>
        </p:childTnLst>
      </p:cTn>
    </p:par>
  </p:tnLst>
</p:timing>



<!--slide{n}.xml.rels-->

<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
  <Relationship Id="rId1"
      Type="http://schemas.microsoft.com/office/2007/relationships/media"
      Target="../media/media1.mp4"/>
  <Relationship Id="rId2"
      Type="http://sc.../officeDocument/2006/relationships/video"
      Target="../media/media1.mp4"/>
  <Relationship Id="rId3"
      Type="http://sc.../officeDocument/2006/relationships/slideLayout"
      Target="../slideLayouts/slideLayout1.xml"/>
  <!-- this one is the poster frame -->
  <Relationship Id="rId4"
      Type="http://sc.../officeDocument/2006/relationships/image"
      Target="../media/image1.png"/>
</Relationships>


<!--[Content_Types].xml-->

<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
  <!-- ... -->
  <Default Extension="mp4" ContentType="video/unknown"/>
  <Default Extension="png" ContentType="image/png"/>
  <Default Extension="jpeg" ContentType="image/jpeg"/>
  <!-- ... -->
</Types>

XML Semantics

  • Extension DAA4B4D4-6D71-4841-9C94-3DE7FCFB9230 is described as a media extension. It appears to allow:
    • “cropping” the video period (set start and stop time markers)
    • provide for “fade-in”
    • allow for setting bookmarks in the video for fast jumps to a particular location
  • This and other extensions are documented in this PDF.