moviepy==1.0.2
整块字幕移动
# 字幕整块平移🆗
from moviepy.editor import VideoFileClip, CompositeVideoClip, ImageClip
from PIL import Image, ImageFont, ImageDraw
import numpy as np
def wrap_text(text, font, max_width):
"""
自动换行函数:根据指定的最大宽度对文本进行折行
:param text: 字幕文本
:param font: PIL字体对象
:param max_width: 每行最大宽度
:return: 换行后的文本列表
"""
lines = []
current_line = ""
for char in text: # 中文按字符处理
test_line = current_line + char
line_width = font.getbbox(test_line)[2] # 使用 getbbox(文本边界) 获取宽度
if line_width <= max_width:
current_line = test_line
else:
lines.append(current_line)
current_line = char
if current_line: # 添加最后一行
lines.append(current_line)
return lines
def generate_subtitle_image(text, font_path, font_size, video_width, video_height, white_space):
"""
生成带有字幕的图像,自动换行
:param text: 字幕文本
:param font_path: 字体路径
:param font_size: 字体大小
:param video_width: 视频宽度
:param video_height: 视频高度
:param white_space: 视频左右留白
:return: 带有字幕的图像(numpy数组)
"""
font = ImageFont.truetype(font_path, font_size)
max_width = video_width - white_space # 留左右边距
# 自动换行
wrapped_text = wrap_text(text, font, max_width)
# 创建字幕图像
image = Image.new("RGBA", (video_width, video_height), (255, 255, 255, 0)) # 透明背景
draw = ImageDraw.Draw(image)
# 绘制字幕:居中显示,每行水平居中,底部显示
line_height = font.getbbox("测试")[3] # 使用 getbbox 获取行高
y_position = video_height - line_height * len(wrapped_text) - 20 # 字幕距底部20像素
for line in wrapped_text:
text_width = font.getbbox(line)[2]
x_position = (video_width - text_width) // 2 # 居中
draw.text((x_position, y_position), line, font=font, fill="white")
y_position += line_height
return np.array(image)
def add_scroll_effect(subtitle_image, video_clip, duration=3):
"""
给字幕添加平移效果(从上至下)
:param subtitle_image: 字幕图像(numpy数组)
:param video_clip: 视频剪辑
:param duration: 平移的持续时间
:return: 带平移效果的字幕剪辑
"""
subtitle_clip = ImageClip(subtitle_image, duration=duration)
# 获取字幕的最终y坐标(视频底部附近)
final_y_position = video_clip.h - subtitle_clip.h - 20 # 字幕停留在视频底部
# 设置字幕从顶部滑入,平移至底部
subtitle_clip = subtitle_clip.set_position(lambda t: ("center", min(final_y_position, -subtitle_clip.h + t * (video_clip.h + subtitle_clip.h) / duration)))
return subtitle_clip
def output(subtitle_clip, video_clip, output_path):
# 合成视频
composite_clip = CompositeVideoClip([video_clip, subtitle_clip])
# 输出视频
composite_clip.write_videofile(output_path, codec="libx264", fps=24)
if __name__ == '__main__':
# 视频路径
video_path = "1127.mp4"
output_path = "output_with_falling_subtitles.mp4"
# 加载视频并获取宽高
video_clip = VideoFileClip(video_path)
video_width, video_height = video_clip.w, video_clip.h
# 字幕文本
subtitle_text = "这是一个字幕示例,平移到视频底部"
# 字幕样式
custom_font_path = r"C:\Windows\Fonts\msyh.ttc" # 替换为实际字体路径
font_size = 50
white_space = 20 # 字幕左右留白
# 生成字幕图像
subtitle_image = generate_subtitle_image(
subtitle_text, custom_font_path, font_size, video_width, video_height, white_space
)
# 给字幕添加平移效果
subtitle_clip = add_scroll_effect(subtitle_image, video_clip)
# 合成视频并应用字幕效果
output(subtitle_clip, video_clip, output_path)
从右到左
#整个字幕从右到左🆗
from moviepy.editor import VideoFileClip, CompositeVideoClip, ImageClip
from PIL import Image, ImageFont, ImageDraw
import numpy as np
def wrap_text(text, font, max_width):
"""
自动换行函数:根据指定的最大宽度对文本进行折行
:param text: 字幕文本
:param font: PIL字体对象
:param max_width: 每行最大宽度
:return: 换行后的文本列表
"""
lines = []
current_line = ""
for char in text: # 中文按字符处理
test_line = current_line + char
line_width = font.getbbox(test_line)[2] # 使用 getbbox(文本边界) 获取宽度
if line_width <= max_width:
current_line = test_line
else:
lines.append(current_line)
current_line = char
if current_line: # 添加最后一行
lines.append(current_line)
return lines
def generate_subtitle_image(text, font_path, font_size, video_width, video_height, white_space):
"""
生成带有字幕的图像,自动换行
:param text: 字幕文本
:param font_path: 字体路径
:param font_size: 字体大小
:param video_width: 视频宽度
:param video_height: 视频高度
:param white_space: 视频左右留白
:return: 带有字幕的图像(numpy数组)
"""
font = ImageFont.truetype(font_path, font_size)
max_width = video_width - white_space # 留左右边距
# 自动换行
wrapped_text = wrap_text(text, font, max_width)
# 创建字幕图像
image = Image.new("RGBA", (video_width, video_height), (255, 255, 255, 0)) # 透明背景
draw = ImageDraw.Draw(image)
# 绘制字幕:居中显示,每行水平居中,底部显示
line_height = font.getbbox("测试")[3] # 使用 getbbox 获取行高
y_position = video_height - line_height * len(wrapped_text) - 20 # 字幕距底部20像素
for line in wrapped_text:
text_width = font.getbbox(line)[2]
x_position = (video_width - text_width) // 2 # 居中
draw.text((x_position, y_position), line, font=font, fill="white")
y_position += line_height
return np.array(image)
def add_scroll_effect(subtitle_image, video_clip, text, font_path, font_size, white_space, duration=5, stay_duration=5):
"""
给字幕添加从右到左滚动效果,并最终固定在视频底部
:param subtitle_image: 字幕图像(numpy数组)
:param video_clip: 视频剪辑
:param text: 字幕文本
:param font_path: 字体路径
:param font_size: 字体大小
:param white_space: 字幕左右留白
:param duration: 滚动持续时间
:param stay_duration: 字幕停留时间(以秒为单位)
:return: 带滚动效果的字幕剪辑
"""
subtitle_clip = ImageClip(subtitle_image, duration=duration + stay_duration)
# 设置字幕初始位置在屏幕右边,使用 `set_position` 来实现滚动
def scroll_position(t):
max_x_position = video_clip.w + subtitle_clip.w
if t < duration: # 在滚动时间内,字幕从右到左
return max_x_position - (max_x_position * t / duration), video_clip.h - subtitle_clip.h - 20
else: # 滚动结束后,字幕保持在底部
return (video_clip.w - subtitle_clip.w) // 2, video_clip.h - subtitle_clip.h - 20
# 设置字幕开始时间和持续时间
subtitle_clip = subtitle_clip.set_position(scroll_position).set_start(0).set_duration(duration + stay_duration)
return subtitle_clip
def output(subtitle_clip, video_clip, output_path):
# 合成视频
composite_clip = CompositeVideoClip([video_clip, subtitle_clip])
# 输出视频
composite_clip.write_videofile(output_path, codec="libx264", fps=24)
if __name__ == '__main__':
# 视频路径
video_path = "1127.mp4"
output_path = "output_with_falling_subtitles.mp4"
# 加载视频并获取宽高
video_clip = VideoFileClip(video_path)
video_width, video_height = video_clip.w, video_clip.h
# 字幕文本
subtitle_text = "ewrqwrwgf这是一个字幕示例,平移到视频底部"
# 字幕样式
custom_font_path = r"C:\Windows\Fonts\msyh.ttc" # 替换为实际字体路径
font_size = 50
white_space = 20 # 字幕左右留白
# 生成字幕图像
subtitle_image = generate_subtitle_image(subtitle_text, custom_font_path, font_size, video_width, video_height, white_space)
# 给字幕添加平移效果
subtitle_clip = add_scroll_effect(subtitle_image, video_clip, subtitle_text, custom_font_path, font_size, white_space, stay_duration=10)
# 合成视频并应用字幕效果
output(subtitle_clip, video_clip, output_path)
单个字幕移动可参照,字符动态效果
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!