使用 ffmpeg 命令进行视频的编辑

摘要

最近项目用到 ffmpeg 的命令对视频或音频进行编辑,在这里由项目需求出发做一个归纳。
通过雷霄骅先生的一篇博文1 可以了解关于 ffmpeg 详尽的知识和用途,让人不由得对这位先驱产生敬意。
文末的参考资料中可以看到一些文档以及教程。通过这些文档和教程,就可以在满足了需求之后再回头学习各个命令的意义和作用,从而在遇到新需求时能够更加快速的找到解决方案。

涉及的 ffmpeg 命令

预设的配置值
	//质量参数, 0~50, 越小质量越高. 18~23 肉眼不可分辨的变化
    private $crf = 16;

    //编码预设值 preset: 可选:ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow, placebo
    private $preset = 'ultrafast';

质量参数 crf 越小,质量越高,输出的文件就越大;编码预设值 preset 可以理解为压制程度与时间的关系值,时间越长,压制程度就要高,输出的文件就越小,反之同理。
项目需要对视频进行一系列的操作,最终输出处理后的视频。所以,在这个一系列操作的过程中,我把编码预设值设成了 ultrafast ,是希望尽量缩短这个过程所耗费的时间。当然,这是由操作所需的临时空间换来的。操作完成后,再由 2-pass 压制视频为所需的文件大小输出。
而关于质量参数的值,系统默认的好像是 18,但是经过多次操作后,视频的质量还是有了肉眼可分辨的下降。设为 16 是可满足我项目的需求的一个值。

为视频添加字幕
ffmpeg -i {$originFileTmpPath} -vf subtitles={$subtitlePath} -crf {$this->crf} -preset {$this->preset} {$subFilePath}
根据输入文件内容,拼接音频并输出到指定路径:

(此处用的是博文2的方法二「FFmpeg concat 分离器」)

ffmpeg -f concat -safe 0 -i {$fileListPath} -c copy {$finalFilePath}

这里多了 -safe 0 ,原因是:

在 filelist.txt 里面加入/的话会报一个不安全文件路径的错误
Unsafe file path
只要加上 -safe 0 就可以解决啦

保留原声合并音(视)频3
ffmpeg -i {$input} -i {$addFilePath} -filter_complex amix=inputs=2:duration=first:dropout_transition=2 -crf {$this->crf} -preset {$this->preset} {$output}

注意:inputs=输入流数量,duration=决定流的结束(longest最长输入时间,shortest最短,first第一个输入持续的时间),dropout_transition= 输入流结束时,容量重整时间

截取时间段内的音频
ffmpeg -ss {$startTime} -i {$input} -to {$endTime} -c copy -copyts {$outputPath}
ffmpeg -ss {$startTime} -i {$input} -t {$duration} -c copy {$outputPath}

如果你仅仅在输入文件之前( -i 之前)指定了 ss 选项,那么时间戳会被重置为 0,此时选项 t 和选项 to 产生的效果一样。
如:ffmpeg -ss 00:01:00 -i video.mp4 -to 00:02:00 -c copy cut.mp4
ffmpeg -i video.mp4 -ss 00:01:00 -to 00:02:00 -c copy cut.mp4
上面例子中,第一个命令会得到从 00:01:00 到 00:03:00 的片断,而第二个命令会真正得到从 00:01:00 到 00:02:00 的片断。

关于 mpeg 格式的截取,这个 关于I帧的解释:什么是GOP 博文里的一个测试还是很具象地解释了 mpeg 格式为什么难以精确剪辑。

关于视频的精确剪辑,直接:

ffmpeg -i {$input} -ss {$startTime} -to {$endTime} {$outputPath}

ffmpeg 会默认重新解码编码,从而截取精确的视频时间段。当然,所耗的时间也会变长了。

调整音频速率4
ffmpeg -i {$input} -filter:a atempo={$multiple} {$output}

$multiple float|int 倍率调整范围为[0.5, 2.0]

超过调整范围时,比如 4 倍,可以通过重复参数实现:

ffmpeg -i {$input} -filter:a atempo=2,atempo=2 {$output}
去除音视频的原声
ffmpeg -i {$input} -c:v copy -an {$output}

-c:v copy 表示复制视频,-an 表示不需要音频。

为不带音频的视频文件添加音频
ffmpeg -i {$input} -i {$audio} {$output}

#0:0 表示视频流,#0:1 表示音频流。该命令只适用于给音频流为空的视频文件添加音频流。

生成指定长度的空白音频
ffmpeg -f lavfi -i aevalsrc=0 -t {$seconds} -q:a 9 -ac 1 -ar 16000 -acodec pcm_s16le {$output}
视频转音频,wav 格式
ffmpeg -i {$input} -vn -ar 16000 -ac {$channel} -f wav {$output}

-vn 表示不需要视频。

生成视频封面图
ffmpeg -ss 00:00:00 -t 00:00:00.001 -i {$input} -r 1 -f image2 {$output}
改变音频文件的音量
ffmpeg -i {$input} -filter: volume={$multiple} -y {$output}
获取音视频时长
ffmpeg -i {$input}  2>&1 | grep 'Duration' | cut -d ' ' -f 4 | sed s/,//

通过命令行命令,搜索、截取出 00:00:00 格式的音视频时长。

获取视频帧图
ffmpeg -i {$input} -vf scale=160:-1 -r {$numPerSecond} -start_number 000000 {$dir}/%11d.png

-start_number 设置输出文件名开始的数字。

修改视频分辨率5
ffmpeg -i {$input} -vf scale=iw*{$multiple}:ih*{$multiple} -crf {$this->crf} -preset {$this->preset} {$output}

-vf 表示滤镜。scale 为滤镜里的缩放功能。iw/ih 表示原始尺寸的大小。scale=-1:ih*2 表示高度乘 2,宽度等比缩放。

2-pass 压制视频可自定义码率6 = 可自定义大小
ffmpeg -i {$input} -strict -2 -passlogfile {$dir} -vb {$bitRate}k -pass 1 -f mp4 -y /dev/null
ffmpeg -i {$input} -strict -2 -passlogfile {$dir} -vb {$bitRate}k -pass 2 -f mp4 {$output}

两条命令可以分开执行,也可以用 && 连接一起执行。
-strict -2 -passlogfile {$dir} 用于指定生成中间临时文件的目录。
-vb 可理解为 video bitrate。

生成纯色视频
ffmpeg -f lavfi -i color=white:1280*720:d=10 -format rgb32 -f matroska -vcodec libx264 -b:v 2000k color.mp4
循环图片生成视频
ffmpeg -stream_loop {$frame} -i {$input} {$output}

参考资料

2015 年中文翻译的文档
官网英文文档
FFmpeg 分 P 教学——哔哩哔哩


  1. FFMPEG 视音频编解码零基础学习方法 ↩︎

  2. 使用 ffmpeg 连接音视频 ↩︎

  3. java操作ffmpeg为视频添加背景音乐的评论 ↩︎

  4. ffmpeg 调整音视频播放速度 ↩︎

  5. 如何用FFmpeg截取视频、调整分辨率和提取音轨? ↩︎

  6. 追求视频画质,教你如何使用 ffmpeg 压制出高质量的视频!——哔哩哔哩 ↩︎

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值