用 ffmpeg 制作 PPT 视频

前言

最近提交 presentation 需要上传带讲解的 PPT 视频,但我不是很喜欢用 PPT 自带的录制功能,而且单独处理录音有更大的操作空间(包括用 TTS 合成音频、后处理降噪等等),所以记录一下我自己制作 PPT 视频的全过程。

TTS

TTS 部分不是本文的重点,因此一笔带过,主要分为以下几个步骤:

参考资料:

https://github.com/coqui-ai/TTS

https://github.com/espeak-ng/espeak-ng

  1. 按照参考资料用 pip 安装 TTS,此时已经可以通过 cli 工具 tts 生成 TTS:
1
tts --text "Hello world." --out_path output.wav
  1. 但默认的 TTS 模型无法阅读逐字母阅读(例如 AI),因此根据 issue 需要换 tts_models/en/ljspeech/vits 模型;按照参考资料安装 espeak-ng,并将其写入 PATH;
  2. 安装完成后重启终端,此时可以通过 tts 调用指定模型生成 TTS,并且用点隔开需要逐字母阅读的文字:
1
tts --text "Hello world. H.E.L.L.O.W.O.R.L.D." --model_name "tts_models/en/ljspeech/vits" --out_path output.wav

从 PPT 导出高清图像

默认情况下 16:9 的 slides 导出的图像尺寸为 1280x720,如果我们需要更高清的图像就要通过修改注册表的方式进行。

参考资料:https://learn.microsoft.com/zh-cn/office/troubleshoot/powerpoint/change-export-slide-resolution

需要修改的注册表项:HKEY_CURRENT_USER\Software\Microsoft\Office\16.0\PowerPoint\Options,新建 DWORD32 值 ExportBitmapResolution

但参考资料中 ExportBitmapResolution 表格中十进制值和像素的对应在我的实际操作中并不正确,实际测试设置 144 时导出的图片尺寸为 4320x2430,仅供参考。

批量重命名文件

从 PPT 中导出的图片文件名类似⌈幻灯片1.PNG⌋,为了方便后续处理需要批量重命名,这里有很多工具可以选用,我使用的是 PowerToys 中的 PowerRename 组件。

参考资料:https://github.com/microsoft/PowerToys/

设置查找项为 幻灯片\d*.PNG,勾选⌈使用正则表达式⌋,设置替换项为 ${padding=2,start=1}.png,即可将图片批量命名为⌈01.png⌋等。

利用 ffmpeg 将多张图片和对应音频组合成视频

首先用 Python 和 ffprobe 生成 ffmpeg 之后要用的 meta 信息 filelist.txtaudio.txt(代码来自 GPT-4):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import subprocess
import re

# 用于获取音频长度的函数
def get_audio_length(audio_file):
    result = subprocess.run(
        ["ffprobe", "-v", "error", "-show_entries", "format=duration", "-of", "default=noprint_wrappers=1:nokey=1", audio_file],
        stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT
    )
    duration = float(result.stdout)
    return round(duration, 2)

# 音频和图片输入路径格式
audio_pattern = "{:02d}.wav"
image_pattern = "{:02d}.png"

# 输出文件
filelist_filename = "filelist.txt"
audio_filename = "audio.txt"

# 比如你有10对文件
num_files = 10

# 生成 filelist.txt
with open(filelist_filename, 'w') as filelist, open(audio_filename, 'w') as audio:
    for i in range(1, num_files + 1):
        # 构造文件名
        audio_file = audio_pattern.format(i)
        image_file = image_pattern.format(i)

        # 获取音频长度
        duration = get_audio_length(audio_file)

        # 写入到 filelist
        filelist.write("file '{}'\n".format(image_file))
        filelist.write("duration {}\n".format(duration))
        audio.write("file '{}'\n".format(audio_file))

print(f"生成 {filelist_filename}{audio_filename} 完成。")

之后用 ffmpeg 合成最终视频(命令来自 GPT-4):

1
ffmpeg -f concat -safe 0 -i filelist.txt -f concat -safe 0 -i audio.txt -r 10 -s 1920x1080 -c:v libx264 -pix_fmt yuv420p -c:a aac -strict experimental output.mp4

可根据需求自行修改帧率 -r 和分辨率 -s

Licensed under CC BY-NC-SA 4.0
京ICP备17016743号
Built with Hugo
主题 StackJimmy 设计