ffmpeg推流命令总结

今天考虑一个mcu混合的实现,也就是接收多路过来的rtp流,然后转发出去一路的rtmp流,使用ffmpeg测试做的记录,刚开始一直通过ffmpeg推送的文件流不能满足要求,还是对参数配置不熟悉;


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文件:

SDP:
v=2 
m=video 5004 RTP/AVP 96
a=rtpmap:96 H264
t=0 0 
a=framerate:25
c=IN IP4 192.168.0.100
 
m=audio 5005 RTP/AVP 97
a=rtpmap:97 PCM/8000/1
a=framerate:25
c=IN IP4 192.168.0.100


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的插件:

引入相关资源
    <link href="https://cdn.bootcss.com/video.js/6.3.3/video-js.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/video.js/6.3.3/video.min.js"></script>
    <script src="https://cdn.bootcss.com/videojs-contrib-hls/5.11.0/videojs-contrib-hls.js"></script>
    <!–[if lt IE 9]>
    <script type="text/javascript" src="http://cdn.static.runoob.com/libs/html5shiv/3.7/html5shiv.min.js"></script>
    <![endif]–>
说明:

video-js.min.css 是播放器的主题样式
video.min.js 是video.js的核心代码
videojs-contrib-hls.js 用于支持HLS的库文件
html5shiv.min.js 由于video.js是基于H5构建的播放器,所以在浏览器不支持H5的时候,需要将相关资源引入到浏览器
放置播放器控件
<video  id="myVideo"  class="video-js vjs-default-skin vjs-big-play-centered"  width="400"
        controls="controls" autoplay="autoplay"
       x-webkit-airplay="true" x5-video-player-fullscreen="true"
       preload="auto" playsinline="true" webkit-playsinline
       x5-video-player-typ="h5">
    <source type="application/x-mpegURL" src="https://cn4.creativemas.cn/ppvod/DD7AB8D25F6AD21E4291775FEAC1F710.m3u8">
</video>
说明:

该控件中用于播放一个网络上找的m3u8的视频资源
给控件一个id主要方便video.js获取控件对象
使用video.js
<script>
    // videojs 简单使用
    var myVideo = videojs('myVideo',{
        bigPlayButton : true,
        textTrackDisplay : false,
        posterImage: false,
        errorDisplay : false,
    })
    myVideo.play() // 视频播放
    myVideo.pause() // 视频暂停
</script>

呱牛笔记

请先登录后发表评论
  • 最新评论
  • 总共0条评论