Python 处理视频

基本逻辑:

1,分割视频

2,选择视频

3,拼接视频


实操 多个文件:

1,找到素材

2,用分割软件分割

3,运行python代码2.2挑选成多个文件夹:# 从文件夹中随机挑选X个文件,拷贝到Y个新文件夹中。

4,用python代码3.2合并视频:# X文件夹中有多个子文件夹,每个子文件夹中有多个视频,将子文件夹中的短视频,分别合成1个长视频。(从SplitedH子文件夹中挑选)


实操 单个/多个文件:

1,找到素材

2,用分割软件分割

3,运行python代码2.1:# 从SplitedH文件夹中,挑选60个文件,生成1个新文件夹

4,运行python代码3.1:# 从SplitedH文件夹中随机选择X个视频,然后合并成1个视频,生成Y个长视频。新视频保存在NewH文件夹中。(从SplitedH中挑选)

4,视频编辑工具合并视频



1,依次分割文件中的所有视频为短视频,开启多线程,消除原音。


      
# 将Origianl文件夹中的所有视频,分给为7到11秒的短视频,保存在Splited文件夹中。


import os
import random
import moviepy.editor as mp
import threading

# 设置输入和输出目录
input_dir = 'C:/0video/Splited8s/Origianl/' 
output_dir = 'C:/0video/Splited8s/Splited/'

# 定义分割视频的时长范围
min_duration = 7
max_duration = 11

# 获取输入目录中所有视频文件的列表
video_files = [os.path.join(input_dir, f) for f in os.listdir(input_dir) if f.endswith('.mp4')]

# 设置要创建的分割视频的数量
num_split_videos = 10

