首页 > 编程语言 >Python系列(4)- 使用 MoviePy 编辑视频

Python系列(4)- 使用 MoviePy 编辑视频

时间:2022-10-26 23:44:30浏览次数:43  
标签:视频 MoviePy sub clip Python moviepy mp4 video editor


MoviePy 是一个用于视频编辑的 Python 模块,可用于进行视频的基本操作(如剪切、连接、标题插入)、视频合成(也称非线性编辑)、视频处理或创建高级效果。

MoviePy 能处理的视频是 ffmpeg 格式的,支持的文件类型:*.mp4 *.wmv *.rm *.avi *.flv *.webm *.wav *rmvb 。

MoviePy: https://pypi.org/project/moviepy/
Github: https://github.com/Zulko/moviepy


1. 安装 MoviePy

    操作系统:Windows 10 Home (64 位)
    Python:3.8.1
    Pip:21.3.1
    Python 安装目录:C:\Applications\Python-3.8.1

    MoviePy 依赖 ffmpeg,安装时会同时安装 imageio-ffmpeg,命令如下:

        C:\> pip install moviepy

        Looking in indexes: https://mirrors.aliyun.com/pypi/simple/
        Collecting moviepy
        Downloading https://mirrors.aliyun.com/pypi/packages/18/54/01a8c4e35c75ca9724d19a7e4de9dc23f0ceb8769102c7de056113af61c3/moviepy-1.0.3.tar.gz (388 kB)
            |████████████████████████████████| 388 kB 6.8 MB/s
        Preparing metadata (setup.py) ... done
        Collecting decorator<5.0,>=4.0.2
        Downloading https://mirrors.aliyun.com/pypi/packages/ed/1b/72a1821152d07cf1d8b6fce298aeb06a7eb90f4d6d41acec9861e7cc6df0/decorator-4.4.2-py2.py3-none-any.whl (9.2 kB)
        Collecting tqdm<5.0,>=4.11.2
        Downloading https://mirrors.aliyun.com/pypi/packages/47/bb/849011636c4da2e44f1253cd927cfb20ada4374d8b3a4e425416e84900cc/tqdm-4.64.1-py2.py3-none-any.whl (78 kB)
            |████████████████████████████████| 78 kB ...
        Requirement already satisfied: requests<3.0,>=2.8.1 in c:\applications\python-3.8.1\lib\site-packages (from moviepy) (2.28.1)
        Collecting proglog<=1.0.0
        Downloading https://mirrors.aliyun.com/pypi/packages/8b/f5/cab5cf6a540c31f5099043de0ae43990fd9cf66f75ecb5e9f254a4e4d4ee/proglog-0.1.10-py3-none-any.whl (6.1 kB)
        Requirement already satisfied: numpy>=1.17.3 in c:\applications\python-3.8.1\lib\site-packages (from moviepy) (1.23.3)
        Collecting imageio<3.0,>=2.5
        Downloading https://mirrors.aliyun.com/pypi/packages/ec/5b/521fcf5836cc46672b04e1ec7a94c0869ca6cc6a6e147277f1eb8cbb6886/imageio-2.22.1-py3-none-any.whl (3.4 MB)
            |████████████████████████████████| 3.4 MB ...
        Collecting imageio_ffmpeg>=0.2.0
        Downloading https://mirrors.aliyun.com/pypi/packages/b7/d2/d838be81d375cc461083a30fca976ce325d052bf5ece1bfe9a4fe92d0a57/imageio_ffmpeg-0.4.7-py3-none-win_amd64.whl (22.6 MB)
            |████████████████████████████████| 22.6 MB 6.8 MB/s
        Collecting pillow>=8.3.2
        Downloading https://mirrors.aliyun.com/pypi/packages/8f/59/97618ad67fc0639ed588c60cfe9d91417f7bae8c87bbe7c7784b0ffdb9f1/Pillow-9.2.0-cp38-cp38-win_amd64.whl (3.3 MB)
            |████████████████████████████████| 3.3 MB ...
        Requirement already satisfied: idna<4,>=2.5 in c:\applications\python-3.8.1\lib\site-packages (from requests<3.0,>=2.8.1->moviepy) (3.3)
        Requirement already satisfied: urllib3<1.27,>=1.21.1 in c:\applications\python-3.8.1\lib\site-packages (from requests<3.0,>=2.8.1->moviepy) (1.26.12)
        Requirement already satisfied: charset-normalizer<3,>=2 in c:\applications\python-3.8.1\lib\site-packages (from requests<3.0,>=2.8.1->moviepy) (2.1.1)
        Requirement already satisfied: certifi>=2017.4.17 in c:\applications\python-3.8.1\lib\site-packages (from requests<3.0,>=2.8.1->moviepy) (2022.9.24)
        Collecting colorama
        Downloading https://mirrors.aliyun.com/pypi/packages/77/8b/7550e87b2d308a1b711725dfaddc19c695f8c5fa413c640b2be01662f4e6/colorama-0.4.5-py2.py3-none-any.whl (16 kB)
        Using legacy 'setup.py install' for moviepy, since package 'wheel' is not installed.
        Installing collected packages: colorama, tqdm, pillow, proglog, imageio-ffmpeg, imageio, decorator, moviepy
            Running setup.py install for moviepy ... done
        Successfully installed colorama-0.4.5 decorator-4.4.2 imageio-2.22.1 imageio-ffmpeg-0.4.7 moviepy-1.0.3 pillow-9.2.0 proglog-0.1.10 tqdm-4.64.1


    注:本文使用 pip 阿里源,如果安装速度慢,可以参考 “Python系列(2)- Python 包 (package) 和 Pip 管理工具 ” 的 “2. Pip 管理工具” 调整 pip 源。

        默认安装的 Moviepy 版本是 1.0.3 。


