文 | 李晓飞

来源:Python 技术「ID: pythonall」

最近有了一个新任务,需要将赛事视频,拆分成两分钟以内的小段,用于发布到短视频平台上。

本以为是个一次性的工作,结果赛事视频数据巨大,视频文件长短不一,完全没法手工处理,于是 Python 又一次拯救了我。

还等什么,开始干吧!

最重要的事

无论做什么事情,都要去分析一下最重要的是什么,然后集中精力攻克,再继续找最重要的事。

对我们这个任务来说,不算是个大项目,不过呢,还是要找最重要的事开始,步步为营,最终将整个问题解决了。

整体来来看,我们需要从一个目录中读取视频文件,然后,对每个视频文件进行裁剪,最后将处理好的文件保存好。

在这个过程中,最重要的是什么呢?我觉得,是视频裁剪,如果不能方便的裁剪视频,其他的一切工作都是白费的,是吧。

裁剪视频

现在短视频很流行,有很多视频编辑软件,功能丰富,而我们需要的只是裁剪功能,而且需要用编程的方式调用,那么最合适的莫过于 ffmpeg[1] 了。

ffmpeg 是一个命令行工具,功能强大,可以编程调用。

从 ffmpeg 官网上下载对应操作系统的版本,我下的是 Windows 版[2]

下载后解压到一个目录,然后将目录下的 bin,配置到环境变量里。然后打开一个命令行,输入:

> ffmpeg -version
ffmpeg version 2021-10-07-git-b6aeee2d8b-full_build- ...

测试一下,能显示出版本信息,说明配置好了。

现在读一下文档,发现拆分视频文件的命令是:

ffmpeg -i [filename] -ss [starttime] -t [length] -c copy [newfilename]
  • i 为需要裁剪的文件

  • ss 为裁剪开始时间

  • t 为裁剪结束时间或者长度

  • c 为裁剪好的文件存放

好了,用 Python 写一个调用:

import subprocess as spdef cut_video(filename, outfile, start, length=90):cmd = "ffmpeg -i %s -ss %d -t %d -c copy %s" % (filename, start, length, outfile)p = sp.Popen(cmd, shell=True)p.wait()return
  • 定义了一个函数,通过参数传入 ffmpeg 需要的信息

  • 将裁剪命令写成一个字符串模板,将参数替换到其中

  • subprocessPopen 执行命令,其中参数 shell=True 表示将命令作为一个整体执行

  • p.wait() 很重要,因为裁剪需要一会儿,而且是另起进程执行的,所以需要等执行完成再做后续工作,否则可能找不到裁剪好的文件

这样视频裁剪工作就完成了,然后再看看什么是最重要的。

计算分段

视频裁剪时,需要一些参数,特别是开始时间,如何确定呢?如果这件事做不好,裁剪工作就很麻烦。

所以看看如何计算裁剪分段。

我需要将视频裁剪成一分半的小段,那么将需要知道目标视频文件的时间长度。

获取视频长度

如何获得长度呢?ffmpeg 提供了另一个命令 —— ffprobe

找了一下,可以合成一个命令来获取:

> ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 -i a.flv920.667

命令比较复杂哈,可以先不用管其他参数,只要将要分析的视频文件传入就好了。命令的结果是显示一行视频文件的长度。

于是可以编写一个函数:

import subprocess as spdef get_video_duration(filename):cmd = "ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 -i %s" % filenamep = sp.Popen(cmd, stdout=sp.PIPE, stderr=sp.PIPE)p.wait()strout, strerr = p.communicate() # 去掉最后的回车ret = strout.decode("utf-8").split("\n")[0]return ret
  • 函数只有一个参数,就是视频文件路径

  • 合成命令语句,将视频文件路径替换进去

  • subprocess 来执行,注意这里需要设置一下命令执行后的输出

  • wait 等待命令执行完成

  • 通过 communicate 提取输出结果

  • 从结果中提取视频文件的长度,返回

分段

得到了视频长度,确定好每个分段的长度,就可以计算出需要多少分段了。

代码很简单:

import math
duration = math.floor(float(get_video_duration(filename)))
part = math.ceil(duration / length)

注意,计算分段时,需要进行向上取整,即用 ceil,以包含最后的一点尾巴。

得到了需要的分段数,用一个循环就可以计算出每一段的起始时间了。

获取文件

因为处理的文件很多,所以需要自动获取需要处理的文件。

方法很简单,也很常用,一般可以用 os.walk 递归获取文件,还可以自己写,具体根据实际情况。

for fname in os.listdir(dir):fname = os.path.join(dir, os.path.join(dir, fname))basenames = os.path.basename(fname).split('.')mainname = basenames[0].split("_")[0]...

提供视频文件所在的目录,通过 os.listdir 获取目录中的文件,然后,合成文件的绝对路径,因为调用裁剪命令时需要绝对路径比较方便。

获取文件名,是为了在后续对裁剪好的文件进行命名。

代码集成

现在每个部分都写好了,可以将代码集成起来了:

def main(dir):outdir = os.path.join(dir, "output")if not os.path.exists(outdir):os.mkdir(outdir)for fname in os.listdir(dir):fname = os.path.join(dir, os.path.join(dir, fname))if os.path.isfile(fname):split_video(fname, outdir)
  • main 方法是集成后的方法

  • 先创建一个裁剪好的存储目录,放在视频文件目录中的 output 目录里

  • 通过 listdir 获取到文件后,对每个文件进行处理,其中判断了一下是否为文件

  • 调用 split_video 方法开始对一个视频文件进行裁剪

总结

总体而言,这是个很简单的应用,核心功能就是调用了一个 ffmpeg 命令。

相对于技术,更重要的是如何对一个项目进行分析和分解,以及从什么地方开始。

