一、引言

在写《第15.39节、splitDockWidget和tabifyDockWidget嵌套布局QDockWidget的PyQt人机对话案例:笨笨机器人》的,为了说明setDockNestingEnabled的作用,使用了2个动画,当时是使用录屏软件录屏录的MP4文件,但将其转gif时遇到了困难,网上各种下载的工具都是在gif文件中加了各种LOGO图形,在线的转码操作很困难,转得慢,好不容易转完之后发现下载不下来,实在不想用了。作为一个Pythonic的人,马上想到的是“人生苦短,我用Python”,网上一查,结果发现好多大神有跟老猿一样的情况,并且还真有工具,一个是基于MoviePy 的,一个是基于OpenCV的,都还比较好使用,但MoviePy更好用,于是马上动手安装了一个。

二、MoviePy简介

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

MoviePy有很多与视频相关的功能,包括剪辑、合成、分离音视频等,在此老猿只用了其中的视频转gif的功能,老猿暂时没准备去深入研究,在此也不多介绍,大家可以参考《MoviePy - 中文文档(一个专业的python视频编辑库)教程》的介绍以及英文版官方文档https://zulko.github.io/moviepy/中文版文档:http://moviepy.cn/。在此就说明如下几点:

  1. 安装:pip安装时,请将站点指向国内的镜像站点,否则下载很慢或者下载不下来,老猿使用清华的镜像,指令是:

    pip install -i https://pypi.tuna.tsinghua.edu.cn/simple moviepy

    注意moviepy全小写,安装时会自动安装相关依赖包,这点与上面文章介绍的有出入。

  2. 模块导入:moviepy是一个包,由于只使用视频转gif,相关功能在editor模块内,因此导入使用指令:

    import moviepy.editor as mpe

  3. 视频文件装载方法:

    VideoFileClip(videoFile)

    这个方法就是构造一个VideoFileClip对象,这个对象就是视频的内容,可以通过该对象对视频进行剪辑等操作

  4. 截取视频方法:

    subclip(start,end)

    参数start和end是视频起止位置,如果是整数单位是秒,也可以是其他时间设置方法,如:2分12.5秒,表示方法可以是(2,12.5)、(0,2,12.5)或者 (00:02:12.5)。

    返回值还是一个VideoFileClip对象。

  5. 输出视频到gif文件的方法:

    write_gif(gifFileName,fps=fps)

    write_gif有很多参数,除了第一个参数是文件名外,其他参数都是关键字参数(不明白关键字参数的请参考《第5章函数进阶 第5.1节 Python函数的位置参数、关键字参数精讲》),在此老猿仅使用了fps参数,其他参数就不展开说了。fps参数是指生成GIF是每秒抽取的帧数,这个数字越大,同样视频生成的gif文件就越大,所以需要有所取舍。

    6、关闭视频缓存方法:close方法用于关闭视频缓存。

示例代码:
		import moviepy.editor as mpe
cache = mpe.VideoFileClip(r"c:\temp\操作录屏.mp4").subclip(0,15)
cache.write_gif(r"c:\temp\操作录屏.gif",fps=2)

三、构建MP4视频转gif工具

3.1、设计操作界面

工具的操作界面提供了选择视频文件、输出gif文件、设置输出视频段的起止时间以及转换GIF的fps,另外老猿发现moviepy的输出都是打印输出,因此将所有相关输出信息(包括自编代码输出和moviepy模块的输出)重定向到了信息输出历史窗proccessInf中,同时将最近输出的信息显示在“最近输出信息”后面的名为currentInf的label上。输入信息设置完成后,点击转换按钮即将对应视频输出到gif文件中。整体ui设计界面如下:

3.2、实现转换按钮点击的槽方法

为了确保转换不被异常操作干扰,开始转换后整个主窗口设置为disable,转换完成后恢复enable。

    def convert(self):
self.setEnabled(False)
self.proccessInf.clear()
self.convertByMoviepy(self.videoFile.text(),self.gifFile.text())
self.setEnabled(True)

