• Python常用视频编辑操作——读取与保存视频、更改帧数、拼接视频、视频语音合并、视频与图像互转等


    1.更改视频帧数

    降低视频帧数,简单的操作只能降低视频帧数,如果要增加视频帧数,那就要使用深度学习进行插帧处理:

    import cv2
    from moviepy.editor import *
    def change_fps(inpt_path,output_path,fps):
        # 加载视频
        video = VideoFileClip(inpt_path)
    
        # 将帧率降低为15帧/秒
        new_video = video.set_fps(fps)
    
        # 保存为新的文件
        new_video.write_videofile(output_path, codec="libx264")
    
    def change_fps_dir(video_dir,fps):
        file_list = os.listdir(video_dir)
    
        for file in file_list:
            # 使用os.path.basename()获取文件名(包括后缀)
            file_name = os.path.basename(file)
            out_name = "F" + file_name
    
            input = os.path.join(video_dir,file_name)
            output = os.path.join(video_dir,out_name)
    
            change_fps(input,output,fps)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    2.把视频拆分成帧保存

    def split_video(video_path,save_path):
        # 创建输出目录
        os.makedirs(save_path, exist_ok=True)
    
        # 打开视频文件
        cap = cv2.VideoCapture(video_path)
    
        frame_count = 0
    
        # 读取视频帧并保存为图像
        while True:
            ret, frame = cap.read()
    
            if not ret:
                break
    
            # 生成输出图像文件名
            frame_filename = os.path.join(save_path, f'{frame_count:05d}.jpg')
    
            frame_count += 1
    
            # 保存帧图像
            cv2.imwrite(frame_filename, frame)
    
        # 释放视频文件
        cap.release()
    
        print(f"总共保存了 {frame_count} 帧图像")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    3.把拆分图像合成视频

    def img_video_merge(img_dir,video_path,frame_rate):
        file_list = os.listdir(img_dir)
        cv_src = cv2.imread(os.path.join(img_dir,file_list[0]))
    
        fourcc = cv2.VideoWriter_fourcc(*'mp4v')  # 使用H.264编解码器
    
        height, width, channels = cv_src.shape
    
        # 帧速率和帧大小
        frame_size = (width, height)
        # 创建VideoWriter对象
        out = cv2.VideoWriter(video_path, fourcc, frame_rate, frame_size)
    
        for file in file_list:
            cv_dst = cv2.imread(os.path.join(img_dir, file))
            out.write(cv_dst)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    4.提取视频的音轨

    def video_to_audio(video_path,audio_path):
        video = VideoFileClip(video_path)
        audio = video.audio
        audio_temp = "temp.wav"
    
        if os.path.exists(audio_path):
            os.remove(audio_temp)
    
        audio.write_audiofile(audio_temp)
        audio.close()
    
        if os.path.exists(audio_path):
            os.remove(audio_path)
        cmd = "ffmpeg -i " + audio_temp + " -ac 1 -ar 16000 " + audio_path
        subprocess.run(cmd,shell=True)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    5.视频与音轨合并

    from moviepy.editor import VideoFileClip, AudioFileClip
    
    # 读取视频和音轨
    video_clip = VideoFileClip('video.mp4')  # 替换为您的视频文件
    audio_clip = AudioFileClip('audio.mp3')  # 替换为您的音轨文件
    
    # 将音轨添加到视频
    video_clip = video_clip.set_audio(audio_clip)
    
    # 保存合并后的视频
    output_video_path = 'output_video.mp4'
    video_clip.write_videofile(output_video_path, codec='libx264')
    
    # 关闭视频和音轨文件
    video_clip.close()
    audio_clip.close()
    
    print(f"已将音轨成功合并到视频并保存为 {output_video_path}")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    6.视频合并

    def image_stitching(images,stack):
        height, width, channels = images[0].shape
        # 遍历所有图像,如果尺寸不同,将它们调整为相同的尺寸
        for i in range(1, len(images)):
            if images[i].shape != (height, width, channels):
                images[i] = cv2.resize(images[i], (width, height))
        if stack == 0:
            result = np.hstack(images)
        else:
            result = np.vstack(images)
    
        return result
    
    #stack为0是水平合并,等于1是垂直合并
    def video_stitching(video_path_1,video_path_2,output_path,stack):
        cap1 = cv2.VideoCapture(video_path_1)
        cap2 = cv2.VideoCapture(video_path_2)
    
        if stack == 0:
            frame_width = int(cap1.get(3)) * 2
            frame_height = int(cap1.get(4))
        elif stack == 1:
            frame_width = int(cap1.get(3))
            frame_height = int(cap1.get(4)) * 2
    
        fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
    
        out = cv2.VideoWriter(output_path, fourcc, 25, (frame_width, frame_height))
    
        while (True):
            ret1, frame1 = cap1.read()
            ret2, frame2 = cap2.read()
            if ret1 and ret2 == True:
                images = [frame1, frame2]
                dst = image_stitching(images,stack)
                out.write(dst)
            else:
                break
        cap1.release()
        cap2.release()
        out.release()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    水平合并的效果:
    在这里插入图片描述

  • 相关阅读:
    大数据分析工具构建智能监测与异常预警
    Vue的render函数&修改默认配置
    【AI视野·今日Sound 声学论文速览 第十六期】Mon, 2 Oct 2023
    Android|集成 slf4j + logback 作为日志框架
    基于物联网开发的水电站远程管控系统方案
    王者荣耀-镜教学视频
    炽热如初 向新而生|ISC2022 HackingClub白帽峰会圆满举办!
    短视频无尽流前端开发指南
    零基础小白,照样也可以成为年薪15W+的网络安全工程师!
    Openssl数据安全传输平台015:OCCI的使用方法+在项目中的设计与实现
  • 原文地址:https://blog.csdn.net/matt45m/article/details/133894011