前提条件,已经下载ffmpeg,熟练使用nginx,配置好rtmp及hls切片
1 简单使用需要下载ffmepg,然后配置环境变量
也可以在ffmepg下载好的文件夹上,使用cmd,操作
2 基本命令行参数介绍
-i 输入文件的位置
-y(覆盖输出文件,即如果1.***文件已经存在的话,不经提示就覆盖掉了)
-b 码率
-b:a 200k, 音频,-b:v 200k 视频
-re 使用正常速度推流
-stream_loop -1 循环推流
-vcodec copy或者libx264 视频转码格式,可以不写
-acodec copy或者aac 音频转码格式,可以不写
-f flv 输出流格式
-r 16 帧率,一秒钟可以看到多少帧数,可以直接优化直播画面卡顿问题
-framerate 15 可以优化直播画面卡顿问题
-crf 51 码率, 可以将视频清晰度直接下降,直接降低网速,硬件要求
-ab 128000 声音品质,越小,声音越模糊,但是视频越流畅
3 一些推流命令
ffmpeg -re -stream_loop -1 -fflags +genpts -i c:\aa\aa.mp4 -vcodec copy
-acodec copy -strict -2 -f flv -y rtmp://localhost:1935/hls1/test03
4 调节帧率
帧率 1、用 -r 参数设置帧率
ffmpeg –i input –r 25 output
5 码率 设置参数-b
ffmpeg -i 1.mp4 -b 1.5M 2.mp4
音频:-b:a 视频: - b:v 设置视频码率为1500kbps ffmpeg -i input.avi -b:v 1500k output.mp4
6 rtmp流 转为 hls
ffmpeg -re -i rtmp://124.221.251.9:1935/live1/test03 -vcodec libx264 -vprofile baseline -acodec libmp3lame -ar 44100 -ac 1 -f flv rtmp://127.0.0.1:1935/hls1/test03
7 本地视频文件循环播放,推送为rtmp,并生成hls切片 亲测可用
ffmpeg -re -stream_loop -1 -fflags +genpts -i c:\aa\aa.mp4 -vcodec libx264
-acodec aac -strict -2 -f flv -y rtmp://localhost:1935/hls1/test03
8 本地视频文件,推送为rtmp流,亲测可用
ffmpeg -re -i c:\aa\aa.mp4 -vcodec libx264 -acodec aac -ac 1 -ab 128 -framerate 20 -crf 51 -r 20 -f flv rtmp://localhost:1935/live1/test03
9 如果输入的流,那么不要使用re命令,否则会卡
10 同时使用-crf 51, -r 16 -ac 1可以直接降低网路要求,立马提高直播视频流畅度
11 window系统环境,读取硬盘的视频文件,生成hls切片, 亲测可用
ffmpeg -re -i c:\aa\aa.mp4 -vcodec libx264
-acodec aac -ac 1 -crf 51 -r 16 -y -hls_time 2 -hls_list_size 50 -f hls c:\\m3u8\\test03_.m3u8
linux系统环境
ffmpeg + " -i " + videoInputPath + " -vcodec libx264 " + " -acodec aac -ab 1 "+ " -hls_time 2 -hls_list_size 20 " + " -crf 30 " + " -y " + " /usr/local/nginx/html/hls1/aa.m3u8";
今天考虑一个mcu混合的实现,也就是接收多路过来的rtp流,然后转发出去一路的rtmp流,使用ffmpeg测试做的记录,刚开始一直通过ffmpeg推送的文件流不能满足要求,还是对参数配置不熟悉;
0、ffmpeg 命令格式:
$ ffmpeg \
-y \ # 全局参数
-c:a libfdk_aac -c:v libx264 \ # 输入文件参数
-i input.mp4 \ # 输入文件
-c:v libvpx-vp9 -c:a libvorbis \ # 输出文件参数
output.webm # 输出文件
下列为较常使用的参数:
-i——设置输入文件名。
-f——设置输出格式。
-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——指定输出文件的编码。
-metadata——更改输出文件的元数据。
-help——查看帮助信息
影像参数:
-b:v——设置影像流量,默认为200Kbit/秒。(单位请引用下方注意事项)
-r——设置帧率值,默认为25。
-s——设置画面的宽与高。
-aspect——设置画面的比例。
-vn——不处理影像,于仅针对声音做处理时使用。
-vcodec( -c:v )——设置影像影像编解码器,未设置时则使用与输入文件相同之编解码器。
声音参数:
-b:a——设置每Channel(最近的SVN版为所有Channel的总合)的流量。(单位请引用下方注意事项)
-ar——设置采样率。
-ac——设置声音的Channel数。
-acodec ( -c:a ) ——设置声音编解码器,未设置时与影像相同,使用与输入文件相同之编解码器。
-an——不处理声音,于仅针对影像做处理时使用。
-vol——设置音量大小,256为标准音量。(要设置成两倍音量时则输入512,依此类推。)
-preset:指定输出的视频质量,会影响文件的生成速度,有以下几个可用的值 ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow。
1、udp或者rtp推流
>最简单模式:
ffmpeg -re -i d:\videos\1080P.264 -vcodec copy -f rtp rtp://127.0.0.1:1234
ffplay接收端的命令:
ffplay -protocol_whitelist "file,udp,rtp" -i rtp://127.0.0.1:1234
>复杂模式,决定rtp包封装大小,封装格式,决定I帧间隔
ffmpeg -re -i tuiliu_mp4.mp4 -vcodec libx264 -b:v 800k -s 480x320 -preset:v ultrafast -tune:v zerolatency -an -f rtp -profile baseline -rtpflags h264_mode0 -pkt_size 1460 -slice-max-size 1400 -maxrate 600k -minrate 600k -r 20 -g 20 -keyint_min 20 -an -f rtp rtp://11.12.112.42:49196
关键命令参数说明:
-re一定要加,代表按照帧率发送
-i url (input) 输入文件路径或者 url
-vcodec libx264 ,表示使用x264重新编码
-b:v 800k 码率设置
-s 480x320 分辨率设置
-preset:v ultrafast 开启x264的 -preset fast/faster/verfast/superfast/ultrafast参数
-tune:v zerolatency 即时编码,去掉编码延迟
-profile: 设置编码等级,baseline, main, high
-payload_type :rtp的pt值
-pkt_size:rtp发送的最大长度
-slice-max-size:一个nula包数据的最大长度
-rtpflags h264_mode0 rtp打包模式 packetizition-mode=0, 当 packetization-mode 的值为 0 时或不存在时, 必须使用单一 NALU 单元模式.;当 packetization-mode 的值为 1 时必须使用非交错(non-interleaved)封包模式.;当 packetization-mode 的值为 2 时必须使用交错(interleaved)封包模式.
-pkt_size 1460
-slice-max-size 1400
-maxrate 600k
-minrate 600k (可以使用 -crf 24替换,控制视频码率和质量的均衡)
-r 20 设置帧率为20帧/s
-g 20 GOP间隔,每隔20个帧为一个GOP,两个关键帧之间的帧数称为一个GOP,将关键帧帧间隔设置为1s,也就是每秒一个关键帧
-keyint_min 20 最小关键帧间隔
-an 没有音频,“-an”(no audio)和“-vn”(no video)分别用来单独输出视频和音频
-f:rtp 强制ffmpeg采用某种格式,后跟对应的格式。
> 使用RTP分别发送音频流和视频流
FFmpeg命令:
ffmpeg -re -i <media_file> -an -vcodec copy -f rtp rtp://<IP>:5004 -vn -acodec copy -f rtp rtp://<IP>:5005 > test.sdp
FFplay接收的SDP文件:
1 2 3 4 5 6 7 8 9 10 11 12 |
|
2、rtsp推流
ffmpeg -re -i /root/mp4/1.mp4 -vcodec copy -acodec copy -rtsp_transport tcp -f rtsp rtsp://192.168.2.161/live/rtsp_test
-rtsp_transport tcp 标识使用tcp作为rtp的通道
3、rtmp推流
ffmpeg -re -i /root/mp4/1.flv -vcodec copy -acodec copy -f flv rtmp://192.168.2.161/live/rtsp_test
修改-i参数为rtsp的地址,可以拉监控流然后转发为rtmp流:
ffmpeg -f rtsp -i rtsp://admin:xdddd1998@11.12.112.249:554/h264/ch1/sub/av_stream -vcodec libx264 -b:v 800k -s 480x320 -preset:v ultrafast -tune:v zerolatency -an -f rtp -profile baseline -rtpflags h264_mode0 -pkt_size 1460 -slice-max-size 1400 -maxrate 600k -minrate 600k -g 20 -keyint_min 20 -y rtp://11.12.112.42:62159
4、ffmpeg切片,很多人会问,直接播放mp4不就好了么,为什么要切片再播放?
如果是MP4文件,需要先完整的下载格式为 mp4 的视频文件,当视频文件下载完成后,网站才可以播放该视频,这就对于用户体验是极大的下降,所以需要切片为多个ts文件,以及m3u8文件,m3u8格式的视频是将文件分成一小段一小段的ts文件,播放完一个在播放下一个,由于每次请求的ts文件都很小,所以基本可以做到无延时播放:
切片mp4视频文件:
ffmpeg -i ./video.mp4 -c:v libx264 -hls_time 60 -hls_list_size 0 -c:a aac -strict -2 -f hls ./video.m3u8
切片mp3音频文件:
ffmpeg -i ./kczfrr.mp3 -c:a libmp3lame -map 0:0 -f segment -segment_time 10 -segment_list ./kczfrr.m3u8
web页面播放m3u8,一方面可以使用腾讯的js插件,另一方面就是使用video.js的插件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
|
5、合并音视频
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
|
6、添加字幕
linux 下使用 ffmpeg 的命令
ffmpeg -i input.mp4 -vf "subtitles=input.srt:force_style='FontName=Source Han Sans SC,Fontsize=27,PrimaryColour=&H88FFFFFF&'" -c:a copy -preset fast -crf 22 output.mp4
srt 字幕文件要注意编码方式,直接下载网上的字幕,使用时老是加不上硬字幕,即使在 ffmpeg 加了“-sub_charenc GB18030”参数还是不行,最后把 srt 文件转成 GB18030 编码方式。
FontName 里的名字可以用"fc-list :lang=zh"或"fc-list"命令查看已安装的字体名字。
PrimaryColour=&H88FFFFFF&,88 是字幕透明度(00 到 FF),FFFFFF 字幕颜色。
如果不加 force_style 参数,可能字幕的大小会很少。