2. 视频属性

    获取视频的大小、宽高、fps、时长等属性,代码如下:

        #!/usr/bin/python

        from moviepy import editor

        video_clip = editor.VideoFileClip(r"C:\temp\a.mp4")
        
        # 大小
        print("video_clip.size: ", video_clip.size)
        
        # 图像宽和高
        print("video_clip.w: ", video_clip.w)
        print("video_clip.h: ", video_clip.h)
        
        # fps
        print("video_clip.fps: ", video_clip.fps)
        
        # 时长,单位:秒
        print("video_clip.duration: ", video_clip.duration)


    修改视频属性,代码如下:

        #!/usr/bin/python

        from moviepy import editor
        
        sub_clip = editor.VideoFileClip(r"C:\temp\a.mp4").subclip(0, 10)
        
        sub_clip = sub_clip.fx(editor.vfx.resize, width=480) # 调整尺寸,保持比例

        # sub_clip = sub_clip.fx(editor.vfx.speedx, 2)     # 调整倍数
        # sub_clip = sub_clip.fx(editor.vfx.colorx, 0.5)    # 画面调暗

        sub_clip.write_videofile(r"C:\temp\out_1.mp4")


3. 视频音频合成

    把一个视频和另一个视频的音频合成,代码如下:

        #!/usr/bin/python

        from moviepy import editor
        
        sub_clip_a = editor.VideoFileClip(r"C:\temp\a.mp4").subclip(0, 10)
        sub_clip_b = editor.VideoFileClip(r"C:\temp\b.mp4").subclip(0, 10)
 
        # 获取 sub_clip_b 的音频
        audio_b = sub_clip_b.audio
 
        # 将 sub_clip_b 的音频和 sub_clip_a 合成
        sub_clip_a = sub_clip_a.set_audio(audio_b)
        sub_clip_a.write_videofile(r"C:\temp\out_2.mp4")


    把一个视频和一个 MP3 合成,代码如下:

        #!/usr/bin/python

        from moviepy import editor

        sub_clip = editor.VideoFileClip(r"C:\temp\a.mp4").subclip(0, 10)
        audio = editor.AudioFileClip(r"C:\temp\123.mp3").subclip(0, 10)

        sub_clip = sub_clip.set_audio(audio)
        sub_clip.write_videofile(r"C:\temp\out_3.mp4")


