基于Python實(shí)現(xiàn)視頻和音頻長度對(duì)齊合成并添加字幕功能
環(huán)境設(shè)置
首先,我們需要安裝必要的庫??梢允褂靡韵旅顏戆惭b它們:
pip install opencv-python moviepy Pillow
準(zhǔn)備工作
- 準(zhǔn)備音頻和視頻文件:確保你有需要對(duì)齊的音頻和視頻文件。
- 下載支持中文的字體文件:例如SimHei.ttf,并將其保存到合適的位置。在示例中,我們使用NotoSansCJKsc-Regular.ttf。
實(shí)現(xiàn)代碼
以下是實(shí)現(xiàn)音視頻對(duì)齊并添加中文字幕的完整Python代碼。你可以將這段代碼保存為一個(gè)Python文件,并根據(jù)需要進(jìn)行調(diào)用。
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):
# 使用正則表達(dá)式匹配所有標(biāo)點(diǎn)符號(hào)并替換為 @
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圖像轉(zhuǎn)換為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]
# 計(jì)算字幕的放置位置
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圖像轉(zhuǎn)換回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):
# 加載音頻文件并調(diào)整音量
original_audio = AudioSegment.from_file(audio_path)
original_audio = original_audio + (audio_volume * 10 - 10) # 調(diào)整音量
silence = AudioSegment.silent(duration=500) # 0.5秒的靜音
audio_with_silence = silence + original_audio + silence
# 創(chuàng)建臨時(shí)文件以保存修改后的音頻
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
# 計(jì)算新的視頻幀率
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))
# 創(chuàng)建臨時(shí)文件以存儲(chǔ)中間視頻結(jié)果
temp_video_path = os.path.join(tempfile.gettempdir(), "temp_video.mp4")
# 創(chuàng)建VideoWriter對(duì)象
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
# 添加當(dāng)前字幕到幀
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將音頻和調(diào)整后的視頻合并
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()
# 刪除臨時(shí)文件
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='然而屈原的直言進(jìn)諫,引來了朝中權(quán)臣的嫉恨,他成為了政治斗爭的犧牲品。'
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, # 設(shè)置字體大小
font_color=(255, 255, 255), # 設(shè)置字體顏色
subtitle_bottom_margin=80, # 設(shè)置字幕底部的位置
audio_volume=2) # 調(diào)整音頻音量,1.0為原始音量,1.5為增加50%音量
代碼說明
- add_chinese_subtitle_to_frame: 這個(gè)函數(shù)將字幕添加到給定的幀上。它使用PIL庫來繪制字幕,然后將圖像轉(zhuǎn)換回OpenCV格式。
- sync_audio_video_add_subtitle: 這個(gè)函數(shù)處理音頻和視頻的對(duì)齊,并將字幕添加到每一幀上。最終,它將處理好的視頻和音頻合并,并生成輸出文件。
保證音頻長度不變,調(diào)整視頻長度
在此代碼中,我們特別強(qiáng)調(diào)了保證音頻長度不變,通過調(diào)整視頻的幀率來匹配音頻長度。這是通過計(jì)算新的幀率 new_fps 實(shí)現(xiàn)的:
new_fps = fps * (video_duration / audio_duration)
調(diào)整參數(shù)
你可以通過調(diào)整以下參數(shù)來修改字幕的顯示效果和位置:
font_size: 字體大小。font_color: 字體顏色。subtitle_bottom_margin: 字幕距離視頻底部的距離。
運(yùn)行示例
你可以使用提供的示例用法來運(yùn)行代碼,只需將audio_path、video_path和font_path替換為你自己的文件路徑即可。
通過這個(gè)教程,你應(yīng)該能夠使用Python輕松地實(shí)現(xiàn)視頻和音頻的對(duì)齊,并在視頻中添加中文字幕。
以上就是基于Python實(shí)現(xiàn)視頻和音頻長度對(duì)齊合成并添加字幕功能的詳細(xì)內(nèi)容,更多關(guān)于Python視頻和音頻對(duì)齊并添加字幕的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Python中字節(jié)數(shù)組和16進(jìn)制字符串轉(zhuǎn)換方式
這篇文章主要介紹了Python中字節(jié)數(shù)組和16進(jìn)制字符串轉(zhuǎn)換方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06
一文詳解Python HTML/XML解析庫BeautifulSoup4
這段文章詳細(xì)介紹了BeautifulSoup4的使用方法、解析器選擇與性能對(duì)比,并提供了實(shí)戰(zhàn)案例,文章強(qiáng)調(diào)在生產(chǎn)環(huán)境中推薦使用lxml解析器,同時(shí)提供了數(shù)據(jù)清洗、文檔樹修改及優(yōu)化技巧等內(nèi)容,需要的朋友可以參考下2026-06-06
python模塊詳解之pywin32使用文檔(python操作windowsAPI)
pywin32是一個(gè)第三方模塊庫,主要的作用是方便python開發(fā)者快速調(diào)用windows API的一個(gè)模塊庫,這篇文章主要給大家介紹了關(guān)于python模塊詳解之pywin32使用文檔的相關(guān)資料,文中將python操作windowsAPI介紹的非常詳細(xì),需要的朋友可以參考下2024-01-01
使用python的turtle函數(shù)繪制一個(gè)滑稽表情
Turtle庫是Python語言中一個(gè)很流行的繪制圖像的函數(shù)庫,今天通過實(shí)例代碼給大家分享使用python的turtle函數(shù)繪制一個(gè)滑稽表情,一起看看吧2020-02-02
python 實(shí)現(xiàn)百度網(wǎng)盤非會(huì)員上傳超過500個(gè)文件的方法
這篇文章主要介紹了python 實(shí)現(xiàn)百度網(wǎng)盤非會(huì)員上傳超過500個(gè)文件的方法,幫助大家更好的利用python解決問題,感興趣的朋友可以了解下2021-01-01
Python遠(yuǎn)程控制Windows服務(wù)器的方法總結(jié)
在信息時(shí)代的洪流中,掌握一門編程語言已經(jīng)成為一項(xiàng)必備技能,Python,這門以簡潔、易學(xué)、強(qiáng)大著稱的編程語言,更是成為無數(shù)開發(fā)者的大寶劍,今天,我們要探討的就是如何用 Python 遠(yuǎn)程控制 Windows 服務(wù)器,需要的朋友可以參考下2024-07-07

