当前位置: 首页 > news >正文

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

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

环境设置

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

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 resultdef 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 // 2y = 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 framedef 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 = 0for 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 += 1out.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 secondsfinal_clip = final_clip.subclip(0, final_clip.duration - 0.3)# Write the final video filefinal_clip.write_videofile(output_path, codec="libx264", audio_codec="aac")# Close the clips to release the filefinal_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轻松地实现视频和音频的对齐,并在视频中添加中文字幕。如果你有任何问题或建议,请在评论区留言!


相关文章:

  • ubuntu gitlab 部署 私有git库
  • 银河麒麟系统安装
  • 为什么javascript中数组可以存储不同类型的元素,而大多编程语言数组必须存储相同的元素?
  • LeetCode-day11-2813. 子序列最大优雅度
  • 每日一题——Python实现PAT乙级1012 数字分类(举一反三+思想解读+逐步优化)五千字好文
  • 基于YOLO检测算法(单检测器网络+多视频输入)设计与实现
  • pdf格式转成jpg图片,pdf格式如何转jpg
  • 网络安全等级保护基本要求解读- 安全计算环境-应用系统和数据安全
  • 19.2 HTTP客户端-定制HTTP请求、调试HTTP、响应超时
  • 国产芯片狂飙,连遥遥领先都给他们写感谢信
  • 2024蓝桥杯初赛决赛pwn题全解
  • java如何预防sql注入
  • 46-4 等级保护 - 网络安全等级保护概述
  • 构建 deno/fresh 的 docker 镜像
  • 解锁 LLMs 的“思考”能力:Chain-of-Thought(CoT) 技术推动复杂推理的新发展
  • [PHP内核探索]PHP中的哈希表
  • 【译】React性能工程(下) -- 深入研究React性能调试
  • Android系统模拟器绘制实现概述
  • Angular Elements 及其运作原理
  • CNN 在图像分割中的简史:从 R-CNN 到 Mask R-CNN
  • Java|序列化异常StreamCorruptedException的解决方法
  • JS进阶 - JS 、JS-Web-API与DOM、BOM
  • Mysql优化
  • 回顾2016
  • 检测对象或数组
  • 深度学习入门:10门免费线上课程推荐
  • 验证码识别技术——15分钟带你突破各种复杂不定长验证码
  • 译有关态射的一切
  • 京东物流联手山西图灵打造智能供应链,让阅读更有趣 ...
  • 蚂蚁金服CTO程立:真正的技术革命才刚刚开始
  • ​TypeScript都不会用,也敢说会前端?
  • ​马来语翻译中文去哪比较好?
  • # 详解 JS 中的事件循环、宏/微任务、Primise对象、定时器函数,以及其在工作中的应用和注意事项
  • #mysql 8.0 踩坑日记
  • #我与Java虚拟机的故事#连载05:Java虚拟机的修炼之道
  • #预处理和函数的对比以及条件编译
  • (13)Hive调优——动态分区导致的小文件问题
  • (js)循环条件满足时终止循环
  • (附源码)计算机毕业设计ssm基于Internet快递柜管理系统
  • (强烈推荐)移动端音视频从零到上手(上)
  • (三)elasticsearch 源码之启动流程分析
  • (三)Kafka 监控之 Streams 监控(Streams Monitoring)和其他
  • (三)mysql_MYSQL(三)
  • (深入.Net平台的软件系统分层开发).第一章.上机练习.20170424
  • (生成器)yield与(迭代器)generator
  • (十七)Flask之大型项目目录结构示例【二扣蓝图】
  • (四)JPA - JQPL 实现增删改查
  • (转)德国人的记事本
  • (转)树状数组
  • ****** 二 ******、软设笔记【数据结构】-KMP算法、树、二叉树
  • *2 echo、printf、mkdir命令的应用
  • .NET Core使用NPOI导出复杂,美观的Excel详解
  • .net php 通信,flash与asp/php/asp.net通信的方法
  • .NET 简介:跨平台、开源、高性能的开发平台
  • .NET 将多个程序集合并成单一程序集的 4+3 种方法