基于python实现视频和音频长度对齐合成并添加字幕

在许多视频编辑任务中,我们常常需要将视频和音频进行对齐,并添加字幕。本文将详细介绍如何使用Python实现这一功能,并在视频中添加中文字幕。我们将使用OpenCV处理视频帧,使用MoviePy处理音频和视频的合成,使用PIL库绘制中文字幕。

环境设置

首先,我们需要安装必要的库。可以使用以下命令来安装它们:

bash 复制代码
pip install opencv-python moviepy Pillow

准备工作

  1. 准备音频和视频文件:确保你有需要对齐的音频和视频文件。
  2. 下载支持中文的字体文件:例如SimHei.ttf,并将其保存到合适的位置。在示例中,我们使用NotoSansCJKsc-Regular.ttf。

实现代码

以下是实现音视频对齐并添加中文字幕的完整Python代码。你可以将这段代码保存为一个Python文件,并根据需要进行调用。

python 复制代码
import cv2
import numpy as np
from moviepy.editor import AudioFileClip, VideoFileClip
from pydub import AudioSegment
from PIL import Image, ImageDraw, ImageFont
import tempfile
import os

def add_chinese_subtitle_to_frame(frame, subtitle_text, position, font_path, font_size, font_color):
    # 将OpenCV图像转换为PIL图像
    img_pil = Image.fromarray(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
    draw = ImageDraw.Draw(img_pil)
    font = ImageFont.truetype(font_path, font_size)
    
    # 获取字幕文本的宽度和高度
    text_bbox = draw.textbbox((0, 0), subtitle_text, font=font)
    text_width = text_bbox[2] - text_bbox[0]
    text_height = text_bbox[3] - text_bbox[1]
    
    # 计算字幕的放置位置
    x = position[0] - text_width // 2
    y = position[1] - text_height // 2
    
    # 在PIL图像上添加字幕
    draw.text((x, y), subtitle_text, font=font, fill=font_color)
    
    # 将PIL图像转换回OpenCV图像
    frame = cv2.cvtColor(np.array(img_pil), cv2.COLOR_RGB2BGR)
    return frame

def sync_audio_video_add_subtitle(audio_path, video_path, output_path, subtitle_text, font_path, font_size=24, font_color=(255, 255, 255), subtitle_bottom_margin=30):
    # 加载音频文件并添加静音
    original_audio = AudioSegment.from_file(audio_path)
    silence = AudioSegment.silent(duration=500)  # 0.5秒的静音
    audio_with_silence = silence + original_audio + silence
    
    # 创建临时文件以保存修改后的音频
    temp_audio_path = os.path.join(tempfile.gettempdir(), "temp_audio.mp3")
    audio_with_silence.export(temp_audio_path, format="mp3")

    # 加载修改后的音频文件
    audio_clip = AudioFileClip(temp_audio_path)
    audio_duration = audio_clip.duration

    # 加载视频文件
    cap = cv2.VideoCapture(video_path)
    fps = cap.get(cv2.CAP_PROP_FPS)
    frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
    video_duration = frame_count / fps

    # 计算新的视频帧率
    new_fps = fps * (video_duration / audio_duration)

    # 获取视频尺寸
    width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
    height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

    # 创建临时文件以存储中间视频结果
    temp_video_path = os.path.join(tempfile.gettempdir(), "temp_video.mp4")

    # 创建VideoWriter对象
    out = cv2.VideoWriter(temp_video_path, cv2.VideoWriter_fourcc(*'mp4v'), new_fps, (width, height))

    # 分批读取和写入视频帧,并添加字幕
    while cap.isOpened():
        ret, frame = cap.read()
        if not ret:
            break
        # 添加字幕到每一帧
        frame = add_chinese_subtitle_to_frame(frame, subtitle_text, (width // 2, height - subtitle_bottom_margin), font_path, font_size, font_color)
        out.write(frame)

    cap.release()
    out.release()

    # 使用MoviePy将音频和调整后的视频合并
    video_clip = VideoFileClip(temp_video_path).set_duration(audio_duration)
    final_clip = video_clip.set_audio(audio_clip)
    final_clip.write_videofile(output_path, codec="libx264", audio_codec="aac")

    # 删除临时文件
    os.remove(temp_audio_path)
    os.remove(temp_video_path)

if __name__ == "__main__":
    # 示例用法
    audio_path = r"C:\Users\60568\Pictures\create\屈原\mp3\00000002.mp3"
    video_path = r"C:\Users\60568\Pictures\create\屈原\mp4\03.mp4"
    output_path = "synced_video.mp4"

    sync_audio_video_add_subtitle(audio_path, 
                                video_path, 
                                output_path,
                                subtitle_text='然而屈原的直言进谏 引来了朝中权臣的嫉恨 他成为了政治斗争的牺牲品',
                                font_path="./NotoSansCJKsc-Regular.ttf",
                                font_size=30, # 设置字体大小
                                font_color=(255, 255, 255), # 设置字体颜色
                                subtitle_bottom_margin=80) # 设置字幕底部的位置

代码说明

  1. add_chinese_subtitle_to_frame: 这个函数将字幕添加到给定的帧上。它使用PIL库来绘制字幕,然后将图像转换回OpenCV格式。
  2. sync_audio_video_add_subtitle: 这个函数处理音频和视频的对齐,并将字幕添加到每一帧上。最终,它将处理好的视频和音频合并,并生成输出文件。

保证音频长度不变,调整视频长度

在此代码中,我们特别强调了保证音频长度不变,通过调整视频的帧率来匹配音频长度。这是通过计算新的帧率 new_fps 实现的:

python 复制代码
new_fps = fps * (video_duration / audio_duration)

调整参数

你可以通过调整以下参数来修改字幕的显示效果和位置:

  • font_size: 字体大小。
  • font_color: 字体颜色。
  • subtitle_bottom_margin: 字幕距离视频底部的距离。

运行示例

你可以使用提供的示例用法来运行代码,只需将audio_pathvideo_pathfont_path替换为你自己的文件路径即可。

通过这个教程,你应该能够使用Python轻松地实现视频和音频的对齐,并在视频中添加中文字幕。如果你有任何问题或建议,请在评论区留言!


相关推荐
数据智能老司机13 小时前
精通 Python 设计模式——分布式系统模式
python·设计模式·架构
数据智能老司机14 小时前
精通 Python 设计模式——并发与异步模式
python·设计模式·编程语言
数据智能老司机14 小时前
精通 Python 设计模式——测试模式
python·设计模式·架构
数据智能老司机14 小时前
精通 Python 设计模式——性能模式
python·设计模式·架构
c8i14 小时前
drf初步梳理
python·django
每日AI新事件14 小时前
python的异步函数
python
这里有鱼汤15 小时前
miniQMT下载历史行情数据太慢怎么办?一招提速10倍!
前端·python
databook1 天前
Manim实现脉冲闪烁特效
后端·python·动效
程序设计实验室1 天前
2025年了,在 Django 之外,Python Web 框架还能怎么选?
python
倔强青铜三1 天前
苦练Python第46天:文件写入与上下文管理器
人工智能·python·面试