FFmpeg 是一个用于处理音视频的开源程序,但它的入门较为复杂,难度较大,且没有较为清晰明了的简易教程,因此有必要,系统性地讲解 FFmpeg 的一些实用操作。
关于下载:
官方下载链接:
https://ffmpeg.zeranoe.com/builds/win64/static/ffmpeg-20200715-a54b367-win64-static.zip
这也是针对 Windows 系统的最新版本,当然 static 版无需执行安装操作,较为简单。 对上述压缩文件解压缩后,获得文件下的子级内容: --- bin --- doc --- presets --- LICENSE.txt --- README.txt 事实上,该文件夹,需要放置在一个固定的位置,建议采用全英文路径!ffmpeg -version
即可获得:
ffmpeg -i x1 [] x2
-i 后面,输入文件名,即为需要处理的音视频文件
x1: 对应待处理的文件名,需要添加后缀名
[]: 认为是控制处理的一系列参数
x2: 最后输出的文件名
ffmpeg -i 04.mp4 _hide_banner
当前文件夹下,存在 04.mp4 文件,参数:_hide_banner 用于隐藏banner 信息,仅展示 mp4 文件的相关信息。
注意事项:由于 Powershell 下不支持中文输入,因此所有文件名必须为英文模式。
通过上述命令,即可获取该视频的基本信息,如时长,画面的宽高,速率等
> ffmpeg -i 04.mp4 -sameq -f avi 2.avi
....
Option 'sameq' was removed. If you are looking for an option to preserve the quality (which is not what -sameq was for), use -qscale 0 or an equivalent quality factor option.
Failed to set value '1' for option 'sameq': Invalid argument
Error parsing global options: Invalid argument
上述命令用于将 04.mp4 转为 2.avi , 但需要注意:-sameq 参数,目前已经被移除,所以控制转格式时的质量,需要采用 -qscale 0 参数。
-qscale 0 : 跟原视频质量相同,其值越大,转码后视频质量愈差。
ffmpeg -i 04.mp4 -qscale 0 -f avi 2.avi
通过上述方式,将 mp4 转为同等质量的 avi 格式
-qscale 参数值一般在 0 ~6 之间比较合适,越大,转码后视频质量越差。
视频裁剪
ffmpeg -i 04.mp4 -t 60 03.mp4
-t 参数 60 表示取视频长度为:60s
由于未指定起始和终止点,默认截取前 60s, 因此:
ffmpeg -i 04.mp4 -t 60 -c copy 03-1.mp4
ffmpeg -i 04.mp4 -ss 4:30 -t 45 -c copy 01.mp4
-ss 指定起始点,如上所示,为 4 分 30 秒处开始,往后截取 45 秒。
以及:
ffmpeg -i 04.mp4 -ss 4:30 -to 6:45 -c copy 01.mp4
-to 实际上,指定终点点,从 4 分 30 秒到 6 分 45 秒
而:
-c:v copy 只拷贝视频编码部分!
ffmpeg -i 04.mp4 -ss 4:30 -to 6:45 -c:v copy -an 01.mp4
上述代码中的:-an , 用于去除音频部分。此时,获得 「无声的视频」:
ffmpeg -i 04.mp4 -ss 4:30 -to 6:45 -vn 01.mp3
-vn 去除视频,获得音频文件。但此时不能添加:-c:a copy
事实上,标准的时间格式为:00:00:00 表示 「时:分:秒」,但一般情况下,不需要用到的,都可以省略,直接以 4:30 即可表示 「分:秒」
事实上,FFmpeg 并不支持批量操作!如何构建批量化操作,则只能另想办法?
首先,我们先考虑有没有前人做好的 「轮子」, 这样就不必闭门造车,重新制造轮子。
Name: Pazera Free Audio Extractor (32/64-bit)
Version: 2.9
License: Freeware
Date: 2018.07.29
Author: Jacek Pazera
Web page: http://www.pazera-software.com/products/audio-extractor/
Quick start: http://www.pazera-software.com/products/audio-extractor/quickstart.php
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
This program uses the following open source software:
1. FFmpeg, licensed under the GNU Lesser General Public License (LGPL) version 2.1 available at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
2. MediaInfo library, licensed under the MediaInfo(Lib) License available at https://mediaarea.net/en/MediaInfo/License
3. Free SpTBX components available at http://www.silverpointdevelopment.com/sptbxlib/index.htm, licensed under the SpTBXLib License available at http://www.silverpointdevelopment.com/sptbxlib/SpTBXLib-LICENSE.htm
4. The Drop Files and Version Information components by Peter D. Johnson (http://delphidabbler.com/), licensed under the Mozilla Public License v2.0 available at https://www.mozilla.org/en-US/MPL/2.0/
AudioExtractor64.exe 的 README.txt 文件信息如上所示,专门用于音频的提取!其中使用了 FFmpeg 工具,本质上是调用 FFmpeg 来完成视频的相关操作,但作者已经把这个轮子做成了完善的软件。同时也实现了 Freeware 的目标。
界面:
> ffmpeg -i 04.mp4 -ss 4:30 -to 6:45 -vn 01.mp3
> ffmpeg -i 05.mp4 -ss 4:30 -to 6:45 -vn 02.mp3
> ffmpeg -i 06.mp4 -ss 4:30 -to 6:45 -vn 03.mp3
事实上,可能就是如上所示,一条一条的命令,依次执行罢了,但最终依然需要通过命令行来执行。
有规律性的命令,本质上依然是一堆字符串,因此利用 R 语言的字符串操作来生成字符串向量,最终传递给命令行窗口,执行命令即可。
f 'ffmpeg -i ',
sprintf('%02.0f',1:4),
'.mp4',
' -ss 4:30 -to 6:45 -vn ',
sprintf('%02.0f',1:4),'.mp3')
返回信息:
> f
[1] "ffmpeg -i 01.mp4 -ss 4:30 -to 6:45 -vn 01.mp3"
[2] "ffmpeg -i 02.mp4 -ss 4:30 -to 6:45 -vn 02.mp3"
[3] "ffmpeg -i 03.mp4 -ss 4:30 -to 6:45 -vn 03.mp3"
[4] "ffmpeg -i 04.mp4 -ss 4:30 -to 6:45 -vn 04.mp3"
实践环节:
> list.files()
[1] "01.mp4" "02.mp4" "03.mp4" "04.mp4"
list.files() 返回当前路径下的文件。
然后,开始构造循环:
for (i in seq_along(f)) {
system(f[i])
}
执行代码后,查看文件:
> list.files()
[1] "01.mp3" "01.mp4" "02.mp3" "02.mp4" "03.mp3"
[6] "03.mp4" "04.mp3" "04.mp4"
事实上,已经生成了目标文件。至此,批量工作结束。
> list.files()
[1] "01.mp3" "01.mp4" "02.mp3" "02.mp4" "03.mp3"
[6] "03.mp4" "04.mp3" "04.mp4"
> list.files(pattern = '.mp3') %>% unlink
> list.files()
[1] "01.mp4" "02.mp4" "03.mp4" "04.mp4"
通过 pattern 进行筛选,交由 unlink() 删除 mp3 文件
unlink() 在这里的作用等同于 file.remove()
比对效率:
a function() {
for (i in seq_along(f)) {
system(f[i],show.output.on.console = F)
}
list.files(pattern = '.mp3') %>% unlink
}
b function() {
sapply(f, system,show.output.on.console = F)
list.files(pattern = '.mp3') %>% unlink
}
a 采用 for 循环,b 采用 sapply() 方法
同时,添加了参数:show.output.on.console = F, 不再输出终端信息。
那么他们的效率如何呢?
> system.time(a())
user system elapsed
0.00 0.01 12.24
> system.time(b())
user system elapsed
0.01 0.00 12.17
事实上,后者仅比前者快了 0.07s
但,sapply() 的形式,更加优雅,推荐使用后者。
小细节:
a() 运行后,实际上已经删除了生成的 mp3 文件,之后才重新运行 b()
这里,在 R 语言运行模式下,是不能够默认覆盖文件的,因此需要删除之前的 mp3 文件。
y 参数:
ffmpeg -i 01.mp4 -ss 4:30 -to 6:45 -y -vn 01.mp3
-y 用于直接覆盖同名文件。即意味着:若之前就存在 01.mp3 同名文件,则直接覆盖。
av 包
Package: av
Type: Package
Title: Working with Audio
and Video in R
Version: 0.5.0
Authors@R: person("Jeroen",
"Ooms", role =
c("aut", "cre"),
email =
"jeroen@berkeley.edu",
comment = c(ORCID =
"0000-0002-4035-0289"))
Description: Bindings to 'FFmpeg'
...
SystemRequirements:
FFmpeg (>= 3.2);
with at least
libx264 and lame
(mp3) drivers.
Debian/Ubuntu:
libavfilter-dev,
Fedora/CentOS:
ffmpeg-devel (via
https://rpmfusion.org),
MacOS Homebrew:
ffmpeg.
Depends: R (>= 3.5)
av 包的出现,解决了 R 语言无法更好地处理音视频的弊端,同时 av 包其实是需要 FFmpeg 作为支持,其实是调用 FFmpeg 进行处理。
因此,更建议使用 av
> ls('package:av')
[1] "av_audio_convert" "av_capture_graphics" "av_decoders"
[4] "av_demo" "av_demuxers" "av_encode_video"
[7] "av_encoders" "av_filters" "av_log_level"
[10] "av_media_info" "av_muxers" "av_spectrogram_video"
[13] "av_video_convert" "av_video_images" "av_video_info"
[16] "bartlett" "bhann" "bharris"
[19] "blackman" "bnuttall" "bohman"
[22] "cauchy" "dolph" "flattop"
[25] "gauss" "hamming" "hanning"
[28] "lanczos" "nuttall" "parzen"
[31] "read_audio_bin" "read_audio_fft" "sine"
[34] "tukey" "welch"
av 中的函数,其实仅仅只有 35个,量并不是很大,但涉及到音视频相关的一系列知识,想要熟练使用的话,仍需付出大量的实践。
---end---