神器 ffmpeg —— 操作视频,极度舒适

简介: 最近有了一个新任务,需要将赛事视频,拆分成两分钟以内的小段,用于发布到短视频平台上。本以为是个一次性的工作,结果赛事视频数据巨大,视频文件长短不一,完全没法手工处理,于是 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 sp
def 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.flv
920.667

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

于是可以编写一个函数:

import subprocess as sp
def get_video_duration(filename):
    cmd = "ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 -i %s" % filename
    p = 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 命令。

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

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

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

目录
相关文章
|
3月前
|
XML Java Android开发
FFmpeg开发笔记(五十二)移动端的国产视频播放器GSYVideoPlayer
GSYVideoPlayer是一款国产移动端视频播放器,支持弹幕、滤镜、广告等功能,采用IJKPlayer、Media3(EXOPlayer)、MediaPlayer及AliPlayer多种内核。截至2024年8月,其GitHub星标数达2万。集成时需使用新版Android Studio,并按特定步骤配置依赖与权限。提供了NormalGSYVideoPlayer、GSYADVideoPlayer及ListGSYVideoPlayer三种控件,支持HLS、RTMP等多种直播链接。
116 18
FFmpeg开发笔记(五十二)移动端的国产视频播放器GSYVideoPlayer
|
3月前
|
Linux 开发工具 Android开发
FFmpeg开发笔记(五十三)移动端的国产直播录制工具EasyPusher
EasyPusher是一款国产RTSP直播录制推流客户端工具,支持Windows、Linux、Android及iOS等系统。尽管其GitHub仓库(安卓版:https://github.com/EasyDarwin/EasyPusher-Android)已多年未更新,但通过一系列改造,如升级SDK版本、迁移到AndroidX、指定本地NDK版本及更新Gradle版本等,仍可在最新Android Studio上运行。以下是针对Android Studio Dolphin版本的具体改造步骤。
65 3
FFmpeg开发笔记(五十三)移动端的国产直播录制工具EasyPusher
|
4月前
|
Web App开发 5G Linux
FFmpeg开发笔记(四十四)毕业设计可做的几个拉满颜值的音视频APP
一年一度的毕业季来临,计算机专业的毕业设计尤为重要,不仅关乎学业评价还积累实战经验。选择紧跟5G技术趋势的音视频APP作为课题极具吸引力。这里推荐三类应用:一是融合WebRTC技术实现视频通话的即时通信APP;二是具备在线直播功能的短视频分享平台,涉及RTMP/SRT等直播技术;三是具有自定义动画特效及卡拉OK歌词字幕功能的视频剪辑工具。这些项目不仅技术含量高,也符合市场需求,是毕业设计的理想选择。
95 6
FFmpeg开发笔记(四十四)毕业设计可做的几个拉满颜值的音视频APP
|
5月前
|
Linux
FFmpeg开发笔记(三十四)Linux环境给FFmpeg集成libsrt和librist
《FFmpeg开发实战》书中介绍了直播的RTSP和RTMP协议,以及新协议SRT和RIST。SRT是安全可靠传输协议,RIST是可靠的互联网流传输协议,两者于2017年发布。腾讯视频云采用SRT改善推流卡顿。以下是Linux环境下为FFmpeg集成libsrt和librist的步骤:下载安装源码,配置、编译和安装。要启用这些库,需重新配置FFmpeg,添加相关选项,然后编译和安装。成功后,通过`ffmpeg -version`检查版本信息以确认启用SRT和RIST支持。详细过程可参考书中相应章节。
117 1
FFmpeg开发笔记(三十四)Linux环境给FFmpeg集成libsrt和librist
|
6月前
|
编解码 Linux
FFmpeg开发笔记(二十八)Linux环境给FFmpeg集成libxvid
XviD是开源的MPEG-4视频编解码器,曾与DivX一起用于早期MP4视频编码,但现在已被H.264取代。要集成XviD到Linux上的FFmpeg,首先下载源码,解压后配置并编译安装libxvid。接着,在FFmpeg源码目录中,重新配置FFmpeg以启用libxvid,然后编译并安装。成功后,通过`ffmpeg -version`检查是否启用libxvid。详细步骤包括下载、解压libxvid,使用`configure`和`make`命令安装,以及更新FFmpeg配置并安装。
98 2
FFmpeg开发笔记(二十八)Linux环境给FFmpeg集成libxvid
|
6月前
|
Web App开发 JSON 开发者
程序技术好文:用Python撸点视频背景音乐素材
程序技术好文:用Python撸点视频背景音乐素材
|
Java 程序员 Android开发
关于那些编程,剪辑,开黑,我用了就离不开手的软件
关于那些编程,剪辑,开黑,我用了就离不开手的软件
60 0
|
算法 内存技术
ffmpeg开课工具准备
ffmpeg开课工具准备
51 0
|
Python
Python3,9分钟撸完一个电脑录屏神器,女神说今晚要给我加鸡腿。
Python3,9分钟撸完一个电脑录屏神器,女神说今晚要给我加鸡腿。
42226 1
|
搜索推荐
码农必备的8大工具神器:在线图片压缩超好用!
Hello,新人初到,给大家分享整理了作为新手码农,我最近很爱用的8个工作必备神器网站,解决你可能遇到的各种问题
码农必备的8大工具神器:在线图片压缩超好用!