4. 视频分割/合成

    视频分割,代码如下:

        #!/usr/bin/python

        from moviepy import editor

        video_clip = editor.VideoFileClip(r"C:\temp\a.mp4")

        sub_clip = video_clip.subclip(10, 20);
        sub_clip.write_videofile(r"C:\temp\out_split_001.mp4")

        sub_clip = video_clip.subclip(30, 40);
        sub_clip.write_videofile(r"C:\temp\out_split_002.mp4")

        sub_clip = video_clip.subclip(50, 60);
        sub_clip.write_videofile(r"C:\temp\out_split_003.mp4")


    多个视频按照先后顺序拼接起来,代码如下:

        #!/usr/bin/python

        from moviepy import editor

        video_clip1 = editor.VideoFileClip(r"C:\temp\out_split_003.mp4")
        video_clip2 = editor.VideoFileClip(r"C:\temp\out_split_001.mp4")
 
        clip = editor.concatenate_videoclips([video_clip1, video_clip2])
        clip.write_videofile(r"C:\temp\out_concatenate_1.mp4")


    多个视频在同一个画面上显示,代码如下:

        #!/usr/bin/python

        from moviepy import editor

        video_clip1 = editor.VideoFileClip(r"C:\temp\a.mp4").subclip(0, 10).margin(10)
        video_clip2 = editor.VideoFileClip(r"C:\temp\b.mp4").subclip(0, 10).margin(10)
        
        clip = editor.clips_array([[video_clip1, video_clip2]])
        clip.write_videofile(r"C:\temp\out_concatenate_2.mp4")


5. 视频内容编辑

    把文本添加到视频上,代码如下:

        #!/usr/bin/python

        from moviepy import editor
 
        video_clip = editor.VideoFileClip(r"C:\temp\a.mp4").subclip(0, 20)

        # 调整音量,变为原来的 0.5
        #video_clip = video_clip.volumex(0.5)
 
        # 做一个文本剪贴板,自定义样式、颜色。
        text_clip = editor.TextClip("Hello, Python Moviepy!", fontsize=52, color="red")

        # 让文本在屏幕的正中间显示,持续 10 秒,设置透明度为 0.8
        # 屏幕左上角为(0, 0),右下角为(屏幕宽度, 屏幕高度)
        """
        set_position((800, 500)): 显示在800, 500的位置上
        set_position(("center", "center")): 显示在屏幕的正中央
        set_position((0.4, 0.6), True): 显示在距离左边百分之40、距离上边百分之60的位置上
        
        set_duration(10): 持续10秒
        set_opacity(0.6): 设置透明度为0.6
        """
        text_clip = text_clip.set_position(("center", "center")).set_duration(10).set_opacity(0.8)
 
        # 然后把文本剪贴板贴在视频上
        video_clip = editor.CompositeVideoClip([video_clip, text_clip])
 
        # 然后导出视频,可以是其它的视频格式
        video_clip.write_videofile(r"C:\temp\out_edit_1.mp4")
 

   
    注:在 Windows 上执行以上脚本,执行到 editor.TextClip() 时,会报出如下错误:
 
            OSError: MoviePy Error: creation of None failed because of the following error:
            
            [WinError 2] 系统找不到指定的文件。.
            
            .This error can be due to the fact that ImageMagick is not installed on your computer,
            or (for Windows users) that you didn't specify the path to the ImageMagick binary in file conf.py,
            or that the path you specified is incorrect
 
        以上错误是因为缺少 ImageMagick 造成的,访问 http://www.imagemagick.org/script/download.php 下载 Windows 版的 ImageMagick,本文下载 ImageMagick-7.1.0-51-Q16-HDRI-x64-dll.exe。
        
        下载后,双击 *.exe 文件,安装到 C:\Applications\ImageMagick-7.1.0-Q16-HDRI 目录。

        Moviepy 的配置文件 C:\Applications\Python-3.8.1\Lib\site-packages\moviepy\config_defaults.py, 在文件的尾部有如下内容:

            import os
            
            FFMPEG_BINARY = os.getenv('FFMPEG_BINARY', 'ffmpeg-imageio')
            IMAGEMAGICK_BINARY = os.getenv('IMAGEMAGICK_BINARY', 'auto-detect')

        环境变量 IMAGEMAGICK_BINARY 对应的是 ImageMagick 的可执行文件,这里有两种修改方法。

            方法1:直接修改 config_defaults.py 文件,修改代码如下:

                import os
                
                FFMPEG_BINARY = os.getenv('FFMPEG_BINARY', 'ffmpeg-imageio')
                IMAGEMAGICK_BINARY = r'C:\Applications\ImageMagick-7.1.0-Q16-HDRI\magick.exe'  

            方法2:添加 Windows 系统变量 IMAGEMAGICK_BINARY,步骤如下:

                右击 “我的电脑” → “属性” → “高级系统设置” → “高级” → “环境变量”

                新建系统变量(点击 “系统变量” 下方的 “新建” 按钮)

                    变量名:IMAGEMAGICK_BINARY
                    变量值:C:\Applications\ImageMagick-7.1.0-Q16-HDRI\magick.exe

                点击 “确定”

        建议使用方法2,即添加系统变量 IMAGEMAGICK_BINARY,打开一个新的命令行控制台,再次执行以上 Python 脚本,完成视频编辑。


