视频关系存储在 SlidePart 的 ExternalReleationships 集合中。
Powerpoint 通过以下方式(简化)将视频(外部文件)嵌入到演示文稿中:
Video
它在 ap:timing (class Timing
) 标签内为包含视频的幻灯片创建 ap:video (class ) 标签。
p:video 标签包含一个名为 p:cMediaNode (class CommonMediaNode
) 的子标签。
p:cMediaNode 包含一个名为 p:tgtEl(类TargetElement
)的子节点。
同样,p:cMediaNode 包含一个名为 p:spTgt (class ShapeTarget
) 的子节点,它指向与视频相关的图片形状的 ID。图片形状的ID存储在NonVisualDrawingProperties
Id
成员中。因此,视频通过这些 Id 连接到图片形状。
此外,图片形状包含一个名为 a:videoFile (class VideoFromFile
) 的子对象。VideoFromFile 类有一个名为的成员Link
,它指向外部关系的 Id。
我强烈建议您下载OpenXML SDK 2.0 生产力工具。此工具允许您检查演示文件的生成 XML。
以下代码枚举给定演示文稿中所有幻灯片的所有视频。对于每个视频,都会打印到外部文件的 Uri。这是通过查找给定视频的相关外部关系来完成的。
using (var doc = PresentationDocument.Open("c:\\temp\\presentation.pptx", false))
{
var presentation = doc.PresentationPart.Presentation;
foreach (SlideId slideId in presentation.SlideIdList)
{
SlidePart slidePart = doc.PresentationPart.GetPartById(slideId.RelationshipId) as SlidePart;
if (slidePart == null || slidePart.Slide == null)
{
continue;
}
Slide slide = slidePart.Slide;
var videos = slide.Descendants<Video>();
Console.Out.WriteLine("Found videos for slide ID: {0}", slideId.Id);
foreach (Video video in videos)
{
ShapeTarget shapeTarget = video.Descendants<ShapeTarget>().FirstOrDefault();
Console.Out.WriteLine("ShapeTargetId = {0}", shapeTarget.ShapeId);
var videoFromFile = slide.CommonSlideData.ShapeTree.Descendants<Picture>().
Where<Picture>(p => p.NonVisualPictureProperties.Descendants<NonVisualDrawingProperties>().FirstOrDefault().Id == shapeTarget.ShapeId).
FirstOrDefault().Descendants<VideoFromFile>().FirstOrDefault();
Console.Out.WriteLine("Releationship ID: {0}", videoFromFile.Link);
var externalReleationship =
slidePart.ExternalRelationships.Where(er => er.Id == videoFromFile.Link).FirstOrDefault();
if(externalReleationship == null) // Then it must be embedded
{
ReferenceRelationship rr = slidePart.GetReferenceRelationship(videoFromFile.Link);
if (rr != null)
{
Console.Out.WriteLine(rr.Uri.OriginalString);
}
}
else
{
Console.Out.WriteLine("Path to video file: {0}", externalReleationship.Uri.AbsolutePath);
}
}
}
}
当然,您也可以直接枚举 a:videoFile (class VideoFromFile
) 标签。请参阅下面的代码。
foreach (SlideId slideId in presentation.SlideIdList)
{
SlidePart slidePart = doc.PresentationPart.GetPartById(slideId.RelationshipId) as SlidePart;
if (slidePart == null || slidePart.Slide == null)
{
continue;
}
Slide slide = slidePart.Slide;
var videos = slide.CommonSlideData.ShapeTree.Descendants<VideoFromFile>();
foreach (VideoFromFile video in videos)
{
Console.Out.WriteLine("Releationship ID: {0}", video.Link);
var externalReleationship =
slidePart.ExternalRelationships.Where(er => er.Id == video.Link).FirstOrDefault();
if(externalReleationship == null)
{
ReferenceRelationship rr = slidePart.GetReferenceRelationship(videoFromFile.Link);
if (rr != null)
{
Console.Out.WriteLine(rr.Uri.OriginalString);
}
}
else
{
Console.Out.WriteLine("Path to video file: {0}", externalReleationship.Uri.AbsolutePath);
}
}
}