本文包含一些利用Python快速实现的简单视频编辑操作,可以比Pr等软件更为高效的处理视频操作。
2024.11.7.更新【批量视频快速压缩(根据视频大小判别)】
2024.9.5.更新【多个视频拼接操作】、【图片序列合成视频】、【视频转换为动图】、【视频压缩】和【视频裁剪】这些功能。
import os
import subprocess
def get_all_mp4_files(directory):
"""
获取指定目录中所有MP4文件的路径
:param directory: 目录路径
:return: 包含MP4文件路径的列表
"""
mp4_files = []
for root, dirs, files in os.walk(directory):
for file in files:
if file.endswith(".mp4"):
mp4_files.append(os.path.join(root, file))
return mp4_files
def concatenate_videos_ffmpeg(video_paths, output_path):
"""
使用ffmpeg合成多个视频文件
:param video_paths: 包含视频文件路径的列表
:param output_path: 输出视频文件路径
"""
# 创建一个临时文件,包含所有视频文件的路径
with open('video_list.txt', 'w') as f:
for video in video_paths:
f.write(f"file '{video}'\n")
# 使用ffmpeg合成视频,并添加 -fflags +genpts 参数
command = [
'ffmpeg', '-y', '-f', 'concat', '-safe', '0',
'-fflags', '+genpts', '-i', 'video_list.txt', '-c', 'copy', output_path
]
subprocess.run(command, check=True)
# 删除临时文件
os.remove('video_list.txt')
# 指定视频文件所在的目录
directory = r'D:\视频文件夹'
# 获取该目录中所有的MP4视频文件
video_files = get_all_mp4_files(directory)
# 输出视频文件路径
output_file = os.path.join(directory, 'output_video.mp4')
# 合成视频
concatenate_videos_ffmpeg(video_files, output_file)
print(f"合成视频已保存到: {output_file}")
import cv2
import os
import imageio
def images_to_video(image_folder, video_name, fps):
images = [img for img in os.listdir(image_folder) if img.endswith(".png") or img.endswith(".jpg") or img.endswith(".jpeg")]
frame = cv2.imread(os.path.join(image_folder, images[0]))
height, width, layers = frame.shape
video = cv2.VideoWriter(video_name, cv2.VideoWriter_fourcc(*'mp4v'), fps, (width, height))
i = 0
times=1 #循环次数
len_images=len(images)
for time in range(0,times):
for image in images:
i += 1
if os.name == 'nt':
_ = os.system('cls')
else:
_ = os.system('clear')
# 打印合成进度
print('\r合成进度:', int(i / len_images /(times) * 100), '%', end='')
video.write(cv2.imread(os.path.join(image_folder, image)))
cv2.destroyAllWindows()
video.release()
if __name__ == "__main__":
path = 'C:\\Users\\Desktop\\1\\'
image_folder = path + '\\1'
name = 'video'
video_name = path + name + '.mp4'
fps = 15#设置视频帧率
images_to_video(image_folder, video_name, fps)
import imageio
def video_to_gif(video_name, gif_name):
video = imageio.get_reader(video_name)
gif = imageio.get_writer(gif_name, mode='I')
for frame in video:
gif.append_data(frame)
if __name__ == "__main__":
path = 'C:\\Users\\\Desktop\\1\\'
name = '145w'
video_name = path + name + '.mp4'
gif_name = path + name + '.gif'
video_to_gif(video_name, gif_name)
压缩画幅(比如4K压缩成1080P)
import subprocess
def compress_video_to_1080p(input_path, output_path):
"""
使用ffmpeg将视频从4K压缩到1080P
:param input_path: 输入视频文件路径
:param output_path: 输出视频文件路径
"""
command = [
'ffmpeg', '-i', input_path, '-vf', 'scale=1920:1080',
'-c:v', 'libx264', '-crf', '23', '-preset', 'fast',
'-c:a', 'aac', '-b:a', '192k', output_path
]
subprocess.run(command, check=True)
print(f"视频已压缩并保存到: {output_path}")
# 输入视频文件路径(4K视频)
path = 'E:\\视频路径\\'
name = 'video.mp4'
input_video_path = path + name
# 输出视频文件路径(压缩后的1080P视频)
output_video_path = path + 'compressed_video_1080p.mp4'
# 压缩视频
compress_video_to_1080p(input_video_path, output_video_path)
压缩比特率(比如高比特率压缩到3000,画幅不变)
import os
import subprocess
# 定义输入和输出文件夹路径
input_path = 'C:\\Users\\Videos\\Captures\\1\\'
output_path = 'C:\\Users\\Videos\\Captures\\2\\'
# 获取输入文件夹中所有视频文件的列表
video_files = [f for f in os.listdir(input_path) if f.endswith('.mp4')]
# 遍历每个视频文件进行压缩
for video in video_files:
input_file = os.path.join(input_path, video)
output_file = os.path.join(output_path, video)
# 使用ffmpeg进行视频压缩
command = [
'ffmpeg', '-i', input_file, '-b:v', '3000k', '-c:a', 'copy', output_file
]
subprocess.run(command)
print(f'压缩完成: {output_file}')
比如我只想要原视频前半部分
import os
from moviepy.editor import VideoFileClip
def cut_video_half(input_video_path, output_video_path):
# 加载视频
video = VideoFileClip(input_video_path)
# 计算前50%时长
duration = video.duration
half_duration = duration *0.5
# 剪辑前50%的视频
new_video = video.subclip(0, half_duration)
# 写入新视频文件
new_video.write_videofile(output_video_path, codec="libx264")
def process_videos_in_directory(input_directory, output_directory):
# 如果输出目录不存在,创建它
if not os.path.exists(output_directory):
os.makedirs(output_directory)
# 遍历输入目录中的所有文件
for filename in os.listdir(input_directory):
if filename.endswith(".mp4"): # 只处理MP4文件
input_video_path = os.path.join(input_directory, filename)
output_video_path = os.path.join(output_directory, f"{filename}")
print(f"Processing {input_video_path}...")
cut_video_half(input_video_path, output_video_path)
print(f"Saved to {output_video_path}")
if __name__ == "__main__":
input_directory = r'C:\Users\Desktop\1' # 输入目录路径
output_directory = os.path.join(input_directory, '1') # 输出目录路径
process_videos_in_directory(input_directory, output_directory)
在根目录下,所有子目录中的过大的视频将被快速压缩,我这里阈值设置为10MB。
#条件压缩,文件过大将被压缩
import os
import subprocess
import winsound
def compress_video(input_video_path):
"""选择合适的方法压缩视频"""
output_video_path = f"{os.path.splitext(input_video_path)[0]}_compressed.mp4"
command = [
'ffmpeg',
'-i', input_video_path,
'-c:v', 'libx265',
'-preset', 'ultrafast', # 更快的压缩速度
'-crf', '30', # 调整 CRF 值,试试更高的值
'-c:a', 'aac',
# '-b:a', '64k', # 降低音频比特率
output_video_path
]
subprocess.run(command, check=True)
print(f"Compressed video saved to {output_video_path}")
os.remove(input_video_path)
print(f"Deleted original video: {input_video_path}")
def process_files_in_directory(input_directory):
"""处理目录中的视频文件"""
for dirpath, dirnames, filenames in os.walk(input_directory):
print(f"Processing folder: {dirpath}")
for filename in filenames:
if filename.lower().endswith('.mp4'): # 处理视频文件
input_file_path = os.path.join(dirpath, filename)
if filename.lower().endswith('_compressed.mp4'): # 处理视频文件
print('发现已压缩视频文件:', filename)
continue
# 检查文件大小是否大于10MB
elif os.path.getsize(input_file_path) > 10 * 1024 * 1024: # 10MB
print(f"Compressing video {input_file_path}...")
compress_video(input_file_path)
# 发出提示音
def Sound_beep():
duration = 1000 # millisecond
freq = 440 # Hz
winsound.Beep(freq, duration)
if __name__ == "__main__":
root_directory = r"E:\D\抖音下载(20241101)" # 根目录路径
process_files_in_directory(root_directory)
Sound_beep()