6. 视频分割工具

    命令行方式运行可传入参数的视频分割工具 split-video.py,代码如下:

        #!/usr/bin/python

        import os, sys
        import os.path as osp

        from moviepy import editor

        # 默认值
        save_dir = '/out'
        default_seconds = 10
        max_count = 999

        # 分割函数
        def splitFile(filename, dura, sdir):
            if filename.isspace() == True or dura < default_seconds or sdir.isspace == True:
                print("Error: invalid parameters")
                return

            if osp.exists(filename) != True:
                print(f"Error: \'{filename}\' not exists")
                return

            if osp.exists(sdir) != True:
                os.mkdir(sdir)

            print(f"Opening \'{filename}\' ...")
            video_clip = editor.VideoFileClip(filename)
            duration_end = video_clip.duration
            if duration_end <= dura:
                print(f"Error: video duration {video_clip.duration} seconds <= {dura} seconds, unable to split")
                return

            filecount = int(duration_end // dura)
            if (duration_end % dura) > 1.0:
                filecount += 1

            if filecount > max_count:
                print(f"Error: file count {filecount} > {max_count}, unable to split")        
                return

            print(f"Split to {filecount} files ...")
            #
            basename = osp.basename(filename)
            fileObj = osp.splitext(basename)

            i = 1
            start = 0
            end = dura
            while i <= filecount:

                if start > duration_end:
                    break

                if end > duration_end:
                    end = duration_end

                sub_clip = video_clip.subclip(start, end)
                sub_clip.write_videofile("{0}/{1}_{2:03d}{3}".format(sdir, fileObj[0], i, fileObj[1]))

                start += dura
                end += dura
                i += 1


        # 命令行入口
        if __name__=="__main__":
            msg = """Usage: python %s [file] [seconds] [sdir]
            file - Source file, full path
            seconds - Duration, default 10 seconds
            sdir - Output dir
            """
            count = len(sys.argv)
            if count < 2:
                print(msg % sys.argv[0])
            elif count == 2:
                dura = default_seconds
                sdir = osp.abspath('.') + save_dir
                splitFile(sys.argv[1], dura, sdir)
            elif count == 3:
                dura = int(sys.argv[2])
                if dura < default_seconds:
                    dura = default_seconds
                sdir = osp.abspath('.') + save_dir
                splitFile(sys.argv[1], dura, sdir)
            else:
                dura = int(sys.argv[2])
                if dura < default_seconds:
                    dura = default_seconds
                sdir = sys.argv[3]
                if sdir.isspace() == True:
                    sdir = osp.abspath('.') + save_dir
                splitFile(sys.argv[1], dura, sdir)


    注:Windows 10 Home(64 位) + Python 3.8.1 + Moviepy 1.0.3 环境下,测试通过。
    
        假设 split-video.py 在 D:\Workshop\python 目录下,视频文件为 D:\temp\a.mp4,视频时长为 246 秒,我们要把 a.mp4 分割为每个 30 秒长度的小视频。命令行格式如下:

            D:\Workshop\python> python split-video.py D:\temp\a.mp4 30

            Opening 'D:\temp\a.mp4' ...
            Split to 9 files ...
            Moviepy - Building video D:\Workshop\python/out/a_001.mp4.
            MoviePy - Writing audio in a_001TEMP_MPY_wvf_snd.mp3
            MoviePy - Done.
            Moviepy - Writing video D:\Workshop\python/out/a_001.mp4

            Moviepy - Done !
            Moviepy - video ready D:\Workshop\python\moviepy/out/a_001.mp4
            Moviepy - Building video D:\Workshop\python\moviepy/out/a_002.mp4.
            MoviePy - Writing audio in a_002TEMP_MPY_wvf_snd.mp3
            MoviePy - Done.
            Moviepy - Writing video D:\Workshop\python\moviepy/out/a_002.mp4

...

 

标签:视频,MoviePy,sub,clip,Python,moviepy,mp4,video,editor
From: https://www.cnblogs.com/tkuang/p/16830598.html

相关文章

  • b站 bilibili 哔哩哔哩 js小脚本 油猴 查找搜索某年的视频 自动翻页
    varccount=0;varnumnum=5constsleep=(delay)=>newPromise((resolve)=>setTimeout(resolve,delay))while(numnum--){  document.querySelect......
  • python爬虫获取tap帖子
    1.tap帖子数据获取代码中cookie为登陆后页面抓包的cookie,其中详情页需要3种拼接url,第一种是链接中含有topic,第二种中含有moment,第三种是视频,其中含有videoimportr......
  • Python: Template Method Pattern
    GeovinDuTemplate.py#模板方法模式TemplateMethodPatterndefget_text():return"text文件""""methodtogetthexmlversionoffile"""......
  • 我的爱情与Python不得不说的故事
    最近,沉迷于辩论比赛,有最近有场辩论赛因为一句话出圈了:为什么是坠入爱河而不是跳入爱河呢?因为爱本身是自由意志的沉沦。这让我想起来我当时坠入爱河的时候,作为人家印象里呆板......
  • 学习python-Day80
    今日学习内容一、表单控制二、购物车案例三、v-model进阶(了解)四、vue生命周期五、与后端交互ajaz六、计算属性七、侦听属性......
  • Python进阶篇04-面向对象编程
    面向对象编程面向对象编程和面向过程编程的区别:类和实例类:抽象的、用于创建实例的基础模板,类里面可以定义这个类所拥有的基础的属性。实例:根据类而创建的具体的对象,实......
  • python基础之模块
    第三方模块的下载与使用第三方模块:别人写的模块一般情况下功能特别强大想使用第三方模块必须先下载后面才可以反复使用方式1:命令行借助于pip工具pip......
  • OpenCV-Python learning-9.图像阈值处理
    你也可以​​iframe外链​​查看。本节内容包括:常用阈值方法自适应阈值Otsu(大津法)自适应阈值​​github地址​​......
  • OpenCV-Python learning-8.颜色空间
    你也可以​​iframe外链​​查看。本节内容包括:改变色彩空间:cvtColor使用HSV对象跟踪练习......
  • python sklearn中的KNN
    代码fromsklearnimportdatasetsfromsklearn.model_selectionimporttrain_test_splitfromsklearn.neighborsimportKNeighborsClassifierimportnumpyasnpiris=dat......