3.3、实现方法convertByMoviepy

方法convertByMoviepy就是取界面相关设置调用moviepy对应方法完成文件转换,为了确保转换顺利,对相关参数进行了校验,如起止位置和fps必须是整数,如果终止位置不为0则必须大于起始位置。最后就是执行视频文件加载和转换,代码可以参考上面moviepy简介部分。

3.4、重定向输出信息到信息输出历史窗proccessInf

信息输出历史窗proccessInf为一个QTextBrowser对象,要将所有print输出信息到该历史窗,需要完成如下工作:

  1. 在构造方法中备份标准输出sys.stdout
  2. 构建承接输出信息的对象赋值给sys.stdout

    承接输出对象必须是一个类似文件io的对象,Python判断对象是否支持文件IO,是个典型的鸭子类型处理方式,就是看对象是否实现了读写方法,由于标准输出无需读只需写,因此只要实现了write方法即可。

    在本工具的实现方法内,老猿将标准输出指向了主窗口,因此在主窗口中实现了write方法,在write方法中将输出信息追加显示到proccessInf中、将最新信息显示到“最近输出信息”后的currentInf标签上。

    但在此需要注意,输出到proccessInf中的信息在程序输出过程中不会即时显示,导致给人的感觉是没有输出一样,为了确保输出信息即时显示在proccessInf窗口中,需要主动调用应用的processEvents方法。

    同时为了确保信息可对比跟踪,将重定向的信息使用备份的标准输出进行了输出
重定向参考代码如下:
class mainWin(QtWidgets.QWidget,ui_mainWin.Ui_mainWin):
def __init__(self):
super().__init__()
self.setupUi(self)
self.stdoutbak = sys.stdout
self.stderrbak = sys.stderr
sys.stdout = self def write(self,info):
self.proccessInf.insertPlainText(info)
if len(str):self.currentInf.setText(str)
QtWidgets.qApp.processEvents(QtCore.QEventLoop.ExcludeUserInputEvents|QtCore.QEventLoop.ExcludeSocketNotifiers)
self.stdoutbak.write(info)

3.5、运行界面截图及动图



广告

老猿关于PyQt的付费专栏《使用PyQt开发图形界面Python应用》只需要9.9元,该部分与第十五章的内容基本对应,但同样内容在付费专栏上总体来说更详细、案例更多。本节内容对应付费专栏的《第三十三章、PyQt+moviepy实现的MP4视频转gif工具》。如果有兴趣也愿意支持老猿的读者,欢迎购买付费专栏。

老猿Python,跟老猿学Python!

第15.40节、PyQt(Python+Qt)实战:moviepy实现MP4视频转gif动图的工具的更多相关文章

  1. 第15.25节 PyQt(Python+Qt)入门学习:Model/View开发实战--使用QTableView展示Excel文件内容

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.概述 在前面的订阅专栏<第十九章.Model/View开发:QTableView的功能及属 ...

  2. 第15.38节 PyQt(Python+Qt)入门学习:containers容器类部件QDockWidget停靠窗功能详解

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 一.概述 QDockWidget类提供了一个可以停靠在QMainWin ...

  3. 第15.37节 PyQt(Python+Qt)入门学习:containers容器类部件QMdiArea多文档界面部件详解及编程开发案例

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 一.引言 老猿在前期学习PyQt相关知识时,对每个组件的属性及方法都研 ...

  4. 第15.28节 PyQt(Python+Qt)入门学习:Model/View架构中的便利类QTableWidget详解

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.引言 表格部件为应用程序提供标准的表格显示工具,在表格内可以管理基于行和列的数据项,表格中的最大 ...

  5. 第15.18节 PyQt(Python+Qt)入门学习:Model/View架构中视图Item Views父类详解

    老猿Python博文目录 老猿Python博客地址 一.概述 在PyQt图形界面中,支持采用Model/View架构实现数据和界面逻辑分离,其中Model用于处理数据存储,View用于界面数据展现,当 ...

  6. 第15.13节 PyQt(Python+Qt)入门学习:Qt Designer的Spacers部件详解

    一. 引言 在Designer的部件栏中,有两种类型的Spacers部件,下图中上面布局中为一个水平间隔部件(按钮1和按钮2之间的部件),下面布局中为一个垂直间隔部件(按钮3和4之间),如图: 这两种 ...

  7. 第15.33节 PyQt(Python+Qt)入门学习:containers容器类部件QTabWidget选项窗部件简介

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.概述 容器部件就是可以在部件内放置其他部件的部件,在Qt Designer中可以使用的容器部件有 ...

  8. 第15.31节 PyQt(Python+Qt)入门学习:containers容器类部件GroupBox分组框简介

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.概述 容器部件就是可以在部件内放置其他部件的部件,在Qt Designer中可以使用的容器部件有 ...

  9. 第15.29节 PyQt(Python+Qt)入门学习:containers容器类部件QScrollArea滚动区域详解

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.概述 Scroll Area提供了一个呈现在其他部件上的可滚动区域视图,滚动区域用于显示框架内的 ...

