如何用MoviePy制作普通字幕?遇TextClip及ImageClip问题求助
解决MoviePy添加字幕时TextClip报错及ImageClip+PIL失效问题
我需要给视频添加已有文本及对应时长的字幕,要求无需生成大量文件。尝试两种方案均失败:
- 使用
TextClip时出现权限相关报错,已安装ImageMagick及所有相关dev包但无效; - 尝试通过PIL生成图片转numpy数组结合
ImageClip实现,同样失败。
尝试的代码及报错信息
1. ImageClip + PIL 实现代码
import numpy as np from PIL import Image, ImageDraw from moviepy.video.VideoClip import ImageClip, CompositeVideoClip def get_image(text: str) -> np.array: image = Image.new('RGB', (600, 400), color=(255, 255, 255)) draw = ImageDraw.Draw(image) draw.text((10, 10), text.encode('utf-8'), fill=(255, 255, 0)) image.show() return np.array(image) audio_with_subtitles = [("示例文本", 3), ...] # 示例数据 textclips = [ ImageClip(get_image(phrase)).set_duration(duration) for phrase, duration in audio_with_subtitles ] # 假设videoclip是已加载的原始视频片段 videoclip = CompositeVideoClip([videoclip, *textclips])
2. TextClip 实现代码
from moviepy.video.VideoClip import TextClip, CompositeVideoClip audio_with_subtitles = [("示例文本", 3), ...] # 示例数据 textclips = [ TextClip(phrase, fontsize=30, color='black').set_duration(duration) for phrase, duration in audio_with_subtitles ] # 假设videoclip是已加载的原始视频片段 videoclip = CompositeVideoClip([videoclip, *textclips])
3. TextClip 报错信息
OSError: convert-im6.q16: attempt to perform an operation not allowed by the security policy `@/tmp/tmp7wugzgq3.txt' @ error/property.c/InterpretImageProperties/3706. convert-im6.q16: no images defined `PNG32:/tmp/tmpk3q2l74h.png' @ error/convert.c/ConvertImageCommand/3229. During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/home/bifle/Desktop/tiktok_test.py", line 67, in <module> TextClip( File "/home/bifle/.local/lib/python3.10/site-packages/moviepy/video/VideoClip.py", line 1146, in __init__ raise IOError(error) OSError: MoviePy Error: creation of None failed because of the following error: convert-im6.q16: attempt to perform an operation not allowed by the security policy `@/tmp/tmp7wugzgq3.txt' @ error/property.c/InterpretImageProperties/3706. convert-im6.q16: no images defined `PNG32:/tmp/tmpk3q2l74h.png' @ error/convert.c/ConvertImageCommand/3229. . .This error can be due to the fact that ImageMagick is not installed on your computer, or (for Windows users) that you didn't specify the path to the ImageMagick binary in file conf.py, or that the path you specified is incorrect
解决方案
针对TextClip的权限报错
报错核心是ImageMagick的安全策略限制了临时文件操作,修改策略即可:
- 找到ImageMagick的策略配置文件,通常路径为
/etc/ImageMagick-6/policy.xml(版本不同可能为ImageMagick-7); - 编辑文件,找到行:
修改为:<policy domain="path" rights="none" pattern="@*" /><policy domain="path" rights="read|write" pattern="@*" /> - 保存文件后重启终端,重新运行代码。
针对ImageClip+PIL的失效问题
代码存在明显错误:draw.text()接收字符串,无需encode('utf-8'),编码后会变成字节串导致显示异常。修正后的get_image函数:
def get_image(text: str) -> np.array: # 用透明背景更适合叠加视频 image = Image.new('RGBA', (600, 400), color=(255, 255, 255, 0)) draw = ImageDraw.Draw(image) # 显示中文需指定支持中文的字体路径 from PIL import ImageFont font = ImageFont.truetype("/usr/share/fonts/truetype/wqy/wqy-microhei.ttc", 30) draw.text((10, 10), text, fill=(255, 255, 0), font=font) return np.array(image)
同时建议给ImageClip添加位置参数(如set_position(('center', 'bottom'))),避免字幕遮挡视频内容。
更优方案:使用TextClip的method='label'(无需ImageMagick)
MoviePy的TextClip支持method='label'参数,直接用PIL渲染文本,完全不依赖ImageMagick,符合“无需生成大量文件”的需求:
from moviepy.video.VideoClip import TextClip, CompositeVideoClip # 替换为本地支持中文的字体路径 font_path = "/usr/share/fonts/truetype/wqy/wqy-microhei.ttc" audio_with_subtitles = [("示例中文", 3), ("Hello World", 2), ...] textclips = [ TextClip( phrase, fontsize=30, color='black', font=font_path, method='label' # 关键:用PIL渲染,不依赖ImageMagick ).set_duration(duration).set_position(('center', 'bottom')) for phrase, duration in audio_with_subtitles ] # 叠加到原始视频并导出 final_clip = CompositeVideoClip([videoclip, *textclips]) final_clip.write_videofile("output.mp4", codec="libx264")
内容的提问来源于stack exchange,提问作者biflé
相关产品推荐
相关产品推荐

