FFmpeg
FFmpeg
是视频处理最常用的开源软件。它功能强大,用途广泛,大量用于视频网站和商业软件,也是许多音频和视频格式的标准编码/解码实现。
什么?! 你还没安装,可以根据 官方文档 先完成安装。
然后把目录下的bin
文件夹加到系统环境变量。然后CMD
输入 ffmpeg
可以看见版本信息就说明好了


基本概念
1 .容器
视频文件本身其实是一个容器(container)
,里面包括了视频和音频,也可能有字幕等其他内容。
常见的容器格式有以下几种。一般来说,视频文件的后缀名反映了它的容器格式。
- MP4
- MKV
- WebM
- AVI
查看 FFmpeg 支持的容器
$ ffmpeg -formats
2 .编码格式
视频和音频都需要经过编码,才能保存成文件。不同的编码格式(CODEC)
,有不同的压缩率,会导致文件大小和清晰度的差异。
常用的视频编码
- H.262
- H.264
- H.265
上面的编码格式都是有版权的,但是可以免费使用。此外,还有几种无版权的视频编码格式
- VP8
- VP9
- AV1
常用的音频编码
- MP3
- AAC
上面所有这些都是有损的编码格式,编码后会损失一些细节,以换取压缩后较小的文件体积。无损的编码格式压缩出来的文件体积较大,这里就不介绍了,可以查看 FFmpeg 支持的编码格式,视频编码和音频编码
$ ffmpeg -codecs
3 .编码器
编码器(encoders)
是实现某种编码格式的库文件。只有安装了某种格式的编码器,才能实现该格式视频/音频的编码和解码。
这是一些 FFmpeg 内置的视频编码器
- libx264:最流行的开源 H.264 编码器
- NVENC:基于 NVIDIA GPU 的 H.264 编码器
- libx265:开源的 HEVC 编码器
- libvpx:谷歌的 VP8 和 VP9 编码器
- libaom:AV1 编码器
音频编码器如下
- libfdk-aac
- aac
查看 FFmpeg 已安装的编码器
$ ffmpeg -encoders
参数
$ ffmpeg {1} {2} -i {3} {4} {5}
上面命令中,五个部分的参数依次如下
1. 全局参数
2. 输入文件参数
3. 输入文件
4. 输出文件参数
5. 输出文件
参数太多的时候,为了便于查看,ffmpeg 命令可以写成多行
$ ffmpeg \
[全局参数] \
[输入文件参数] \
-i [输入文件] \
[输出文件参数] \
[输出文件]
例子
$ ffmpeg \
-y \ # 全局参数
-c:a libfdk_aac -c:v libx264 \ # 输入文件参数
-i input.mp4 \ # 输入文件
-c:v libvpx-vp9 -c:a libvorbis \ # 输出文件参数
output.webm # 输出文件
上面的命令将 mp4
文件转成 webm
文件,这两个都是容器格式。输入的mp4
文件的音频编码格式是 aac
,视频编码格式是 H.264
;输出的 webm
文件的视频编码格式是 VP9
,音频格式是 Vorbis
如果不指明编码格式,FFmpeg
会自己判断输入文件的编码。
因此,上面的命令可以简单写成下面的样子
$ ffmpeg -i input.avi output.mp4
实例
这是我最常用的,也是博客上视频使用的方式,把MP4
切割成TS
的切片,并生成M3U8
索引,视频转码流hls
和音频ACC
时间
$ ffmpeg -i mp4\22.mp4 -c:v libx264 -hls_time 10 -hls_list_size 0 -c:a aac -threads 5 -preset ultrafast -strict -2 -f hls ia223\itgsa.m3u8
命令说明:
- -i 源视频绝对路径
- -c 视频流和没一片的时间 time这里 8,表示每片8秒时长
- -threads 5 -preset 使用多线程,如果你的设备好,可以多开几个
- acc 音频
- strict -2 -f hls 存放的绝对路径
- .m3u8 输入的文件名,不要写数字,顺序容易出错
注:使用多线程切出来的积极较大,几乎会增加一半的体积,看个人需要,下面是使用默认线程切割
$ ffmpeg -i mp4\33.mp4 -c:v libx264 -hls_time 8 -hls_list_size 0 -c:a aac -strict -2 -f hls ia223\itgsa.m3u8
开始切割
完成之后是这样子的,第一个是索引文件
不转码直接切,切的很快
ffmpeg -i 1.mp4 -c copy -strict -2 -bsf:v h264_mp4toannexb -f hls -hls_list_size 0 -hls_time 10 test/1.m3u8
转码
$ ffmpeg -i out.ogv -vcodec h264 out.mp4
$ ffmpeg -i out.ogv -vcodec mpeg4 out.mp4
$ ffmpeg -i out.ogv -vcodec libxvid out.mp4
$ ffmpeg -i out.mp4 -vcodec wmv1 out.wmv
$ ffmpeg -i out.mp4 -vcodec wmv2 out.wmv
-i
后面是输入文件名,-vcodec
后面是编码格式,h264
最佳,但 Windows
系统默认不安装,如果是要插入 ppt
的视频,选择 wmv1 或 wmv2
基本上万无一失。
附加选项
- -r 指定帧率
- -s 指定分辨率
- -b 指定比特率
于此同时可以对声道进行转码
- -acodec 指定音频编码
- -ab 指定音频比特率
- -ac 指定声道数
例
$ ffmpeg -i out.ogv -s 640x480 -b 500k -vcodec h264 -r 29.97 -acodec libfaac -ab 48k -ac 2 out.mp4
剪切
用 -ss
和 -t
选项, 从第 30
秒开始,向后截取 10
秒的视频,并保存
$ ffmpeg -i input.wmv -ss 00:00:30.0 -c copy -t 00:00:10.0 output.wmv
$ ffmpeg -i input.wmv -ss 30 -c copy -t 10 output.wmv
达成相同效果,也可以用 -ss
和 -to
选项, 从第 30
秒截取到第 40
秒
$ ffmpeg -i input.wmv -ss 30 -c copy -to 40 output.wmv
值得注意的是,ffmpeg
为了加速,会使用关键帧技术, 所以有时剪切出来的结果在起止时间上未必准确。 通常来说,把 -ss
选项放在 -i
之前,会使用关键帧技术; 把 -ss
选项放在 -i
之后,则不使用关键帧技术。 如果要使用关键帧技术又要保留时间戳,可以加上 -copyts
选项
$ ffmpeg -ss 00:01:00 -i video.mp4 -to 00:02:00 -c copy -copyts cut.mp4
合并
把多个个视频文件合并成一个,在视频文件所在目录下新建一个文件filelist.txt
,内容如下
file '1.mp4'
file '2.mp4'
file '3.mp4'
file '4.mp4'
file '5.mp4'
file '6.mp4'
在目录执行
ffmpeg -f concat -i filelist.txt -c copy output.mp4
更多时候,由于输入文件的多样性,需要转成中间格式再合成
ffmpeg -i input1.avi -qscale:v 1 intermediate1.mpg
ffmpeg -i input2.avi -qscale:v 1 intermediate2.mpg
cat intermediate1.mpg intermediate2.mpg > intermediate_all.mpg
ffmpeg -i intermediate_all.mpg -qscale:v 2 output.avi
GPU
ffmpeg
默认使用CPU
跑的,CPU
跑这种任务性能自然就不必多说了,电脑一般的,直接爆炸,或者根本跑不动,好在ffmpeg
是支持GPU
的,GPU
虽然速度快,但是质量不高,处理后的视频体积较大。而我主要是优化视频体积和质量的,因此在生产环境中我几乎没有用过GPU
进行加速,只是在测试时用了下。AMD
显卡请直接放弃,不用折腾了,我已经折腾过了 吐血经历只有自己知道
1、首先要先安装显卡驱动CUDACUDA
是Nvidia
出的一个GPU
计算库,让程序可以驱动Nvidia
显卡的GPU
进行各种工作,其中就包含了视频的编解码,怎么安装请自行百度下,内容太多,又可以写两篇文章了,这里就不赘述了。
2、查询使用的ffmpeg版本是否支持 CUDA,小站网盘提供的下载版本是支持的,在ZIP里,自己下载
$ ffmpeg -hwaccels
3、测试下
参数
- -hwaccel cuvid:指定使用cuvid硬件加速
$ ffmpeg -hwaccel cuvid -c:v h264_cuvid -i 0.mp4 -c:v h264_nvenc -y 00.mp4
1
将当前目录下的0.mp4转成00.mp4
$ ffmpeg -hwaccel cuvid -c:v h264_cuvid -i 0.mp4 -c:v h264_nvenc -r 15 -b 500k -y 00.mp4
个人站长视频解决方案
说实话,对于个人博客上放视频,有点难搞,涉及到两个最大的问题,第一无非就是流量和存储环境的问题,第二还有速度的问题,一个视频几百M,放几次流量就去没了几个G。视频储存是很多人的一个难题,如果自己买个服务器又需要带宽有需要硬盘够大,如果你服务器牛逼,放自己服务器也可以,那么这个方案就不用看了。小白请直接劝退,这部分内容不写教怎么一步一步做,而是解决思路和方法。
对于个人站长来说流量和存储两部分的费用一般人是玩不起的,反正我是玩不起。其次速度也很重要,不然放出来卡的鸭皮,谁TM看啊。放5秒 卡1秒,看的人直接心态爆炸,看尼玛
这个方案也是目前我在使用的方案,在经历,从播放器,到视频格式,到兼容设备,到云存储,到播放效果几个环节的折腾,终于得出非常低成本,低维护,却高效的方案,我另一个音乐站(blog.itggg.cn)
放了几十个视频上去,播放一点也不卡,进度条随便拖,几百个人同时看都可以,苹果,安卓,PC,都可以完美支持。
1、播放器的选择:我用的是 DPlayer
,这个播放器非常好用,支持HLS,MP4,flv,mkv
等众多格式的播放,在设备的兼容性也非常好,无论是移动端,还是苹果,PC,安卓都兼容。也很轻量化,我用了这么久是没发现任何问题的,并且是开源的。 项目地址
2、视频流的选择:目前我的是使用hls
的视频流,然后把视频进行切片处理,并生成m3u8
索引,且m3u8
也是目前主流的视频方案,许多大厂除了自己研发格式外,或者搞直播的,基本都是采用的这种方案。hls
支持的设备很完全,其次是MP4
的格式。mkv和flv
等格式大部分都在苹果设备上都不支持的,第二就是视频源要进行TS
切片,每片的大小约2M
左右就好,这样利于加载速度和节约流量,再搭配一个好的存储环境基本可以做到秒开。
m3u8 与 MP4 对比
对m3u8 与MP4 做一个简单对比
MP4
对HTML5
和flash
播放器亲和度都挺好。但是文件头太大,需要加载完成才能播放,其次结构复杂,长视频的大文件头影响加载速度的视频体验,所以MP4
在短视频的应用更常见m3u8
采用苹果的HLS
协议,目前ios
与android
设备均已支持。由于其工作原因是将整个视频流分成一个个小的基于Http
的文件进行下载播放,因此支持视频直播,和视频加速播放。
简单的来说就是,体积不大的视频用MP4更好,体积超过100M的视频用m3u8更好,更多信息可以自己百度下
播放对比,这个MP4
源视频体积约266M
,切片后总约大小14M
3、视频存储的选择:
3.1.稳定很重要,不要把视频传上去后,过不久就丢了,那你幸幸苦苦搞得全白费了。
3.2.速度要快,有钱的可以选择云厂商的对象存储,买个流量套餐包,体积在5G以内的视频基本上50块就就搞定,配上m3u8
可以最大程度上节约流量。没钱的可以选择一些免费的图床啊啥的,比如github,npm这些。
还有一种非常快且安全的方法是,把你的站接入百度云加速,视频都放在服务器上,然后在百度云加速上面的 “特定页面规则” 去缓存目录里所有的TS
切片,这样你服务器目录下的TS
切片就全部缓存在百度云的节点上面了,百度云的节点有多快就不必多说了。
前两种免费的方法都有限制,gitbuh
上传切片麻烦,且单一文件最大20M
。百度云节点的缓存命中率也不是特别高,且免费流量每天10G
,视频不多的可以考虑。想完全白嫖几乎不太可能,如果你真的做到了,请留言分享下好吗,我在这里先谢谢您了
我的存储是放在世纪互联的OneDrive
上的,就完全不考虑流量和并发的问题,只是处理视频的时候麻烦点而已
3.3.视频源需要固定的直链,这个非常重要。
需要注意一点,使用m3u8
做索引的时候,存储源一定要允许跨域请求,不然有时候会出现无法播放,或者播放一半就播放不了的情况。
32 comments
这样的hxd再给来一沓!
噢? 公网IP说个🔨 我现在用的阿里云盘存的视频,已经白嫖了。
我用阿里云盘获取直链,不能播放是什么原因,视频和音频都不行
链接发来看看呢
链接发评论不了唉
用单引号包裹起来就可以了 'https://itggg.cn/' 比如这样
加了还不行
直接邮箱回复
博主,我想问下本地切片后上传世纪互联,然后引用OneIndex的链接可以吗?
可以是可以,但是有个问题,OneIndex的连接不是固定的,是解析出来的,我之前采用的这个方案是写了一个脚本定时去解析,然后更改文章里的链接实现的。
额...那有没有什么办法能获取固定的直链呢
世纪互联版的可以,如果你视频不多,可以切片好打包发给我帮你存。
我视频挺多的...总不能每次都麻烦你吧 。要是可以的话告诉我怎么做就最好了
当然要是不方便的话也没关系 ::aru:aru117::
不是不方便,脚本定时去解析这个方案我已经弃用了,用世纪互联的OneIndex,开放API权限,可以获取直连。可以自己百度下,篇幅较长。
好的,谢啦
我的怎么报错呀
osss设置了跨域 而且在放在本机都播放失败
报的什么错? 有没有地址或者截图看一下
截图有点麻烦 你进我博客
就是加载失败
dplayer插件开启了HLS支持
三个问题:
第一:视频源地址不要加中文,在解码的时候可能有某种未知的问题
第二:视频源放在服务器上,需要FTP的访问,你如果用的是nginx的话,可能是无法播放的,nginx不能做这中反向请求到服务器里的,
第三:跨域了,配置下CORS跨域请求
OK 我在帮你看 你加我QQ吧 546960041
哈哈,想不想试试搞视频
想哦!
那就开搞
请你喝奶茶