แปลงงานนำเสนอ PowerPoint เป็นวิดีโอใน Python
ภาพรวม
การแปลงงานนำเสนอ PowerPoint หรือ OpenDocument ให้เป็นวิดีโอทำให้ผู้ชมสามารถดูเนื้อหาในตัวเล่นวิดีโอโดยไม่ต้องเปิดโปรแกรมนำเสนอ Aspose.Slides for Python via Java แสดงภาพเคลื่อนไหวและการเปลี่ยนสไลด์เป็นเฟรมภาพ ส่วนตัวเข้ารหัสแยก เช่น FFmpeg จะรวมเฟรมเหล่านั้นเป็นไฟล์วิดีโอ
Note
ลองใช้ PowerPoint to Video converter ออนไลน์เพื่อดูการแปลงงานนำเสนอเป็นวิดีโอในปฏิบัติการแปลง PowerPoint เป็นวิดีโอ
การแปลงมีสองขั้นตอน: สร้างเฟรม PNG ที่อัตราเฟรมที่เลือก จากนั้นเข้ารหัสลำดับภาพเป็น MP4 ใช้อัตราเฟรมเดียวกันในทั้งสองขั้นตอนเพื่อรักษาเวลาการเคลื่อนไหว
ก่อนเรียกใช้ตัวอย่าง:
- ตั้งค่า Aspose.Slides for Python via Java.
- ดาวน์โหลด FFmpeg และทำให้ไฟล์ปฏิบัติการของมันอยู่ใน
PATHตัวอย่างใช้เวอร์ชันที่มีตัวเข้ารหัสlibx264 - เรียกใช้โค้ด Python ด้านล่างในไดเรกทอรีที่เขียนได้
ตัวอย่างสร้างรูปทรงยิ้มพร้อมการเคลื่อนไหวเข้าและออก เรนเดอร์เฟรมที่ 30 FPS และเรียก FFmpeg เพื่อสร้าง output.mp4 โฟลเดอร์เฟรมใหม่จะทำให้เฟรมจากการรันก่อนหน้าไม่ถูกรวมในวิดีโอ
import shutil
import subprocess
import tempfile
from pathlib import Path
import jpype
import asposeslides
if not jpype.isJVMStarted():
jpype.startJVM()
from asposeslides.api import EffectPresetClassType, EffectSubtype, EffectTriggerType, EffectType, ImageFormat, Presentation, PresentationAnimationsGenerator, PresentationPlayer, ShapeType
fps = 30
frames_directory = Path(tempfile.mkdtemp(prefix="video_frames_", dir="."))
frame_count = 0
def save_frame(sender, arguments):
global frame_count
frame_path = frames_directory / f"frame_{frame_count:06d}.png"
frame = arguments.getFrame()
try:
frame.save(str(frame_path), ImageFormat.Png)
finally:
frame.dispose()
frame_count += 1
presentation = Presentation()
try:
slide = presentation.getSlides().get_Item(0)
smile = slide.getShapes().addAutoShape(ShapeType.SmileyFace, 110, 20, 500, 500)
sequence = slide.getTimeline().getMainSequence()
entrance = sequence.addEffect(smile, EffectType.Fly, EffectSubtype.TopLeft, EffectTriggerType.AfterPrevious)
entrance.getTiming().setDuration(2.0)
exit_effect = sequence.addEffect(smile, EffectType.Fly, EffectSubtype.BottomRight, EffectTriggerType.AfterPrevious)
exit_effect.setPresetClassType(EffectPresetClassType.Exit)
exit_effect.getTiming().setDuration(2.0)
generator = PresentationAnimationsGenerator(presentation)
try:
player = PresentationPlayer(generator, fps)
try:
callback = jpype.JProxy("com.aspose.slides.PresentationPlayer$FrameTick", dict(invoke=save_frame))
player.setFrameTick(callback)
generator.run(presentation.getSlides())
finally:
player.dispose()
finally:
generator.dispose()
finally:
presentation.dispose()
ffmpeg = shutil.which("ffmpeg")
if frame_count == 0:
print("No frames were generated.")
elif ffmpeg is None:
print(f"FFmpeg was not found on PATH. PNG frames are available in {frames_directory}.")
else:
input_pattern = str(frames_directory / "frame_%06d.png")
command = [ffmpeg, "-n", "-framerate", str(fps), "-start_number", "0", "-i", input_pattern, "-vf", "pad=ceil(iw/2)*2:ceil(ih/2)*2", "-c:v", "libx264", "-pix_fmt", "yuv420p", "output.mp4"]
result = subprocess.run(command, check=False)
if result.returncode == 0:
print("Saved output.mp4")
else:
print(f"FFmpeg failed with exit code {result.returncode}. Frames are available in {frames_directory}.")
เพื่อแปลงไฟล์ที่มีอยู่แล้ว ให้เริ่มต้น Presentation ด้วยเส้นทางของไฟล์และละเว้นคำสั่งสร้างรูปทรงและการสร้างการเคลื่อนไหว
คำสั่ง FFmpeg จะอ่าน image sequence ที่มีหมายเลข, เติมค่ามิติที่เป็นคี่ให้เป็นเลขคู่, และเขียนวิดีโอ H.264 ด้วยรูปแบบพิกเซล yuv420p ตัวเลือก -n ป้องกันไม่ให้เขียนทับไฟล์ผลลัพธ์ที่มีอยู่ ไฟล์ PNG ที่สร้างขึ้นจะคงอยู่ในโฟลเดอร์เฟรม; ให้ลบเมื่อไม่ต้องการใช้ต่อ
Note
ตัวอย่างนี้เข้ารหัสเฉพาะเฟรมภาพเท่านั้น ไม่ได้เพิ่มการบรรยายหรือเสียงที่ฝังอยู่ในงานนำเสนอลงในวิดีโอผลลัพธ์เอฟเฟกต์วิดีโอ
การเคลื่อนไหวควบคุมว่าวัตถุบนสไลด์ปรากฏ, เคลื่อนที่ หรือหายไปอย่างไร การเปลี่ยนสไลด์ควบคุมการเปลี่ยนระหว่างสไลด์ ให้เพิ่มเอฟเฟกต์เหล่านี้ก่อนสร้างเฟรมวิดีโอ
ดู PowerPoint Animation, Shape Animation, Shape Effects, และ Slide Transitions
เพิ่มการเปลี่ยนสไลด์
ตัวอย่างที่เป็นอิสระต่อไปนี้สร้างงานนำเสนอที่มีสองสไลด์ สไลด์ที่สองมีพื้นหลังสีแมเจนตาและการเปลี่ยนแบบ push บันทึกงานนำเสนอแล้วใช้เป็นอินพุตให้กับตัวอย่างการสร้างเฟรมที่อธิบายข้างต้น
import jpype
import asposeslides
if not jpype.isJVMStarted():
jpype.startJVM()
from asposeslides.api import BackgroundType, FillType, Presentation, SaveFormat, ShapeType, TransitionType
Color = jpype.JClass("java.awt.Color")
presentation = Presentation()
try:
first_slide = presentation.getSlides().get_Item(0)
first_slide.getShapes().addAutoShape(ShapeType.SmileyFace, 110, 20, 500, 500)
new_slide = presentation.getSlides().addEmptySlide(first_slide.getLayoutSlide())
new_slide.getBackground().setType(BackgroundType.OwnBackground)
new_slide.getBackground().getFillFormat().setFillType(FillType.Solid)
new_slide.getBackground().getFillFormat().getSolidFillColor().setColor(Color.MAGENTA)
new_slide.getSlideShowTransition().setType(TransitionType.Push)
presentation.save("transition.pptx", SaveFormat.Pptx)
finally:
presentation.dispose()
ทำให้ย่อหน้ามีการเคลื่อนไหว
ข้อความสามารถปรากฏเป็นย่อหน้าทีละย่อหน้า ตัวอย่างนี้สร้างสามย่อหน้าพร้อมเอฟเฟกต์การเข้าจางลำดับต่อกัน โดยแต่ละอันล่าช้าหนึ่งวินาทีหลังจากเอฟเฟกต์ก่อนหน้า ใช้ไฟล์ paragraphs.pptx ที่บันทึกเป็นอินพุตให้กับตัวอย่างการแปลงวิดีโอ
import jpype
import asposeslides
if not jpype.isJVMStarted():
jpype.startJVM()
from asposeslides.api import EffectSubtype, EffectTriggerType, EffectType, Paragraph, Portion, Presentation, SaveFormat, ShapeType
presentation = Presentation()
try:
slide = presentation.getSlides().get_Item(0)
shape = slide.getShapes().addAutoShape(ShapeType.Rectangle, 210, 120, 300, 300)
shape.addTextFrame("")
paragraphs = shape.getTextFrame().getParagraphs()
paragraphs.clear()
sequence = slide.getTimeline().getMainSequence()
texts = ["Aspose.Slides for Python via Java", "Convert presentation text to video", "Paragraph by paragraph"]
for text in texts:
paragraph = Paragraph()
portion = Portion(text)
paragraph.getPortions().add(portion)
paragraphs.add(paragraph)
effect = sequence.addEffect(paragraph, EffectType.Fade, EffectSubtype.None_, EffectTriggerType.AfterPrevious)
effect.getTiming().setTriggerDelayTime(1.0)
effect.getTiming().setDuration(1.0)
presentation.save("paragraphs.pptx", SaveFormat.Pptx)
finally:
presentation.dispose()
คลาสการแปลงวิดีโอ
PresentationAnimationsGenerator สร้างเหตุการณ์การเคลื่อนไหวสำหรับสไลด์ การสร้างจากงานนำเสนอจะใช้ขนาดสไลด์ของงานนำเสนอเป็นขนาดเฟรม ใช้ setDefaultDelay เพื่อตั้งค่าการหน่วงเวลาตั้งต้นเป็นมิลลิวินาที
PresentationPlayer ทำการสุ่มตัวอย่างการเคลื่อนไหวที่สร้างขึ้นที่อัตราเฟรมที่กำหนดให้กับคอนสตรัคเตอร์ของมัน ลงทะเบียนคอลแบ็ก Python ผ่าน JPype ด้วย setFrameTick จากนั้นเรียก run เพื่อสร้างเฟรม ตัวอย่างแรกใช้เคาน์เตอร์เริ่มจากศูนย์ของตนเองเพื่อให้ชื่อไฟล์ตรงกับลำดับอินพุตของ FFmpeg
สำหรับสถานะการเคลื่อนไหวแบบแยกแต่ละอัน ลงทะเบียนคอลแบ็กด้วย setNewAnimation คอลแบ็กจะได้รับ animation player ที่สามารถตั้งตำแหน่งในเวลาเลือกได้ ตัวอย่างต่อไปนี้บันทึกเฟรมแรกและสุดท้ายของการเคลื่อนไหวแต่ละอันด้วยชื่อไฟล์ที่ไม่ซ้ำกัน:
from pathlib import Path
import jpype
import asposeslides
if not jpype.isJVMStarted():
jpype.startJVM()
from asposeslides.api import EffectSubtype, EffectTriggerType, EffectType, ImageFormat, Presentation, PresentationAnimationsGenerator, ShapeType
output_directory = Path("animation_states")
output_directory.mkdir(exist_ok=True)
animation_index = 0
def save_animation_states(animation_player):
global animation_index
duration = animation_player.getDuration()
print(f"Animation {animation_index}: {duration} milliseconds")
for label, position in [("first", 0.0), ("last", duration)]:
animation_player.setTimePosition(position)
frame = animation_player.getFrame()
try:
frame_path = output_directory / f"animation_{animation_index:04d}_{label}.png"
frame.save(str(frame_path), ImageFormat.Png)
finally:
frame.dispose()
animation_index += 1
presentation = Presentation()
try:
slide = presentation.getSlides().get_Item(0)
smile = slide.getShapes().addAutoShape(ShapeType.SmileyFace, 110, 20, 500, 500)
sequence = slide.getTimeline().getMainSequence()
effect = sequence.addEffect(smile, EffectType.Fly, EffectSubtype.TopLeft, EffectTriggerType.AfterPrevious)
effect.getTiming().setDuration(2.0)
generator = PresentationAnimationsGenerator(presentation)
try:
callback = jpype.JProxy("com.aspose.slides.PresentationAnimationsGenerator$NewAnimation", dict(invoke=save_animation_states))
generator.setNewAnimation(callback)
generator.run(presentation.getSlides())
finally:
generator.dispose()
finally:
presentation.dispose()
การสนับสนุนการเคลื่อนไหวและเอฟเฟกต์
ตารางต่อไปนี้สรุปการรองรับการเรนเดอร์ที่อธิบายในบทความการแปลงของ Java ให้ดูตัวอย่างเฟรมที่สร้างเมื่อการนำเสนอใช้เอฟเฟกต์ที่ไม่รองรับ
การเข้ามา:
| ประเภทการเคลื่อนไหว | Aspose.Slides | PowerPoint |
|---|---|---|
| Appear | ไม่ | ใช่ |
| Fade | ใช่ | ใช่ |
| Fly In | ใช่ | ใช่ |
| Float In | ใช่ | ใช่ |
| Split | ใช่ | ใช่ |
| Wipe | ใช่ | ใช่ |
| Shape | ใช่ | ใช่ |
| Wheel | ใช่ | ใช่ |
| Random Bars | ใช่ | ใช่ |
| Grow & Turn | ไม่ | ใช่ |
| Zoom | ใช่ | ใช่ |
| Swivel | ใช่ | ใช่ |
| Bounce | ใช่ | ใช่ |
การเน้น:
| ประเภทการเคลื่อนไหว | Aspose.Slides | PowerPoint |
|---|---|---|
| Pulse | ไม่ | ใช่ |
| Color Pulse | ไม่ | ใช่ |
| Teeter | ใช่ | ใช่ |
| Spin | ใช่ | ใช่ |
| Grow/Shrink | ไม่ | ใช่ |
| Desaturate | ไม่ | ใช่ |
| Darken | ไม่ | ใช่ |
| Lighten | ไม่ | ใช่ |
| Transparency | ไม่ | ใช่ |
| Object Color | ไม่ | ใช่ |
| Complementary Color | ไม่ | ใช่ |
| Line Color | ไม่ | ใช่ |
| Fill Color | ไม่ | ใช่ |
การออก:
| ประเภทการเคลื่อนไหว | Aspose.Slides | PowerPoint |
|---|---|---|
| Disappear | ไม่ | ใช่ |
| Fade | ใช่ | ใช่ |
| Fly Out | ใช่ | ใช่ |
| Float Out | ใช่ | ใช่ |
| Split | ใช่ | ใช่ |
| Wipe | ใช่ | ใช่ |
| Shape | ใช่ | ใช่ |
| Random Bars | ใช่ | ใช่ |
| Shrink & Turn | ไม่ | ใช่ |
| Zoom | ใช่ | ใช่ |
| Swivel | ใช่ | ใช่ |
| Bounce | ใช่ | ใช่ |
เส้นทางการเคลื่อนที่:
| ประเภทการเคลื่อนไหว | Aspose.Slides | PowerPoint |
|---|---|---|
| Lines | ใช่ | ใช่ |
| Arcs | ใช่ | ใช่ |
| Turns | ใช่ | ใช่ |
| Shapes | ใช่ | ใช่ |
| Loops | ใช่ | ใช่ |
| Custom Path | ใช่ | ใช่ |
คำถามที่พบบ่อย
Aspose.Slides สร้างไฟล์ MP4 โดยตรงหรือไม่?
ไม่. Aspose.Slides สร้างเฟรมของงานนำเสนอ ใช้ตัวเข้ารหัสวิดีโอ เช่น FFmpeg เพื่อรวมเป็นไฟล์ MP4
ทำไมวิดีโอถึงเล่นเร็วหรือช้ากว่าที่คาดหวัง?
ใช้ FPS เดียวกันสำหรับการสร้างเฟรมและอัตราเฟรมของอินพุตตัวเข้ารหัส ความไม่สอดคล้องจะทำให้ระยะเวลาการเล่นของลำดับภาพเปลี่ยนไป
ฉันสามารถแปลงงานนำเสนอที่ป้องกันด้วยรหัสผ่านได้หรือไม่?
ได้. ให้ใส่รหัสผ่านที่ถูกต้องเมื่อ loading the protected presentation, แล้วสร้างเฟรมจากเนื้อหาที่โหลด
กระบวนการนี้รักษาเสียงของงานนำเสนอหรือไม่?
ตัวอย่างส่งออกเฟรมภาพเท่านั้น ทำให้วิดีโอผลลัพธ์ไม่มีเสียง หากต้องการรวมเสียง ให้เพิ่มแทร็กเสียงแยกต่างหากในระหว่างการเข้ารหัสวิดีโอ
ฉันจะลดการใช้พื้นที่ดิสก์ชั่วคราวได้อย่างไร?
ใช้ขนาดเฟรมที่เล็กลงหรือ FPS ที่ต่ำลง และลบไฟล์ PNG ชั่วคราวหลังจากการเข้ารหัสสำเร็จ ตรวจสอบคุณภาพวิดีโอที่ได้เมื่อปรับลดการตั้งค่าใด ๆ