# 定义分割视频的函数
def split_videos():
    # 在每个线程中执行 num_split_videos/4 次循环,以便同时处理多个视频
    for i in range(num_split_videos//4):
        # 随机选择一个视频文件
        video_file = random.choice(video_files)

        # 生成分割视频的随机时长
        duration = random.randint(min_duration, max_duration)

        # 设置分割视频的输出文件名
        output_file = os.path.join(output_dir, f'Sp{i}.mp4')

        # 加载视频文件
        video = mp.VideoFileClip(video_file)

        # 去除声音
        video = video.without_audio()

        # 获取视频的总时长
        total_duration = video.duration

        # 设置分割视频的切割点
        cut_points = [0] + sorted(random.sample(range(int(total_duration)), duration-1)) + [total_duration]

        # 将视频分割成多个剪辑
        clips = [video.subclip(cut_points[i], cut_points[i+1]) for i in range(len(cut_points)-1)]

        # 将剪辑合并成单个视频
        output_video = mp.concatenate_videoclips(clips)

        # 将输出视频写入文件
        output_video.write_videofile(output_file)

# 创建四个线程
threads = []
for i in range(4):
    threads.append(threading.Thread(target=split_videos))

# 启动所有线程
for thread in threads:
    thread.start()

# 等待所有线程完成
for thread in threads:
    thread.join()


2,随机从素材库文件夹中挑选X个文件。拷贝过的文件不再拷贝,可以设置生成多少个新文件夹,每个文件夹中多少个文件。

生成1个文件夹

2.1

# 从SplitedH文件夹中,挑选60个文件,生成1个新文件夹

from shutil import copyfile
import random
import os
def random_select_and_copy_files(dir_name=None, select_number=0):
    '''
    随机从dir_name目录中选择select_number个文件并复制到new_dir_name目录下
    :param dir_name: 待选择文件的目录名
    :param select_number: 随机选择的文件数量
    :return: None
    '''
    # 处理输入目录名异常
    try:
        dir_name is None or dir_name not in os.listdir(os.getcwd())
    except:
        print("输入目录名错误")
    dir_path = os.path.join(os.getcwd(), dir_name)  # 获取文件目录路径
    files_list = os.listdir(dir_path)  # 生成文件名列表
    files_number = len(files_list)
    # 处理输入数量异常
    try:
        select_number > files_number
    except:
        print("选择文件超过原本数量")
    generate_list = random.sample(files_list, select_number)  # 随机选取文件
    # 生成存放文件新目录,默认以new开头
    new_dir_path = os.path.join(os.getcwd(), 'Xuanzhe_'+dir_name)
    os.mkdir(new_dir_path)
    success_number = 0  # 记录成功数量
    success_list = []  # 记录成功文件
    # 复制文件并记录
    for file_name in generate_list:
        orl_file_path = os.path.join(dir_path, file_name)
        new_file_path = os.path.join(new_dir_path, file_name)
        copyfile(orl_file_path, new_file_path)  # 复制文件
        success_list.append(file_name)
        success_number += 1
        if success_number % 100 == 0:
            print("success", success_number)
    # 给出提示信息并给出未成功文件
    if success_number == select_number:
        print("all", select_number, "finish")
    else:
        print("unfinished")
        error_list = []
        for file_name in files_list:
            if file_name not in success_list:
                error_list.append(file_name)
        print(error_list, 'error', sep='\n')
if __name__ == "__main__":
    random_select_and_copy_files("SplitedH", 60)

生成多个文件夹

# 2.2 此代码是从SplitedS文件夹及其子文件夹中,选取多个文件组成多个文件夹。修改为,存储的新文件夹路径可以指定,比如保存在 C:
# 2.2 此代码是从SplitedS文件夹及其子文件夹中,选取多个文件组成多个文件夹。修改为,存储的新文件夹路径可以指定,比如保存在 C:\0video\music\
from shutil import copyfile
import random
import os
def random_select_and_copy_files(dir_name=None, select_number=0, x=1, new_dir_path=None):
'''
随机从dir_name目录及其子目录中选择select_number个文件并复制到new_dir_path目录下
:param dir_name: 待选择文件的目录名
:param select_number: 随机选择的文件数量
:param x: 新建文件夹的数量
:param new_dir_path: 存放新文件夹的目录路径
:return: None
'''
# 处理输入目录名异常
try:
dir_name is None or dir_name not in os.listdir(os.getcwd())
except:
print("输入目录名错误")
dir_path = os.path.join(os.getcwd(), dir_name)  # 获取文件目录路径
files_list = []  # 存储所有文件名
for root, dirs, files in os.walk(dir_path):
for file in files:
files_list.append(os.path.join(root, file))
files_number = len(files_list)
# 处理输入数量异常
try:
select_number > files_number
except:
print("选择文件超过原本数量")
# 生成存放文件新目录,默认以new开头
success_set = set()  # 存储已经选择的文件名
for i in range(x):
new_dir_path_i = os.path.join(new_dir_path, 'Xuanzhe_{}_{}'.format(dir_name, i+1))
os.makedirs(new_dir_path_i, exist_ok=True)
success_number = 0  # 记录成功数量
success_list = []  # 记录成功文件
# 复制文件并记录
while success_number < select_number:
file_path = random.choice(files_list)  # 随机选择一个文件路径
file_name = os.path.basename(file_path)  # 获取文件名
if file_name in success_set:  # 如果已经选择过则跳过
continue
new_file_path = os.path.join(new_dir_path_i, file_name)
copyfile(file_path, new_file_path)  # 复制文件
success_list.append(file_name)
success_set.add(file_name)  # 添加到已选择集合中
success_number += 1
if success_number % 100 == 0:
print("success", success_number, "in", new_dir_path_i)
# 给出提示信息并给出未成功文件
if success_number == select_number:
print("all", select_number, "finish in", new_dir_path_i)
else:
print("unfinished in", new_dir_path_i)
error_list = []
for file_path in files_list:
file_name = os.path.basename(file_path)
if file_name not in success_set:
error_list.append(file_name)
print(error_list, 'error', sep='\n')
if __name__ == "__main__":
new_dir_path = r"C:\0video\music"
random_select_and_copy_files("SplitedS", 20, x=1000, new_dir_path=new_dir_path)
video\music\ from shutil import copyfile import random import os def random_select_and_copy_files(dir_name=None, select_number=0, x=1, new_dir_path=None): ''' 随机从dir_name目录及其子目录中选择select_number个文件并复制到new_dir_path目录下 :param dir_name: 待选择文件的目录名 :param select_number: 随机选择的文件数量 :param x: 新建文件夹的数量 :param new_dir_path: 存放新文件夹的目录路径 :return: None ''' # 处理输入目录名异常 try: dir_name is None or dir_name not in os.listdir(os.getcwd()) except: print("输入目录名错误") dir_path = os.path.join(os.getcwd(), dir_name) # 获取文件目录路径 files_list = [] # 存储所有文件名 for root, dirs, files in os.walk(dir_path): for file in files: files_list.append(os.path.join(root, file)) files_number = len(files_list) # 处理输入数量异常 try: select_number > files_number except: print("选择文件超过原本数量") # 生成存放文件新目录,默认以new开头 success_set = set() # 存储已经选择的文件名 for i in range(x): new_dir_path_i = os.path.join(new_dir_path, 'Xuanzhe_{}_{}'.format(dir_name, i+1)) os.makedirs(new_dir_path_i, exist_ok=True) success_number = 0 # 记录成功数量 success_list = [] # 记录成功文件 # 复制文件并记录 while success_number < select_number: file_path = random.choice(files_list) # 随机选择一个文件路径 file_name = os.path.basename(file_path) # 获取文件名 if file_name in success_set: # 如果已经选择过则跳过 continue new_file_path = os.path.join(new_dir_path_i, file_name) copyfile(file_path, new_file_path) # 复制文件 success_list.append(file_name) success_set.add(file_name) # 添加到已选择集合中 success_number += 1 if success_number % 100 == 0: print("success", success_number, "in", new_dir_path_i) # 给出提示信息并给出未成功文件 if success_number == select_number: print("all", select_number, "finish in", new_dir_path_i) else: print("unfinished in", new_dir_path_i) error_list = [] for file_path in files_list: file_name = os.path.basename(file_path) if file_name not in success_set: error_list.append(file_name) print(error_list, 'error', sep='\n') if __name__ == "__main__": new_dir_path = r"C:
# 2.2 此代码是从SplitedS文件夹及其子文件夹中,选取多个文件组成多个文件夹。修改为,存储的新文件夹路径可以指定,比如保存在 C:\0video\music\
from shutil import copyfile
import random
import os
def random_select_and_copy_files(dir_name=None, select_number=0, x=1, new_dir_path=None):
'''
随机从dir_name目录及其子目录中选择select_number个文件并复制到new_dir_path目录下
:param dir_name: 待选择文件的目录名
:param select_number: 随机选择的文件数量
:param x: 新建文件夹的数量
:param new_dir_path: 存放新文件夹的目录路径
:return: None
'''
# 处理输入目录名异常
try:
dir_name is None or dir_name not in os.listdir(os.getcwd())
except:
print("输入目录名错误")
dir_path = os.path.join(os.getcwd(), dir_name)  # 获取文件目录路径
files_list = []  # 存储所有文件名
for root, dirs, files in os.walk(dir_path):
for file in files:
files_list.append(os.path.join(root, file))
files_number = len(files_list)
# 处理输入数量异常
try:
select_number > files_number
except:
print("选择文件超过原本数量")
# 生成存放文件新目录,默认以new开头
success_set = set()  # 存储已经选择的文件名
for i in range(x):
new_dir_path_i = os.path.join(new_dir_path, 'Xuanzhe_{}_{}'.format(dir_name, i+1))
os.makedirs(new_dir_path_i, exist_ok=True)
success_number = 0  # 记录成功数量
success_list = []  # 记录成功文件
# 复制文件并记录
while success_number < select_number:
file_path = random.choice(files_list)  # 随机选择一个文件路径
file_name = os.path.basename(file_path)  # 获取文件名
if file_name in success_set:  # 如果已经选择过则跳过
continue
new_file_path = os.path.join(new_dir_path_i, file_name)
copyfile(file_path, new_file_path)  # 复制文件
success_list.append(file_name)
success_set.add(file_name)  # 添加到已选择集合中
success_number += 1
if success_number % 100 == 0:
print("success", success_number, "in", new_dir_path_i)
# 给出提示信息并给出未成功文件
if success_number == select_number:
print("all", select_number, "finish in", new_dir_path_i)
else:
print("unfinished in", new_dir_path_i)
error_list = []
for file_path in files_list:
file_name = os.path.basename(file_path)
if file_name not in success_set:
error_list.append(file_name)
print(error_list, 'error', sep='\n')
if __name__ == "__main__":
new_dir_path = r"C:\0video\music"
random_select_and_copy_files("SplitedS", 20, x=1000, new_dir_path=new_dir_path)
video\music" random_select_and_copy_files("SplitedS", 20, x=1000, new_dir_path=new_dir_path)

3,用python些一段视频拼接的代码,随机从文件夹中选择X个视频,将选择好的视频拼接成Y个新的视频,保存在另外一个文件夹中,新视频的文件名以NewVideo开头。开启多线程,消除原音,添加转场,合并使用过的视频不再使用。(开启CPU加速)

3.1

# 从SplitedH文件夹中随机选择X个视频,然后合并成1个视频,生成Y个长视频。新视频保存在NewH文件夹中。

import os
import random
from moviepy.editor import VideoFileClip, concatenate_videoclips
import moviepy.video.fx.all as vfx
import threading


input_folder = 'C:/0video/Splited8s/SplitedH/'  # 视频所在的文件夹
output_folder = 'C:/0video/Splited8s/NewH/'  # 新视频保存的文件夹

num_of_videos = 30  # 选择的视频数量
num_of_new_videos = 2  # 生成的新视频数量

# 随机选择视频文件
all_files = os.listdir(input_folder)
video_files = [f for f in all_files if f.endswith('.mp4')]
selected_files = []
selected_files_set = set()  # 存储已经选择的文件名
while len(selected_files) < num_of_videos:
    file = random.choice(video_files)
    if file not in selected_files_set:
        selected_files.append(file)
        selected_files_set.add(file)

# 加载选中的视频文件并拼接
clips = [VideoFileClip(input_folder + f) for f in selected_files]
for i in range(len(clips)-1):
    clips[i+1] = vfx.fadein(clips[i+1], 1)  # 添加淡入效果
    clips[i] = vfx.fadeout(clips[i], 1)  # 添加淡出效果
    clips[i] = clips[i].without_audio()  # 去掉音轨
    clips[i+1] = clips[i+1].without_audio()  # 去掉音轨
    clips[i] = clips[i].resize(height=1920)  # 调整分辨率
    clips[i+1] = clips[i+1].resize(height=1920)  # 调整分辨率
final_clip = concatenate_videoclips(clips)

# 使用多线程加速保存过程
class MergeThread(threading.Thread):
    def __init__(self, index):
        threading.Thread.__init__(self)
        self.index = index

    def run(self):
        new_filename = output_folder + 'NewVideo' + str(self.index+1) + '.mp4'
        final_clip.write_videofile(new_filename, fps=60)

threads = []
for i in range(num_of_new_videos):
    t = MergeThread(i)
    threads.append(t)

for t in threads:
    t.start()

for t in threads:
    t.join()


3.2

import os
from moviepy.editor import VideoFileClip, concatenate_videoclips
import moviepy.video.fx.all as vfx
import threading

input_folder = 'X/'  # 视频所在的文件夹
output_folder = 'X/'  # 新视频保存的文件夹

# 获取所有子文件夹路径
subfolders = [os.path.join(input_folder, f) for f in os.listdir(input_folder) if os.path.isdir(os.path.join(input_folder, f))]

# 处理每个子文件夹
for subfolder in subfolders:
    # 获取子文件夹中的所有视频文件
    video_files = [os.path.join(subfolder, f) for f in os.listdir(subfolder) if f.endswith('.mp4')]
    
    # 加载视频文件并添加转场效果
    clips = [VideoFileClip(f) for f in video_files]
    for i in range(len(clips)-1):
        clips[i+1] = vfx.fadein(clips[i+1], 1)  # 添加淡入效果
        clips[i] = vfx.fadeout(clips[i], 1)  # 添加淡出效果
        clips[i] = clips[i].without_audio()  # 去掉音轨
        clips[i+1] = clips[i+1].without_audio()  # 去掉音轨

    # 拼接所有视频并保存
    final_clip = concatenate_videoclips(clips)
    output_filename = os.path.join(output_folder, 'New'+os.path.basename(subfolder)+'.mp4')

    # 定义保存函数,使用多线程来加速保存过程
    def save_clip(clip, filename):
        clip.write_videofile(filename, fps=60)

    # 创建线程并启动
    t = threading.Thread(target=save_clip, args=(final_clip, output_filename))
    t.start()

print("所有视频已保存完成!")




3.2 更新


import os
from moviepy.editor import VideoFileClip, concatenate_videoclips
import moviepy.video.fx.all as vfx
import threading


# 使用GPU加速视频处理
import imageio_ffmpeg
imageio_ffmpeg.get_ffmpeg_version()


input_folder = 'X/'  # 视频所在的文件夹
output_folder = 'X/'  # 新视频保存的文件夹

# 获取所有子文件夹路径
subfolders = [os.path.join(input_folder, f) for f in os.listdir(input_folder) if os.path.isdir(os.path.join(input_folder, f))]

# 处理每个子文件夹
for subfolder in subfolders:
    # 获取子文件夹中的所有视频文件
    video_files = [os.path.join(subfolder, f) for f in os.listdir(subfolder) if f.endswith('.mp4')]
    
    # 加载视频文件并添加转场效果
    clips = [VideoFileClip(f) for f in video_files]
    for i in range(len(clips)-1):
        clips[i+1] = vfx.fadein(clips[i+1], 1)  # 添加淡入效果
        clips[i] = vfx.fadeout(clips[i], 1)  # 添加淡出效果
        clips[i] = clips[i].without_audio()  # 去掉音轨
        clips[i+1] = clips[i+1].without_audio()  # 去掉音轨
        clips[i] = clips[i].resize(height=1920)  # 调整分辨率
        clips[i+1] = clips[i+1].resize(height=1920)  # 调整分辨率

    # 拼接所有视频并保存
    final_clip = concatenate_videoclips(clips)
    output_filename = os.path.join(output_folder, 'New'+os.path.basename(subfolder)+'.mp4')
    final_clip.write_videofile(output_filename, fps=60, codec='libx264', preset='ultrafast')


    # 定义保存函数,使用多线程来加速保存过程
    def save_clip(clip, filename):
        clip.write_videofile(filename, fps=60)

    # 创建线程并启动
    t = threading.Thread(target=save_clip, args=(final_clip, output_filename))
    t.start()

print("所有视频已保存完成!")


4,删除小于1M的文件。



# 删除X文件夹中,文件大小小于1M的文件

import os

folder_path = 'C:/0video/Splited8s/X/'

for root, dirs, files in os.walk(folder_path):
    for file_name in files:
        file_path = os.path.join(root, file_name)
        if os.path.getsize(file_path) < 1000000: # 1M = 1000000 bytes
            os.remove(file_path)

Leave a Reply