gpt4 book ai didi

video - 在 OpenXML 中定位视频关系

转载 作者:行者123 更新时间:2023-11-28 21:41:27 24 4
gpt4 key购买 nike

所以我正在编写一个 pptx 解析器并使用 OpenXML 来加载数据。一切进展顺利(这是一个谎言 - 我实际上已经准备好将计算机扔到房间另一头并跳出 window ) ,但我在加载视频时遇到了一个我无法弄清楚的问题。问题是 OpenXML 似乎无法找到指定视频 URI 的关系标签。

我所做的是编写代码来循环浏览幻灯片中的各个部分并注销它们的 ID,如下所示:

SlidePart slidePart = ...;
foreach(var curPart in slidePart.Parts)
Console.WriteLine("Part ID: " + curPart.RelationshipId);

这样效果很好 - 它会注销 slide.xml.rels 文件中指定的所有关系 - 除了相关文件的视频关系。我可以在 rels 文件中看到视频关系,它与幻灯片中 videoFile 标签的链接 ID 匹配,但我无法弄清楚如何通过代码获取它。我的图像加载工作正常(OpenXML 可以找到图像关系)。视频关系的处理方式是否与其他关系不同?如何获取视频 URI?

最佳答案

视频关系存储在 SlidePart 的 ExternalRelationships 集合中。

Powerpoint 以下列方式(简化)将视频(外部文件)嵌入到演示文稿中:

  1. 它在 p:timing (class Timing) 标签内创建一个 p:video (class Video) 标签 包含视频的幻灯片。
  2. p:video 标签包含一个名为 p:cMediaNode 的子标签(CommonMediaNode 类)。

  3. p:cMediaNode 包含一个名为 p:tgtEl 的子节点(TargetElement 类)。

  4. 同样,p:cMediaNode 包含一个名为 p:spTgt(类 ShapeTarget)的子节点,它指向与视频相关的图片形状的ID。图片的ID形状存储在 NonVisualDrawingProperties Id 成员中。因此,视频通过这些 ID 连接到图片形状。

  5. 此外,图片形状包含一个名为 a:videoFile(类 VideoFromFile)的子项。VideoFromFile 类有一个名为 Link 的成员,它指向外部关系。

我强烈建议您下载 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);
}
}
}

关于video - 在 OpenXML 中定位视频关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12504010/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com