这里的方式起始时,不断地找最重要地事情,以最重要的事情为线索不断地推进,最终以自下而上地方式解决整个问题。

期望这篇文章对你有所启发,比心。

参考资料

[1]

ffmpeg: http://ffmpeg.org/

[2]

ffmpeg Window 版下载: https://www.gyan.dev/ffmpeg/builds/packages/ffmpeg-2021-10-14-git-c336c7a9d7-full_build.7z

PS:公号内回复「Python」即可进入Python 新手学习交流群,一起 100 天计划!

老规矩,兄弟们还记得么,右下角的 “在看” 点一下,如果感觉文章内容不错的话,记得分享朋友圈让更多的人知道!

代码获取方式】

识别文末二维码,回复:太阳雪

神器 ffmpeg —— 操作视频,极度舒适相关推荐

  1. 史林枫:C#.NET利用ffmpeg操作视频实战(格式转换,加水印 一步到位)

    ffmpeg.exe是大名鼎鼎的视频处理软件,以命令行参数形式运行.网上也有很多关于ffmpeg的资料介绍.但是在用C#做实际开发时,却遇到了几个问题及注意事项,比如如何无损处理视频?如何在转换格式的 ...

  2. 操作体验极度舒适的多功能软件卸载工具 - iObit Uninstaller PRO

    前言 每次的电脑重装,对我这么一个爱折腾的人,IObit Unlocker 和 IObit Uninstaller 都是必不可少需要安装的工具.前者比360卫士自带的解除软件占用功能更强力,后者在卸载 ...

  3. ffmpeg入门及java操作ffmpeg对视频进行处理

    一.ffmpeg 1.简介 FFmpeg是一个开源免费跨平台的视频和音频流方案,属于自由软件,采用LGPL或GPL许可证(依据你选择的组件).它提供了录制.转换以及流化音视频的完整解决方案.它包含了非 ...

  4. FFMPEG针对视频操作的基本命令

    1.FFMPEG裁剪视频 命令:ffmpeg -ss START -t DURATION -i INPUT -vcodec copy -acodec copy OUTPUT 其中各参数的说明如下: S ...

  5. Java 实现分段截取视频 生成gif图 使用ffmpeg操作

    Java 实现分段截取视频 生成gif图 使用ffmpeg操作 前言 核心代码 调用的抽象方法,包含逻辑处理 通过ffmpeg获取视频时长 合成gif图 删除文件夹 最终的调用 如果有更好的方式,请务 ...

  6. java操作ffmpeg为视频添加背景音乐

    最近学习仿抖音微信小程序遇到一个坑,视频中使用以下语句为视频添加背景音乐 ffmpeg.exe -i input.mp4 -i 音乐.mp3 -t 7 -y 新视频.mp4 ,然而我怎么尝试都不行,上 ...

  7. 小学生python入门-极度舒适的全套 Python 入门教程,小学生看了也能学会

    编程几乎已经成为现代人的一门必修课,特别是 Python ,不仅长期霸占编程趋势榜.薪资榜第一,还屡屡进入小学教材,甚至成为浙江省信息技术高考项目-- 今天,小编带来了一门极度舒适的 Python 入 ...

  8. 极度舒适的 Python 入门教程,佩奇也能学会~

    编程几乎已经成为现代人的一门必修课,特别是 Python ,不仅长期霸占编程趋势榜.薪资榜第一,还屡屡进入小学教材,甚至成为浙江省信息技术高考项目-- 今天,小编带来了一门极度舒适的 Python 入 ...

  9. ffmpeg将视频flv格式转为mp4格式

    前言 最近使用bilibili哔哩哔哩下载助手下载B站的视频时,发现下载的视频的格式都是.flv,因此想利用网络上的在线转换工具将flv转为mp4格式,无奈转换后的mp4视频,下载速度感人,于是使用f ...

最新文章

  1. APT-高级软件包管理
  2. PyTorch 实现孪生网络识别面部相似度
  3. java加载c库阻塞_【死磕Java並發】-----J.U.C之阻塞隊列:DelayQueue
  4. Webservice开发之xsd中开发请求数据的响应接口
  5. 北斗导航 | GPS卫星导航技术重要人物简介
  6. 理解分布式一致性:Paxos协议之Generalized Paxos Byzantine Paxos
  7. php 输出01,php基础01_thinkphp输出Hello World-Go语言中文社区
  8. Linq 合并数据并相加
  9. 软件设计中架构和框架的区别
  10. 无限宽神经网络 - 神经网络正切核理论【NTK】
  11. 好程序员web前端培训分享JavaScript学习指南
  12. html中标记pre的作用是什么,html中pre和code标签
  13. Pandas数据处理与分析
  14. 计算机组装日记,求微机组装与维护实习日记?
  15. srsLTE源码分析(一)---enb协议栈入口
  16. 38条搞笑WOW下线理由。。。 达人火速添加啊
  17. gcc posix sjij for MSYS 9.2.1+
  18. Andersen Global与Baptiste Co. Law Firm合作加强加勒比海平台
  19. python爬虫之下载京东页面图片
  20. 关于NXP 汽车ABS ASIC芯片BA13系列轮速部分驱动

热门文章

  1. hugeng007_demo03_
  2. 蝶舞无线串口服务器,蝶舞世界自在绽放
  3. PyTorch手写字体识别MNIST
  4. 封面的下划线上添加字时候,下划线粗细不均的问题
  5. python+tkinter+nuitka 打包单个可执行exe文件(PyInstaller比nuitka更稳定)
  6. html5编写圆柱,three.js实现圆柱体
  7. 查看Office365 License在不同机器上授权状态
  8. 毕业设计-管理系统-俱乐部管理系统
  9. pgadmin导出表及其数据
  10. 【站长工具】域名批量查询历史权重流量软件