随机推荐

  1. 对Spark硬件配置的建议

    对于Spark开发人员来说,一个比较普遍的问题就是如何合理的配置Spark的硬件?当然如何合理的对Spark集群进行硬件配置要视情况而定,在这里给出以下建议: 存储系统 在大数据领域,有一句" ...

  2. 使用git处理github中提交有冲突的pull request

    前言: 为什么要写这篇文章,因为前段时间有一个开源的github中的项目有一个朋友提交了一个pr看了下是帮忙优化了下代码(十分感谢这位网友).但是他提交的pr刚好和我的项目有许多的冲突导致无法自动合并 ...

  3. 阿里云函数计算 VSCode 使用,及部署 Docusaurus

    代码: https://github.com/ikuokuo/start-serverless 使用简介 产品页开通服务.使用流程,如下: 新手示例,如下: 创建函数 阿里云提供了如下几种方式创建函数 ...

  4. 对于STM32F103的USART的通讯调试

    USART:(Universal Synchronous/Asynchronous Receiver/Transmitter)通用同步/异步串行接收/发送器USART是一个全双工通用同步/异步串行收发 ...

  5. .Net核心依赖项注入:生命周期和最佳实践

    在讨论.Net的依赖注入(DI)之前,我们需要知道我们为什么需要使用依赖注入 依赖反转原理(DIP): DIP允许您将两个类解耦,否则它们会紧密耦合,这有助于提高可重用性和更好的可维护性 DIP介绍: ...

  6. socket里面那个又爱又恨的锁

    查一个问题:结果看了一下软中断以及系统 所耗cpu,心中满是伤痕啊------- perf 结果一眼可以看到:主要是锁 那么这个lock 是用来干什么的呢?? A:TCP socket的使用者有两种: ...

  7. tcp ESTABLISHED 接收数据

    tcp_rcv_established函数的工作原理是把数据包的处理分为2类:fast path和slow path,其含义显而易见.这样分类的目的当然是加快数据包的处理,因为在正常情况下,数据包是按 ...

  8. 一键SSH连接 = SSH密钥登陆 + WindowsTerminal

    本文记录如何利用SSH密钥登录和WindowsTerminal/FluentTerminal实现一键SSH连接 目录 一.在本地生成SSH密钥对 二.在远程主机安装公钥 三.在远程主机打开密钥登陆功能 ...

  9. 'sortbitwise'是什么意思

    问题 flag sortbitwise 在ceph中是什么意思,在Jewel版本下可以看到多了这个flags [root@lab8106 current]# ceph -s cluster ffe7a ...

  10. shell脚本的自动交互

    使用expect来自动应答shell的交互 #!/usr/bin/expect spawn openssl req -new -key server.key -out server1.csr expe ...