多媒体工具ffmpeg常见用法总结
ffmpeg是一个非常好用的多媒体工具,不少音视频编辑软件其实都是内置ffmpeg然后调用它的。一些简单的日常需求,对我来说,它无需付费,足够好用,并且轻量。
下载安装
http://ffmpeg.org/download.html
页面可以下载ffmpeg的源码与可执行文件,这里我们选择Get packages & executable files。选择对应的平台,以windows为例,需要点击windows徽标,下载对应的windows builds。解压完成后,将bin目录添加到环境变量,安装就完成了。
常用命令
媒体格式转换
视频格式转换,准确地说是视频包装格式转换,比如你打算把一个flv的视频转换成mp4,则可以使用以下命令。
ffmpeg -i source.flv -acodec copy -vcodec copy out.mp4
-i表示输入文件,-acodec表示音频编解码器,-vcodec表示视频编解码器,copy表示直接拷贝输入流到输出流。其中-acodec copy -vcodec copy
可以简写为-c copy
。
假如说你打算提取出一个视频中的音频文件,并将其保存为mp3格式,那就更简单了,几乎不需要什么额外的参数。
ffmpeg -i mv.mp4 music.mp3
音频格式转换,比如将aac格式转换成wav格式。
ffmpeg -i source.aac out.wav
去除一个视频中的音频。
ffmpeg -i source.mp4 -an out.mp4
其中-an
表示不要音频。
媒体剪辑与合并
比如说现在有一个需求,需要剪辑视频的1:01到1:31这段时间输出为一个新的视频。
ffmpeg -i source.mp4 -ss 00:01:01 -t 30 -c copy out.mp4
上述这段命令表示从1:01开始剪30秒的视频,当然,你也可以使用下面的命令:
ffmpeg -i source.mp4 -ss 00:01:01 -to 00:01:31 -c copy out.mp4
注意到,t表示剪辑的时长,而to表示剪辑的终点。你也可以将-ss
放置在-i
输入文件的前面,不过,当这样使用时,只可使用t选项,而不可使用to。
ffmpeg -ss 00:01:01 -i source.mp4 -t 30 -c copy out.mp4
下载网络视频的一段
上文中提到的命令还有一个重要的用处,即下载网络视频的一段。比如说你在网上看到一个不错的视频,打算将其中的一个精彩片段存下来。能够想到的一个方法是,将整个视频下载下来,再使用剪辑工具剪辑。可是这样做会有几个问题,一个是下载视频文件耗时且费流量,另一个问题则是占用硬盘空间。亦或者录屏,然而画质会遭受损失。不过,有了ffmpeg,一切问题都迎刃而解。
首先,你需要解析出在线视频的源地址,你可以使用一些在线解析工具,也可以按F12打开控制台切换到network选项卡手动查找。这里有一些技巧(将在另一篇文章中介绍),不过这不是本文的重点。
现在,假设你已经获得了视频源地址,它可能是一个较大的mp4文件,或者是一个m3u8文件,不过这些并不影响。下面这个例子将一个网络视频中的01:01:01(一小时零一分一秒)到01:11:01下载到本地,并保存为download.mp4。
ffmpeg -ss 01:01:01 -i "https://example.com/hls/token/he-xu-yuan/player.m3u8?t=10086&key=10086&expiredtime=YIWANNIAN" -t 600 -c copy download.mp4
注意到,修改-i
选项。是的,就是如此简单。请注意,必须将-ss
选项放到-i
前面。
自定义HTTP Header
当输入为网络地址时,有时可能需要自定义请求头。此时,使用-headers
选项。
ffmpeg -ss 01:02:03 -headers "Referer: https://example.com/" -i "https://example.com/hls/token/he-xu-yuan/index.m3u8" 1.mp4
特别地,user-agent可以由-user_agent
选项指定,即-user_agent "chrome"
和-headers "user-agent: chrome"
是等价的。
媒体合并
细心的朋友可能注意到,某些app缓存下来的视频是三个文件,一个没有声音的视频文件、一个原生音频文件、还有一个媒体编码信息info文件。此时,一种可能的需求是将视频文件和音频文件合并。这并不麻烦。
ffmpeg -i movie.flv -i audio.flac -c copy out.mkv
注意到,只需多次使用-i
选项。是的,这并不复杂。
然而,多数情况下,手机缓存下来的视频可能是由一堆ts文件组成,如何将多个视频文件片段合成一个完整的视频呢?故技重施?好像并不可以。
此时需要新建一个 list.txt 文件,告诉ffmpeg有哪些文件需要合并。格式如下:
file "1.ts"
file "2.ts"
file "3.ts"
然后,使用以下命令[1]:
ffmpeg -f concat -i list.txt -c copy out.mp4
问题在于,通常ts文件可能有100多个,如果手打的话,十分费劲。熟悉C语言的同学,可以使用printf
格式化输出,并将输出流重定向到文件。此时,只需一个for语句即可。
上面的这个命令对于不是ts格式文件也可以使用,比如说都是flv格式的文件,此时输出文件也需为out.flv。
然而,有时可能会遭遇一些问题,比如说需要合并的文件都是自己手工剪辑的,而非视频网站切分好的文件。这时,在合并完成后,你可能会看到一些错误提示[2]。有时它并不会影响合并后的视频正常播放,有时它会引起视频时间轴错误。此时,可以尝试将视频先包装进ts文件中[1],再合并ts文件。
ffmpeg -i source.flv -c copy -bsf:v h264_mp4toannexb -f mpegts 1.ts
上述命令将一个flv文件转为了ts文件,也可以尝试将其转为mts文件。
ffmpeg -i 1.mp4 -q 0 1.mts
其中,-q 0
为指定输出文件采用尽可能最好的质量以实现输入文件的画面与声音。
格式转换完成后,再重新合并即可。
另一种情况,如果你能找到m3u8文件,此时只需要将其作为输入即可。
ffmpeg -i index.m3u8 -c copy out.mp4
请注意,当输入文件为本地m3u8文件,而其中引用了网络地址,会引发错误(例如:Protocol 'https' not on whitelist 'file,crypto,data'!
)。此时,需要启用协议白名单[3]。
其他
比如说现在有一个手机录制的视频,但声音太小了,想将视频文件中的声音调大怎么办?
ffmpeg -i source.mp4 -vcodec copy -filter:a "volume=3" out.mp4
上述命令对输入流的视频流直接拷贝,对音频流使用过滤器,volume=3
表示输出文件的音频流的基础音量为源文件的3倍。如果需要调小视频的音量,使用小数即可。
ffmpeg -i music.mp3 -filter:a "volume=0.5" out.mp3
上面的命令将一个mp3音乐文件中的基础音量调小。