【Python自动化】一些好用的视频编辑工具。更新于2024.11.7

本文包含一些利用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()

你可能感兴趣的:(自动化,运维,python,音视频,爬虫)