在 PHP 中将 PowerPoint 演示文稿转换为视频

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

  • 可访问性提升: 所有设备(无论平台)默认配备视频播放器,而不是演示文稿打开应用程序,因此用户更容易打开或播放视频。
  • 覆盖面更广: 通过视频,您可以触及更大的受众,并向他们传递在演示文稿中可能显得乏味的信息。大多数调查和统计显示,人们观看和消费视频的比例高于其他内容形式,并且他们普遍更喜欢此类内容。

Aspose.Slides 中的 PowerPoint 转视频转换

Aspose.Slides 支持将演示文稿转换为视频。

  • 使用 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("convert PowerPoint Presentation with text to video"));
    $para3 = new Paragraph();
    $para3->getPortions()->add(new Portion("paragraph by paragraph"));
    $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::getSlideSize,并生成供 PresentationPlayer 使用的动画。

生成动画时,会为每个后续动画生成一个 NewAnimation 事件,该事件携带演示动画播放器参数。后者是表示单独动画播放器的类。

要使用演示动画播放器,需要使用 getDuration(动画的完整持续时间)和 setTimePosition 方法。每个动画位置设置在 0 到 duration 范围内,然后 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("Animation total duration: %f", $animationPlayer->getDuration()));
        $animationPlayer->setTimePosition(0);// 初始动画状态
        try {
            # 初始动画状态位图
            $animationPlayer->getFrame()->save("firstFrame.png", ImageFormat::Png);
        } catch (JavaException $e) {
        }
        $animationPlayer->setTimePosition($animationPlayer->getDuration());// final state of the animation
        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();
    }
  }

随后可以将生成的帧编译为视频。参见 Convert PowerPoint to Video 部分。

支持的动画和效果

进入

动画类型 Aspose.Slides PowerPoint
Appear not supported supported
Fade supported supported
Fly In supported supported
Float In supported supported
Split supported supported
Wipe supported supported
Shape supported supported
Wheel supported supported
Random Bars supported supported
Grow & Turn not supported supported
Zoom supported supported
Swivel supported supported
Bounce supported supported

强调

动画类型 Aspose.Slides PowerPoint
Pulse not supported supported
Color Pulse not supported supported
Teeter supported supported
Spin supported supported
Grow/Shrink not supported supported
Desaturate not supported supported
Darken not supported supported
Lighten not supported supported
Transparency not supported supported
Object Color not supported supported
Complementary Color not supported supported
Line Color not supported supported
Fill Color not supported supported

退出

动画类型 Aspose.Slides PowerPoint
Disappear not supported supported
Fade supported supported
Fly Out supported supported
Float Out supported supported
Split supported supported
Wipe supported supported
Shape supported supported
Random Bars supported supported
Shrink & Turn not supported supported
Zoom supported supported
Swivel supported supported
Bounce supported supported

运动路径

动画类型 Aspose.Slides PowerPoint
Lines supported supported
Arcs supported supported
Turns supported supported
Shapes supported supported
Loops supported supported
Custom Path supported supported

常见问题

是否可以转换受密码保护的演示文稿?

是的,Aspose.Slides 支持处理受密码保护的演示文稿。处理此类文件时,需要提供正确的密码,以便库能够访问演示文稿的内容。

Aspose.Slides 是否支持在云解决方案中使用?

是的,Aspose.Slides 可以集成到云应用和服务中。该库专为服务器环境设计,可确保高性能和可扩展性,以实现批量文件处理。

在转换过程中对演示文稿的大小是否有限制?

Aspose.Slides 能够处理几乎任何大小的演示文稿。然而,在处理非常大的文件时,可能需要额外的系统资源,通常建议对演示文稿进行优化以提升性能。