当前位置: 代码网 > it编程>前端脚本>Python > 基于Python实现视频和音频长度对齐合成并添加字幕功能

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

2025年11月26日 Python 我要评论
环境设置首先,我们需要安装必要的库。可以使用以下命令来安装它们:pip install opencv-python moviepy pillow准备工作准备音频和视频文件:确保你有需要对齐的音频和视频

环境设置

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

pip install opencv-python moviepy pillow

准备工作

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

实现代码

以下是实现音视频对齐并添加中文字幕的完整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
import re 

def replace_punctuation_with_at(input_string):
    # 使用正则表达式匹配所有标点符号并替换为 @
    result = re.sub(r'[^\w\s]', '@', input_string)
    return result

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, audio_volume=1.0):
    # 加载音频文件并调整音量
    original_audio = audiosegment.from_file(audio_path)
    original_audio = original_audio + (audio_volume * 10 - 10)  # 调整音量
    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))

    # 分批读取和写入视频帧,并添加字幕
    subtitle_text = replace_punctuation_with_at(subtitle_text)
    subtitle_text_list = [text for text in subtitle_text.split("@") if text]
    print(subtitle_text_list)
    subtitles_per_frame = frame_count // len(subtitle_text_list)
    current_subtitle_index = 0

    for frame_idx in range(frame_count):
        ret, frame = cap.read()
        if not ret:
            break
        # 添加当前字幕到帧
        if frame_idx // subtitles_per_frame >= current_subtitle_index and current_subtitle_index < len(subtitle_text_list):
            frame = add_chinese_subtitle_to_frame(frame, subtitle_text_list[current_subtitle_index], (width // 2, height - subtitle_bottom_margin), font_path, font_size, font_color)
            if frame_idx // subtitles_per_frame > current_subtitle_index:
                current_subtitle_index += 1
        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)
    
    # trim the last 0.3 seconds
    final_clip = final_clip.subclip(0, final_clip.duration - 0.3)
    
    # write the final video file
    final_clip.write_videofile(output_path, codec="libx264", audio_codec="aac")
    
    # close the clips to release the file
    final_clip.close()
    video_clip.close()
    audio_clip.close()

    # 删除临时文件
    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"
    subtitle_text='然而屈原的直言进谏,引来了朝中权臣的嫉恨,他成为了政治斗争的牺牲品。'
    output_path = "synced_video.mp4"

    sync_audio_video_add_subtitle(audio_path, 
                                video_path, 
                                output_path,
                                subtitle_text=subtitle_text,
                                font_path="./notosanscjksc-regular.ttf",
                                font_size=40, # 设置字体大小
                                font_color=(255, 255, 255), # 设置字体颜色
                                subtitle_bottom_margin=80, # 设置字幕底部的位置
                                audio_volume=2) # 调整音频音量,1.0为原始音量,1.5为增加50%音量

代码说明

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

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

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

new_fps = fps * (video_duration / audio_duration)

调整参数

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

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

运行示例

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

通过这个教程,你应该能够使用python轻松地实现视频和音频的对齐,并在视频中添加中文字幕。

以上就是基于python实现视频和音频长度对齐合成并添加字幕功能的详细内容,更多关于python视频和音频对齐并添加字幕的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com