将 PowerPoint 转换为视频

通过将 PowerPoint 演示文稿转换为视频,您将获得

  • 可访问性增强: 所有设备(无论平台如何)默认都配备视频播放器,而不是演示文稿打开应用程序,因此用户发现打开或播放视频更容易。
  • 更广泛的覆盖: 通过视频,您可以覆盖大量观众,并向他们提供在演示文稿中可能显得乏味的信息。大多数调查和统计数据表明,人们观看和消费视频的时间超过其他形式的内容,他们通常更喜欢这样的内容。

在 Aspose.Slides 中将 PowerPoint 转换为视频

Aspose.Slides 22.11 中,我们实现了演示文稿到视频转换的支持。

  • 使用 Aspose.Slides 生成与特定 FPS(每秒帧数)对应的一组帧(来自演示文稿幻灯片)
  • 使用第三方工具如 ffmpeg (for java) 根据帧创建视频。

将 PowerPoint 转换为视频

  1. 将其添加到您的 POM 文件中:
   <dependency>
     <groupId>net.bramp.ffmpeg</groupId>
     <artifactId>ffmpeg</artifactId>
     <version>0.7.0</version>
   </dependency>
```php

  1. 这里 下载 ffmpeg。

  2. 运行将 PowerPoint 转换为视频的 PHP 代码。

以下 PHP 代码向您展示如何将包含图形和两个动画效果的演示文稿转换为视频:

  $presentation = new Presentation();
  try {
    # 添加一个笑脸形状并对其动画
    $smile = $presentation->getSlides()->get_Item(0)->getShapes()->addAutoShape(ShapeType::SmileyFace, 110, 20, 500, 500);
    $mainSequence = $presentation->getSlides()->get_Item(0)->getTimeline()->getMainSequence();
    $effectIn = $mainSequence->addEffect($smile, EffectType::Fly, EffectSubType::TopLeft, EffectTriggerType::AfterPrevious);
    $effectOut = $mainSequence->addEffect($smile, EffectType::Fly, EffectSubType::BottomRight, EffectTriggerType::AfterPrevious);
    $effectIn->getTiming()->setDuration(2.0);
    $effectOut->setPresetClassType(EffectPresetClassType::Exit);
    $fps = 33;

    class FrameTick {
      function invoke($sender, $arg) {
            try {
                $frame = sprintf("frame_%04d.png", $sender->getFrameIndex());
                $arguments->getFrame()->save($frame, ImageFormat::Png);
                $frames->add($frame);
                } catch (JavaException $e) {
                  }
             }
    }

    $frames = new Java("java.util.ArrayList");
    $animationsGenerator = new PresentationAnimationsGenerator($presentation);
    try {
      $player = new PresentationPlayer($animationsGenerator, $fps);
      try {
        $frameTick = java_closure(new FrameTick(), null, java("com.aspose.slides.PresentationPlayerFrameTick"));
        $player->setFrameTick($frameTick);
        $animationsGenerator->run($presentation->getSlides());
      } finally {
        if (!java_is_null($player)) {
          $player->dispose();
        }
      }
    } finally {
      if (!java_is_null($animationsGenerator)) {
        $animationsGenerator->dispose();
      }
    }
    # 配置 ffmpeg 二进制文件夹。请参见此页面:https://github.com/rosenbjerg/FFMpegCore#installation
    $ffmpeg = new Java("net.bramp.ffmpeg.builder.FFmpeg", "path/to/ffmpeg");
    $ffprobe = new Java("net.bramp.ffmpeg.builder.FFprobe", "path/to/ffprobe");
    $builder = (new Java("net.bramp.ffmpeg.builder.FFmpegBuilder"))->addExtraArgs("-start_number", "1")->setInput("frame_%04d.png")->addOutput("output.avi")->setVideoFrameRate(FFmpeg->FPS_24)->setFormat("avi")->done();
    $executor = new Java("net.bramp.ffmpeg.builder.FFmpegExecutor", $ffmpeg, $ffprobe);
    $executor->createJob($builder)->run();
  } catch (JavaException $e) {
    $e->printStackTrace();
  }

视频效果

您可以在幻灯片上的对象上应用动画,并在幻灯片之间使用转场。

动画和转场使幻灯片放映更加引人入胜、有趣——对视频也同样如此。让我们为之前的演示文稿添加另一张幻灯片和转场代码:

  # 添加一个笑脸形状并对其动画
  # ...
  # 添加一张新幻灯片和动画转场
  $newSlide = $presentation->getSlides()->addEmptySlide($presentation->getSlides()->get_Item(0)->getLayoutSlide());
  $newSlide->getBackground()->setType(BackgroundType::OwnBackground);
  $newSlide->getBackground()->getFillFormat()->setFillType(FillType::Solid);
  $newSlide->getBackground()->getFillFormat()->getSolidFillColor()->setColor(java("java.awt.Color")->MAGENTA);
  $newSlide->getSlideShowTransition()->setType(TransitionType::Push);

Aspose.Slides 还支持文本的动画。因此,我们对对象中的段落进行动画,它们将一个接一个地出现(延迟设置为一秒):

  $presentation = new Presentation();
  try {
    # 添加文本和动画
    $autoShape = $presentation->getSlides()->get_Item(0)->getShapes()->addAutoShape(ShapeType::Rectangle, 210, 120, 300, 300);
    $para1 = new Paragraph();
    $para1->getPortions()->add(new Portion("Aspose Slides for Java"));
    $para2 = new Paragraph();
    $para2->getPortions()->add(new Portion("将 PowerPoint 演示文稿带文本转换为视频"));
    $para3 = new Paragraph();
    $para3->getPortions()->add(new Portion("逐段落"));
    $paragraphCollection = $autoShape->getTextFrame()->getParagraphs();
    $paragraphCollection->add($para1);
    $paragraphCollection->add($para2);
    $paragraphCollection->add($para3);
    $paragraphCollection->add(new Paragraph());
    $mainSequence = $presentation->getSlides()->get_Item(0)->getTimeline()->getMainSequence();
    $effect1 = $mainSequence->addEffect($para1, EffectType::Appear, EffectSubType::None, EffectTriggerType::AfterPrevious);
    $effect2 = $mainSequence->addEffect($para2, EffectType::Appear, EffectSubType::None, EffectTriggerType::AfterPrevious);
    $effect3 = $mainSequence->addEffect($para3, EffectType::Appear, EffectSubType::None, EffectTriggerType::AfterPrevious);
    $effect4 = $mainSequence->addEffect($para3, EffectType::Appear, EffectSubType::None, EffectTriggerType::AfterPrevious);
    $effect1->getTiming()->setTriggerDelayTime(1.0);
    $effect2->getTiming()->setTriggerDelayTime(1.0);
    $effect3->getTiming()->setTriggerDelayTime(1.0);
    $effect4->getTiming()->setTriggerDelayTime(1.0);
    $fps = 33;

    class FrameTick {
      function invoke($sender, $arg) {
            try {
                $frame = sprintf("frame_%04d.png", $sender->getFrameIndex());
                $arguments->getFrame()->save($frame, ImageFormat::Png);
                $frames->add($frame);
                } catch (JavaException $e) {
                  }
             }
    }

    $frames = new Java("java.util.ArrayList");
    $animationsGenerator = new PresentationAnimationsGenerator($presentation);
    try {
      $player = new PresentationPlayer($animationsGenerator, $fps);
      try {
        $frameTick = java_closure(new FrameTick(), null, java("com.aspose.slides.PresentationPlayerFrameTick"));
        $player->setFrameTick($frameTick);
        $animationsGenerator->run($presentation->getSlides());
      } finally {
        if (!java_is_null($player)) {
          $player->dispose();
        }
      }
    } finally {
      if (!java_is_null($animationsGenerator)) {
        $animationsGenerator->dispose();
      }
    }
    # 配置 ffmpeg 二进制文件夹。请参见此页面:https://github.com/rosenbjerg/FFMpegCore#installation
    $ffmpeg = new Java("net.bramp.ffmpeg.builder.FFmpeg", "path/to/ffmpeg");
    $ffprobe = new Java("net.bramp.ffmpeg.builder.FFprobe", "path/to/ffprobe");
    $builder = (new Java("net.bramp.ffmpeg.builder.FFmpegBuilder"))->addExtraArgs("-start_number", "1")->setInput("frame_%04d.png")->addOutput("output.avi")->setVideoFrameRate(FFmpeg->FPS_24)->setFormat("avi")->done();
    $executor = new Java("net.bramp.ffmpeg.builder.FFmpegExecutor", $ffmpeg, $ffprobe);
    $executor->createJob($builder)->run();
  } catch (JavaException $e) {
    $e->printStackTrace();
  }

视频转换类

为了使您能够执行 PowerPoint 到视频转换任务,Aspose.Slides 提供了 PresentationAnimationsGeneratorPresentationPlayer 类。

PresentationAnimationsGenerator 允许您通过其构造函数设置视频的帧大小(稍后将创建)。如果您传递一个演示文稿实例,则将使用 Presentation.SlideSize,并生成 PresentationPlayer 使用的动画。

当动画生成后,将为每个后续动画生成一个 NewAnimation 事件,该事件具有 IPresentationAnimationPlayer 参数。后者是一个表示单独动画播放器的类。

要使用 IPresentationAnimationPlayer,会使用 Duration(动画的总持续时间)属性和 SetTimePosition 方法。每个动画位置在 0 到持续时间 范围内设置,然后 GetFrame 方法将返回与动画状态对应的 BufferedImage:

use aspose\slides\Presentation;
use aspose\slides\PresentationPlayer;
use aspose\slides\PresentationAnimationsGenerator;
use aspose\slides\ImageFormat;
use aspose\slides\ShapeType;
use aspose\slides\EffectType;
use aspose\slides\EffectSubtype;
use aspose\slides\EffectTriggerType;
use aspose\slides\EffectPresetClassType;

class PresentationAnimationPlayer {
    function invoke($animationPlayer) {
        echo(sprintf("动画总持续时间:%f", $animationPlayer->getDuration()));
        $animationPlayer->setTimePosition(0);// 初始动画状态
        try {
            # 初始动画状态位图
            $animationPlayer->getFrame()->save("firstFrame.png", ImageFormat::Png);
        } catch (JavaException $e) {
        }
        $animationPlayer->setTimePosition($animationPlayer->getDuration());// 动画的最终状态
        try {
            # 动画的最后一帧
            $animationPlayer->getFrame()->save("lastFrame.png", ImageFormat::Png);
        } catch (JavaException $e) {
        }
    }
}
$presentation = new Presentation();
try {
    # 添加一个笑脸形状并对其动画
    $smile = $presentation->getSlides()->get_Item(0)->getShapes()->addAutoShape(ShapeType::SmileyFace, 110, 20, 500, 500);
    $mainSequence = $presentation->getSlides()->get_Item(0)->getTimeline()->getMainSequence();
    $effectIn = $mainSequence->addEffect($smile, EffectType::Fly, EffectSubtype::TopLeft, EffectTriggerType::AfterPrevious);
    $effectOut = $mainSequence->addEffect($smile, EffectType::Fly, EffectSubtype::BottomRight, EffectTriggerType::AfterPrevious);
    $effectIn->getTiming()->setDuration(2.0);
    $effectOut->setPresetClassType(EffectPresetClassType::Exit);
    $animationsGenerator = new PresentationAnimationsGenerator($presentation);
    $presentationAnimation=java_closure(new PresentationAnimationPlayer(), null, java("com.aspose.slides.PresentationAnimationsGeneratorNewAnimation"));
    try {
        $animationsGenerator->setNewAnimation($presentationAnimation);
    } finally {
        if (!java_is_null($animationsGenerator)) {
            $animationsGenerator->dispose();
        }
    }
} finally {
    if (!java_is_null($presentation)) {
        $presentation->dispose();
    }
}

要同时播放演示文稿中的所有动画,使用 PresentationPlayer 类。此类在其构造函数中接受一个 PresentationAnimationsGenerator 实例和效果的 FPS,然后调用 FrameTick 事件来播放所有动画:


class FrameTick {
      function invoke($sender, $arg) {
            try {
                $arguments->getFrame()->save("frame_" . $sender->getFrameIndex() . ".png", ImageFormat::Png);
                } catch (JavaException $e) {
                  }
             }
    }

  $presentation = new Presentation("animated.pptx");
  try {
    $animationsGenerator = new PresentationAnimationsGenerator($presentation);
    try {
      $player = new PresentationPlayer($animationsGenerator, 33);
      try {
        $frameTick = java_closure(new FrameTick(), null, java("com.aspose.slides.PresentationPlayerFrameTick"));
        $player->setFrameTick($frameTick);
        $animationsGenerator->run($presentation->getSlides());
      } finally {
        if (!java_is_null($player)) {
          $player->dispose();
        }
      }
    } finally {
      if (!java_is_null($animationsGenerator)) {
        $animationsGenerator->dispose();
      }
    }
  } finally {
    if (!java_is_null($presentation)) {
      $presentation->dispose();
    }
  }

然后生成的帧可以被编译以生成视频。请参见 将 PowerPoint 转换为视频 部分。

支持的动画和效果

出现:

动画类型 Aspose.Slides PowerPoint
出现 不支持 支持
渐变 支持 支持
飞入 支持 支持
浮入 支持 支持
分裂 支持 支持
擦拭 支持 支持
形状 支持 支持
轮子 支持 支持
随机条 支持 支持
增长与旋转 不支持 支持
缩放 支持 支持
旋转 支持 支持
弹跳 支持 支持

强调:

动画类型 Aspose.Slides PowerPoint
脉冲 不支持 支持
渐变脉冲 不支持 支持
摇摆 支持 支持
旋转 支持 支持
增长/缩小 不支持 支持
去饱和化 不支持 支持
变暗 不支持 支持
变亮 不支持 支持
透明度 不支持 支持
物体颜色 不支持 支持
互补颜色 不支持 支持
线条颜色 不支持 支持
填充颜色 不支持 支持

退出:

动画类型 Aspose.Slides PowerPoint
消失 不支持 支持
渐变 支持 支持
飞出 支持 支持
浮出 支持 支持
分裂 支持 支持
擦拭 支持 支持
形状 支持 支持
随机条 支持 支持
收缩与旋转 不支持 支持
缩放 支持 支持
旋转 支持 支持
弹跳 支持 支持

运动路径:

动画类型 Aspose.Slides PowerPoint
直线 支持 支持
弧线 支持 支持
转弯 支持 支持
形状 支持 支持
循环 支持 支持
自定义路径 支持 支持