
HLS (HTTP Live Streaming)是苹果推出的视频流协议,HLS格式的视频包含一个m3u8文本文件,以及众多的.ts的视频片段,而m3u8文本文件的作用就是将这些ts片段索引起来。 因为HLS协议是将视频切分成很多小的ts片段,这些小片段很适合放到cdn上,有很多视频文章都使用了hls格式传输视频。类似于一部漫画中有多张图片的原理,当服务器加载时而不需要加载整个mp4文件(文件有时可能达到4~5G,则会立即消费4~5G的内存),而使用m3u8则不会出现这个缺点,比如一部漫画中有200张图,它会一张一张下载,而不会一次性占有用大量的内存
ffmpeg安装请参见 centos8 之FFmpeg安装笔记
一键式快捷执行转为m3u8
//直接执行 不论任何格式
ffmpeg -y -i /storage3/video1/31144/1/2/02.mkv -c copy -f hls -bsf:v h264_mp4toannexb -hls_list_size 0 -hls_key_info_file /storage3/video1/31144/1/2/hls.keyinfo -hls_segment_filename /storage3/video1/31144/1/2/z02_%04d.ts /storage3/video1/31144/1/2/index.m3u8
加密功能
//创建一个 hls.keyinfo文件
vi /storage3/video1/31144/1/2/hls.keyinfo 并输入以下内容
-----------------------------------------
/video/31144/1/2/index.key #使用http形式的请求路径
/storage3/video1/31144/1/2/index.key #key本地保存的位置
IV[可选项,可以不填]
---------------------------------------------------------
key生成方法:openssl rand -hex 16
//生成m3u8文件时带上参数:
-hls_key_info_file /storage3/video1/xxx/xxx/xxx/hls.keyinfo
其他类型的视频文件转为mp4
//查看视频信息
#ffprobe input.mkv
//如果音视频编码为h264/aac则执行
ffmpeg -i input.mkv -acodec copy -vcodec copy out.mp4
//只是换了一个封装格式
ffmpeg -i test.mp4 -vcodec copy -acodec copy out.flv
//否则执行
ffmpeg -i input.mkv -acodec libfaac -vcodec libx264 out.mp4
//通用:
ffmpeg -i 源文件 -y -c:v libx264 -strict -2 \home\xxx.mp4
1.将mp4转为完整的ts
//例子1
ffmpeg -y -i /storage3/video1/31144/1/2/01.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb /storage3/video1/31144/1/2/01.ts
//例子2
ffmpeg -i out.mp4 -c copy -bsf h264_mp4toannexb output.ts
//通用
ffmpeg -y -i \home\xxx.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb \home\xxx.ts
2.TS文件切片
//例子1:
#ffmpeg -i output.ts -c copy -map 0 -f segment -segment_list playlist.m3u8 -segment_time 10 output%03d.ts
//例子2:以H264和AAC的形式对视频进行输出
#ffmpeg -i output.mp4 -c:v libx264 -c:a aac -strict -2 -f hls -hls_list_size 0 -hls_time 5 output1.m3u8
2.ffmpeg转化成HLS时附带的指令
//通用
ffmpeg -i \home\xxx.ts -c copy -map 0 -f segment -segment_list \home\xxx\index.m3u8 -segment_time 30 \home\xxx\nxb-%04d.ts
ffmpeg -i /storage3/video1/31144/1/2/01.ts -c copy -f segment -segment_list /storage3/video1/31144/1/2/index.m3u8 -segment_time 5 /storage3/video1/31144/1/2/nxb-%04d.ts
ffmpeg -i /storage3/video1/31144/1/2/01.mp4 -c:v copy -hls_time 4 -hls_segment_filename /storage3/video1/31144/1/2/nxb-%04d.ts -f hls /storage3/video1/31144/1/2/index.m3u8
参数
-i ——指定输入的文件名
-f ——指定输出格式。
-f xxx 输出格式,可以为gif,hls(m3u8格式),segment(ts格式),mp3,concat(合并音频/视频)
-f mp3 指定输出的文件格式
-y ——若输出文件已存在时则覆盖文件。
-fs ——超过指定的文件大小时则结束转换。
-t ——指定输出文件的持续时间,以秒为单位。
-ss ——从指定时间开始转换,以秒为单位。
-t从-ss时间开始转换(如-ss 00:00:01.00 -t 00:00:10.00即从00:00:01.00开始到00:00:11.00)。
-title ——设置标题。
-timestamp ——设置时间戳。
-vsync ——增减Frame使影音同步。
-c copy ——指定输出文件的编码。(极速)照抄输入文件原来的编解码器所做的事
-metadata ——更改输出文件的元数据。
-help ——查看帮助信息。
//影像参数
-b:v ——设置影像流量,默认为200Kbit/秒。(单位请引用下方注意事项)
-r ——设置帧率值,默认为25。
-s ——设置画面的宽与高。
-aspect ——设置画面的比例。
-vn ——不处理影像,于仅针对声音做处理时使用。
-vn: 去掉视频
-vcodec( -c:v ) ——设置影像影像编解码器,未设置时则使用与输入文件相同之编解码器。
-vcodec: //视频选项,一般后面加copy表示拷贝
-c:v libx264 //以H264
-re 以本机帧速率读取输入。主要用于模拟抓取设备或实时输入流(例如从文件读取时)。不应与实际抓取设备或实时输入流(可能导致数据包丢失)一起使用。
-hls_time 5 //设置每片的长度,默认值为2。单位为秒
-hls_time n: 设置每片的长度,默认值为2。单位为秒
-hls_time 指定切分的ts文件时长,单位秒
查阅资料后发现,ts切片的大小严格依赖于原始视频的GOP大小,因为必选保证一个ts内至少包含一个GOP,否则这个ts分片就无法使用。
我们只需要再新增一个参数 -force_key_frames "expr:gte(t,n_forced*2)" 这个参数的作用就是让视频GOP大小为2s,这样就能保证ts分片大小是我们想要的2s了。
大概的意思就是:转码成TS格式文件需要使用此项。(英文好的可以自己翻译一下)
-hls_segment_filename ts文件的命名格式
-hls_list_size 0 //设置播放列表保存的最多条目,设置为0会保存有所片信息,默认值为5
-hls_list_size n:设置播放列表保存的最多条目,设置为0会保存有所片信息,默认值为5
-hls_wrap n:设置多少片之后开始覆盖,如果设置为0则不会覆盖,默认值为0.这个选项能够避免在磁盘上存储过多的片,而且能够限制写入磁盘的最多的片的数量
-hls_start_number n:设置播放列表中sequence number的值为number,默认值为0
-bsf h264_mp4toannexb mp4转ts专用参数
ffmpeg中h264_mp4toannexb使用说明及注意事项
如果不使用 -bsf h264_mp4toannexb 参数会提示错误,主要是因为使用了mp4中的h264编码 而h264有两种封装:
一种是annexb模式,传统模式有statrtcode SPS和PPS是在ES中。
另一种是mp4模式,一般mp4 mkv avi会没有startcode SPS和PPS以及其他信息被封装在container中 每一个frame前面是这个frame的长度,
很多解码器只支持 annexb 这种模式,因此需要将mp4做转换,在ffmpeg中用 h264_mp4toannexb_filter 可以做转换,所以需要使用 -bsf h264_mp4toannexb 来进行转换。
-map 0 从输入索引 #0(第一个输入)中选择所有流。
//声音参数
-b:a ——设置每Channel(最近的SVN版为所有Channel的总合)的流量。(单位请引用下方注意事项)
-ar ——设置采样率。
-ac ——设置声音的Channel数。
-acodec ( -c:a ) ——设置声音编解码器,未设置时与影像相同,使用与输入文件相同之编解码器。
-c:a aac //AAC的形式
-acodec: //音频选项, 一般后面加copy表示拷贝
-an ——不处理声音,于仅针对影像做处理时使用。
-an: 去掉音频
-vol ——设置音量大小,256为标准音量。(要设置成两倍音量时则输入512,依此类推。)
-strict -2 //使用FFmpeg自带的aac音频编码
注:-strict -2 之前是实验参数表示 aac音频编码,如果不使用aac音频编码使用使其的编码好像还需要导入第三方的音频编码库,使用FFmpeg自带的aac音频编码带上-strict -2 参数就可以了。
合并视频 (A视频画面+B音频=C视频)
//只要视频,不要声音
ffmpeg -i video.avi -vcodec copy -an video2.avi
//画面+声音 合并输出
ffmpeg -i video2.avi -i audio.mp3 -vcodec copy -acodec copy output.avi
提取视频/音频
ffmpeg -i test.mp4 -an -vcodec copy out.h264 提取视频 an跳过auido
ffmpeg -i test.mp4 -vn -acodec copy out.aac 提取音频
压缩转码mp4文件
压缩转码mp4文件
ffmpeg -i input.avi -s 640x480 output.avi
ffmpeg -i input.avi -strict -2 -s vga output.avi
//将输入的1920x1080缩小到960x540输出:
ffmpeg -i input.mp4 -vf scale=960:540 output.mp4
//ps: 如果540不写,写成-1,即scale=960:-1, 那也是可以的,ffmpeg会通知缩放滤镜在输出时保持原始的宽高比。
合并多段音频
ffmpeg -f concat -i file.txt meg.mp3
解释:将需要拼接的音频文件名称写出 file 文件名.mp3换行,这样一行一行写到txt文件中,meg.mp3为输出文件。
视频添加水印
//为视频添加logo(也就是为视频添加水印)
//将一张图片贴到一个视频上,那可以用如下命令:
ffmpeg -i input.mp4 -i iQIYI_logo.png -filter_complex overlay output.mp4
要贴到其他地方?看下面:
//右上角:
ffmpeg -i input.mp4 -i logo.png -filter_complex overlay=W-w output.mp4
//左下角:
ffmpeg -i input.mp4 -i logo.png -filter_complex overlay=0:H-h output.mp4
//右下角:
ffmpeg -i input.mp4 -i logo.png -filter_complex overlay=W-w:H-h output.mp4
//可以设置坐标,视频的左上角为原点
ffmpeg -i input.mp4 -i logo.png -filter_complex overlay=480:10" output.mp4
去掉水印
//去掉视频的logo(去掉水印)
//语法:-vf delogo=x:y:w:h[:t[:show]]
//x:y 离左上角的坐标
//w:h logo的宽和高
//t: 矩形边缘的厚度默认值4
//show:若设置为1有一个绿色的矩形,默认值0。
ffmpeg -i input.mp4 -vf delogo=0:0:220:90:100:1 output.mp4
画质压缩
https://trac.ffmpeg.org/wiki/Encode/H.264
CRF 比例的范围是 0-51,其中 0 是无损的(仅适用于 8 位,对于 10 位使用 -qp 0),23 是默认值,51 是可能的最差质量。较低的值通常会导致较高的质量,主观上理智的范围是 17-28。将 17 或 18 视为视觉无损或接近无损;它应该看起来与输入相同或几乎相同,但它在技术上不是无损的。
该范围是指数级的,因此将 CRF 值增加 +6 会导致大约一半的比特率/文件大小,而 -6 会导致大约两倍的比特率。
选择仍能提供可接受质量的最高 CRF 值。如果输出看起来不错,则尝试更高的值。如果看起来不好,请选择较低的值。