在OpenXML中找到视频关系 [英] Locate video relationships in OpenXML

查看:72
本文介绍了在OpenXML中找到视频关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我正在编写一个pptx解析器,并使用OpenXML来加载数据.一切都很好(这是一个谎言-我实际上已经准备好将计算机扔到整个房间并跳出窗口) ,但是在加载我根本无法弄清的视频时遇到了一个问题.问题在于OpenXML似乎无法找到指定视频URI的关系标签.

So I'm writing a pptx parser and using OpenXML to get the data loaded in. It's all going pretty well (that's a lie - I'm actually ready to throw the computer across the room and jump out of the window), but I've run into an issue with loading videos that I simply can't figure out. The problem is that OpenXML doesn't seem to be able to locate the relationship tag that specifies video URIs.

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

What I've done is written code to cycle through the parts in the slide and log out their Ids, like so:

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

效果很好-它注销了slide.xml.rels文件中指定的所有关系-除了相关文件的视频关系.我可以在rels文件中看到视频关系,它与幻灯片中videoFile标签的链接ID匹配,但是我不知道如何通过代码来获得它.我的图像加载正常(OpenXML可以找到图像关系).视频关系与其他关系是否有区别?如何获得视频URI?

So that works great - it logs out all of the relationships specified in the slide.xml.rels file - except for the video relationships for the relevant file. I can see the video relationship in the rels file, and it matches the link ID of the videoFile tag in the slide, but I can't figure out how to get at it through code. I've got image loading working fine (OpenXML can find the image relationships). Are video relationships treated differently than other relationships? How can I get at the video URIs?

推荐答案

视频版本存储在SlidePart的ExternalReleationships集合中.

Video releationships are stored in the ExternalReleationships collection of a SlidePart.

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

Powerpoint embeds a video (external file) into a presentation in the following way (simplified):

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

  1. It creates a p:video (class Video) tag within a p:timing (class Timing) tag for the slide containing the video.
  2. The p:video tag contains a child called p:cMediaNode (class CommonMediaNode).

p:cMediaNode包含一个名为p:tgtEl的孩子(类TargetElement).

The p:cMediaNode contains a child called p:tgtEl (class TargetElement).

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

Again, the p:cMediaNode contains a child called p:spTgt (class ShapeTarget) which points to the ID of the picture shape releated to the video. The ID of the picture shape is stored in the NonVisualDrawingProperties Id member. So, the video is connected to the picture shape via these Ids.

此外,图片形状还包含一个称为a:videoFile的子类(类VideoFromFile). VideoFromFile类具有一个名为Link的成员,该成员指向Id的ID. 外部关系.

Furthermore, the picture shape contains a child called a:videoFile (class VideoFromFile). The class VideoFromFile has a member called Link which points to the Id of the external releationship.

我强烈建议您下载 OpenXML SDK 2.0生产力工具.这个工具 允许您检查演示文稿文件的生成的XML.

I highy recommend you to download the OpenXML SDK 2.0 productivity tool. This tool allows you to inspect the generated XML of your presentation file.

以下代码列举了给定演示文稿中所有幻灯片的所有视频. 对于每个视频,将打印到外部文件的Uri.这是通过找到 给定视频的外部外部联系.

The following code enumerates all videos for all slides in a given presentation. For each video the Uri to the external file is printed. This is done by finding the releated external releationship for the given video.

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(类VideoFromFile)标签. 请参见下面的代码.

Of course, you could also directly enumerate the a:videoFile (class VideoFromFile) tags. See the code below.

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);
    }
  }
}

这篇关于在OpenXML中找到视频关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