python實現(xiàn)視頻抽幀與添加背景音頻和字幕朗讀的腳本分享
1.介紹
看完本文章,你將能學(xué)會一下內(nèi)容:
- 批量視頻抽幀;
- 添加srt字幕;
- 添加srt配音;
- 添加背景音樂;
- 多視頻片段合成一個新視頻;
效果:
2.安裝依賴
首先安裝視頻處理庫opencv-python和moviepy,安裝方式pip install xxx。
py文件頂部中導(dǎo)入(下文中使用到的函數(shù)將不在贅述導(dǎo)入過程):
from moviepy.editor import VideoFileClip, CompositeAudioClip, CompositeVideoClip, concatenate_videoclips from cv2 import VideoCapture, VideoWriter, VideoWriter_fourcc, CAP_PROP_FRAME_COUNT
3.視頻抽幀
cv2.VideoCapture:
作用:用于從視頻文件或攝像頭捕獲視頻幀。
解釋:這個函數(shù)允許你創(chuàng)建一個視頻捕獲對象,以便從指定的視頻源中讀取視頻幀。你可以傳遞視頻文件的路徑或攝像頭的索引作為參數(shù),然后使用它來逐幀讀取視頻。
cv2.VideoWriter:
作用:用于將視頻幀寫入到一個新的視頻文件中。
解釋:這個函數(shù)允許你創(chuàng)建一個視頻寫入對象,以便將視頻幀寫入到一個新的視頻文件中。你可以指定輸出文件的名稱、視頻編解碼器、幀速率、分辨率等參數(shù)。這在視頻編輯和保存處理后的視頻時非常有用。
cv2.VideoWriter_fourcc:
作用:用于指定視頻編解碼器的四字符碼(FourCC)。
解釋:FourCC 是一個4字節(jié)的代碼,用于標(biāo)識視頻編解碼器。不同的編解碼器有不同的FourCC碼。通過使用這個函數(shù),你可以選擇要在輸出視頻中使用的編解碼器。
CAP_PROP_FRAME_COUNT:
作用:用于獲取視頻文件中的總幀數(shù)。
解釋:CAP_PROP_FRAME_COUNT 是 cv2.VideoCapture 對象的一個屬性,用于獲取視頻文件中的總幀數(shù)。這對于確定視頻的時長以及循環(huán)播放視頻等操作非常有用。
完整代碼塊:
# 單個視頻抽幀 def video_extract_frame(video_path, out_path): # 打開視頻文件 vc = VideoCapture(video_path) # 視頻的總幀數(shù) total_frame = int(vc.get(CAP_PROP_FRAME_COUNT)) video = VideoFileClip(video_path, audio=False) # # 創(chuàng)建一個視頻寫入對象。設(shè)置視頻的寬度和高度、幀率、輸出路徑 fourcc = VideoWriter_fourcc(*'mp4v') videoWriter = VideoWriter(out_path, fourcc, VIDEO_FPS, (video.w, video.h)) if vc.isOpened(): status, frame = vc.read() else: status = False print("視頻沒有打開成功!") vc.release() video.close() videoWriter.release() return False if status: for index in trange(total_frame, desc='抽幀進(jìn)度'): # 讀取視頻幀并寫入輸出視頻 status, frame = vc.read() if index % VIDEO_FPS == 0: skip_frames = tool.get_unique_random_numbers(index, VIDEO_FPS) if index in skip_frames: continue videoWriter.write(frame) videoWriter.release() vc.release() video.close()
調(diào)用上面的抽幀函數(shù):
video_extract_frame('./test.mp4', 'result.mp4')
如果有多個視頻需要抽幀,只需要循環(huán)調(diào)用即可:
for index, video_file in enumerate(['1.mp4', '2.mp4', '3.mp4']): //取出鏈接中的視頻文件名稱,例如1,2,3 video_name = tool.get_file_name(video_file) //組裝成新目錄、新名字(根據(jù)自己需要) out_path = "{}{}.mp4".format(frame_path, video_name) videoTool.video_extract_frame(video_file, out_path) print("\n第{}條, 視頻抽幀已完成: {}".format(index + 1, out_path))
4.添加srt字幕
完整示例代碼:
# 字幕片段 def generate_textclip(text, width, params, start, duration) -> TextClip: return TextClip( text, font=params.get('font'), align=params.get('align'), fontsize=params.get('fontsize'), color=params.get('color', '#ffbd00'), size=(width, params.get('height')), stroke_color=params.get('stroke_color'), stroke_width=params.get('stroke_width') ).set_position((params['location']['x'], params['location']['y'])).set_duration(duration).set_start(start) # 添加srt字幕 def add_srt(video_clip, params): if not (isfile(params["srt_path"]) and params["srt_path"].endswith('.srt')): print('字幕僅支持srt格式!') return [] else: # 獲取視頻的寬度和高度 v_width, v_height = video_clip.w, video_clip.h # 所有字幕剪輯 txts = [] content = tool.read_srt(params["srt_path"]) sequences = tool.get_sequences(content) max_count = len(sequences) max_duration = video_clip.duration srt_text = params["srt_text"] for index, line in enumerate(sequences): print("字幕生成進(jìn)度:{}/{}".format(index, max_count)) if len(line) < 3: continue start = line[1].split(' --> ')[0] end = line[1].split(' --> ')[1] start = tool.str_float_time(start) end = tool.str_float_time(end) start, end = map(float, (start, end)) if start >= max_duration: break if end >= max_duration: end = max_duration duration = end - start txt_srt = generate_textclip(line[2], (v_width - 20), srt_text, start, duration) txts.append(txt_srt) print("\n字幕轉(zhuǎn)換已完成...") return txts
tool.read_srt 代碼:
def read_srt(self, path): content = "" with open(path, 'r', encoding='UTF-8') as f: content = f.read() return content
tool.get_sequences 代碼:
# 字幕拆分 def get_sequences(self, content): sequences = content.split('\n\n') sequences = [sequence.split('\n') for sequence in sequences] # 去除每一句空值 sequences = [list(filter(None, sequence)) for sequence in sequences] # 去除整體空值 return list(filter(None, sequences))
tool.str_float_time 代碼:
# 字符串?dāng)?shù)字格式化成時間 def str_float_time(self, str): str_list = str.split(':') hour = int(str_list[0]) minute = int(str_list[1]) second = int(str_list[2].split(',')[0]) minsecond = int(str_list[2].split(',')[1]) allTime = hour * 60 * 60 + minute * 60 + second + minsecond / 1000 return allTime
5.添加背景音樂、srt音頻、導(dǎo)出
# frame_video_paths:是抽幀后的視頻片段 def merge_videos_with_bgm(params, frame_video_paths, out_path): # 用VideoFileClip加載所有輸入視頻文件 video_clips = [VideoFileClip(file) for file in frame_video_paths] final_clip = concatenate_videoclips(video_clips) bgm_music = audioTool.get_audio({ "volume": params.get("bgm_volume", 0.1), #背景音頻小聲點 "duration": final_clip.duration, "audio_path": params['bgm_path'] }) # 加載主音樂(朗讀音頻) main_music = audioTool.get_audio({ "volume": params.get("audio_volume", 1.0),# 朗讀音頻大聲點 "duration": final_clip.duration, "audio_path": params['audio_path'] }) # 將音樂混合到最終視頻切片 final_clip = final_clip.set_audio(CompositeAudioClip([main_music, bgm_music])) video_srt = videoTextTool.add_srt(final_clip, params) final_clip.extend(video_srt) # 復(fù)合視頻 video = CompositeVideoClip(final_clip) output_path = path.join(out_path, "result.mp4") # 輸出最終視頻 video.write_videofile(output_path)
到此這篇關(guān)于python實現(xiàn)視頻抽幀與添加背景音頻和字幕朗讀的腳本分享的文章就介紹到這了,更多相關(guān)python視頻抽幀內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
tensorflow1.15與numpy、keras以及Python兼容版本對照方式
這篇文章主要介紹了tensorflow1.15與numpy、keras以及Python兼容版本對照方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-03-03Python使用os模塊和fileinput模塊來操作文件目錄
這篇文章主要介紹了Python編程中使用os模塊和fileinput模塊來操作文件的方法,包括獲取路徑和創(chuàng)建愛你刪除目錄等基本操作的例子,需要的朋友可以參考下2016-01-01Python如何解決secure_filename對中文不支持問題
最近使用到了secure_filename,然后悲劇的發(fā)現(xiàn)中文居然不展示出來,本文就詳細(xì)的介紹一下解決方法,感興趣的可以了解一下2021-07-07python 遺傳算法求函數(shù)極值的實現(xiàn)代碼
今天小編就為大家分享一篇python 遺傳算法求函數(shù)極值的實現(xiàn)代碼,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-02-02