Python實(shí)現(xiàn)視頻mp4垂直和水平拼接
視頻mp4垂直拼接 水平拼接
pinjie_v.py
import imageio
import numpy as np
import os
import cv2
def pinjie_v(dir1,dir2,out_dir):
os.makedirs(out_dir, exist_ok=True)
# 獲取目錄下的所有視頻文件
video_files_1 = [f for f in os.listdir(dir1) if f.endswith('.mp4')]
video_files_2 = [f for f in os.listdir(dir2) if f.endswith('.mp4')]
# 確保兩個(gè)目錄下的視頻文件是同名的
common_files = set(video_files_1).intersection(video_files_2)
# 如果沒有同名視頻,退出
if not common_files:
print("沒有同名的視頻文件。")
exit()
for video_name in common_files:
print(f"處理視頻: {video_name}")
# if "user-4fd103ee-38d4-43c5-bb2a-f496d2fe065e" not in video_name:
# continue
# 打開視頻文件
video_path_1 = os.path.join(dir1, video_name)
video_path_2 = os.path.join(dir2, video_name)
reader1 = imageio.get_reader(video_path_1)
reader2 = imageio.get_reader(video_path_2)
# 獲取視頻信息(假設(shè)兩個(gè)視頻有相同幀數(shù))
fps = reader1.get_meta_data()['fps']
num_frames = min(reader1.count_frames(), reader2.count_frames())
# 創(chuàng)建輸出文件
output_path = os.path.join(out_dir, f"v_{video_name}")
# writer = imageio.get_writer(output_path, fps=fps)
if os.path.exists(output_path):
continue
outs = []
# 逐幀處理
for i in range(num_frames):
frame1 = reader1.get_data(i)
frame2 = reader2.get_data(i)
# 獲取幀的高度和寬度
height1, width1, _ = frame1.shape
height2, width2, _ = frame2.shape
if height1 > width1:
if height1 != height2:
y_scale = height1 / height2
frame2 = cv2.resize(frame2, (int(width2 * y_scale), height1), interpolation=cv2.INTER_AREA)
elif height1 <= width1:
if width1 != width2:
x_scale = width1 / width2
frame2 = cv2.resize(frame2, (width1, int(height2 * x_scale)), interpolation=cv2.INTER_AREA)
if height1 > width1:
frame = np.hstack([frame1, frame2])
else:
frame = np.vstack([frame1, frame2])
outs.append(frame)
try:
imageio.mimsave(f'{output_path}', outs, fps=fps, macro_block_size=None)
except Exception as e:
print(e)
# writer.close()
print(f"視頻 {video_name} 拼接完成,保存在 {output_path}")
if __name__ == '__main__':
# 設(shè)置目錄路徑
dir1 = r'E:\project\smpl\render_blender\linux\hmr_res'
dir2 = r'E:\project\smpl\render_blender\linux\hmr2_res'
dir1 = r'E:\project\smpl\render_blender\linux\val_out_depth_any_color'
dir2 = r'E:\project\smpl\render_blender\linux\val_out_video'
dir1 = r'E:\project\smpl\render_blender\linux\val_out_depth_any_color'
dir2 = r'E:\project\smpl\render_blender\linux\val_out_video'
dir1=r'E:\project\smpl\render_blender\linux\test_lbg_o'
dir2 =r'E:\project\smpl\render_blender\linux\test_lbg6'
out_dir = 'track_diff'
pinjie_v(dir1,dir2,out_dir)方法補(bǔ)充
下面小編為大家整理了Python中視頻拼接的示例代碼,希望對(duì)大家有所幫助
#!/user/bin/env python
# coding=utf-8
"""
@project : csdn
@author : 劍客阿良_ALiang
@file : concat_video.py
@ide : PyCharm
@time : 2021-12-23 15:23:16
"""
from ffmpy import FFmpeg
import os
import uuid
import subprocess
# 視頻拼接
def concat(video_list: list, output_dir: str):
if len(video_list) == 0:
raise Exception('video_list can not empty')
_ext = check_format(video_list)
_fps = check_fps(video_list)
_result_path = os.path.join(
output_dir, '{}{}'.format(
uuid.uuid1().hex, _ext))
_tmp_config = make_tmp_concat_config(video_list, output_dir)
ff = FFmpeg(inputs={'{}'.format(_tmp_config): '-f concat -safe 0 -y'}, outputs={
_result_path: '-c copy'})
print(ff.cmd)
ff.run()
os.remove(_tmp_config)
return _result_path
# 構(gòu)造拼接所需臨時(shí)文件
def make_tmp_concat_config(video_list: list, output_dir: str):
_tmp_concat_config_path = os.path.join(output_dir, '{}.txt'.format(uuid.uuid1().hex))
with open(_tmp_concat_config_path, mode='w', encoding='utf-8') as f:
f.writelines(list(map(lambda x: 'file {}\n'.format(x), video_list)))
return _tmp_concat_config_path
# 校驗(yàn)每個(gè)視頻的格式
def check_format(video_list: list):
_video_format = ''
for x in video_list:
_ext = os.path.splitext(x)[-1]
if _video_format == '' and _ext != '':
_video_format = _ext
continue
if _video_format != '' and _ext == _video_format:
continue
if _video_format != '' and _ext != _video_format:
raise Exception('Inconsistent video format')
return _video_format
# 校驗(yàn)每個(gè)視頻的fps
def check_fps(video_list: list):
_video_fps = 0
for x in video_list:
_fps = get_video_fps(x)
if _video_fps == 0 and _fps:
_video_fps = _fps
continue
if _video_fps != 0 and _fps == _video_fps:
continue
if _video_fps != '' and _fps != _video_fps:
raise Exception('Inconsistent video fps')
if _video_fps == 0:
raise Exception('video fps error')
return _video_fps
# 獲取視頻fps
def get_video_fps(video_path: str):
ext = os.path.splitext(video_path)[-1]
if ext != '.mp4' and ext != '.avi' and ext != '.flv':
raise Exception('format not support')
ffprobe_cmd = 'ffprobe -v error -select_streams v -of default=noprint_wrappers=1:nokey=1 -show_entries stream=r_frame_rate {}'
p = subprocess.Popen(
ffprobe_cmd.format(video_path),
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
shell=True)
out, err = p.communicate()
print("subprocess 執(zhí)行結(jié)果:out:{} err:{}".format(out, err))
fps_info = str(out, 'utf-8').strip()
if fps_info:
if fps_info.find("/") > 0:
video_fps_str = fps_info.split('/', 1)
fps_result = int(int(video_fps_str[0]) / int(video_fps_str[1]))
else:
fps_result = int(fps_info)
else:
raise Exception('get fps error')
return fps_result
if __name__ == '__main__':
print(concat(['D:/tmp/100.mp4', 'D:/tmp/101.mp4'], 'C:/Users/huyi/Desktop'))到此這篇關(guān)于Python實(shí)現(xiàn)視頻mp4垂直和水平拼接的文章就介紹到這了,更多相關(guān)Python視頻拼接內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python掃描proxy并獲取可用代理ip的實(shí)例
下面小編就為大家?guī)硪黄猵ython掃描proxy并獲取可用代理ip的實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-08-08
Python實(shí)現(xiàn)抓取頁(yè)面上鏈接的簡(jiǎn)單爬蟲分享
這篇文章主要介紹了Python實(shí)現(xiàn)抓取頁(yè)面上鏈接的簡(jiǎn)單爬蟲分享,本文使用了一個(gè)開源模塊requests實(shí)現(xiàn)需求,需要的朋友可以參考下2015-01-01
TensorFlow tf.nn.conv2d_transpose是怎樣實(shí)現(xiàn)反卷積的
這篇文章主要介紹了TensorFlow tf.nn.conv2d_transpose是怎樣實(shí)現(xiàn)反卷積的,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04
理想高通濾波實(shí)現(xiàn)Python opencv示例
今天小編就為大家分享一篇關(guān)于理想高通濾波實(shí)現(xiàn)Python opencv示例,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2019-01-01
Python的jsonpath庫(kù)使用方法實(shí)例
這篇文章主要介紹了Python的jsonpath庫(kù)使用方法實(shí)例,接口返回的jsonn數(shù)據(jù),需要取值后斷言,一般我們是使用jsonpath來提取接口返回的數(shù)據(jù) ,JsonPath是一種信息抽取類庫(kù),是從JSON文檔中抽取指定信息的工具,,需要的朋友可以參考下2023-08-08

