FFmpeg 循环推流
ffmpeg -re -stream_loop -1 -i sysj_0QuI4OYme98ha.ts -c copy -f rtsp rtsp://192.168.48.180:8554/mystream
#简单对参数说明
-re 是以流的方式读取
-stream_loop -1 表示无限循环读取(最后那个是数字)
-i 就是输入的文件
-f 格式化输出到哪里
FFmpeg 对设备的查看及使用
ffmpeg -list_devices true -f dshow -i dummy # 查看本机设备列表
ffplay -f dshow -i video="HIK 2K USB CAMERA" # 播放本机设备
ffmpeg -list_options true -f dshow -i video="USB2.0 PC CAMERA" # 查询摄像头信息
ffmpeg -list_options true -f dshow -i audio="麦克风 (2- USB2.0 MIC)" # 查询麦克风信息
# 文件推流 (-flvflags no_duration_filesize 这个参数告诉ffmpeg不要抛出duration_filesize 警告)
ffmpeg -re -i 1.mp4 -f flv -c copy -flvflags no_duration_filesize rtmp://127.0.0.1:1935/live
# 摄像头推流rtmp
ffmpeg -f dshow -i video="USB2.0 PC CAMERA" -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -f flv rtmp://127.0.0.1:1935/live/123
FFmpeg 查看视频流、音频流信息
./ffprobe -select_streams a:0 -show_packets -of json 1.ts
如果是音频,改 -select_streams a
如果要选择音轨,可以这样 -select_streams a:0
FFmpeg同时推相机视频流和音频流
ffmpeg -f dshow -i video="USB2.0 PC CAMERA" -f dshow -i audio="麦克风 (2- USB2.0 MIC)" -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -f flv rtmp://127.0.0.1:1935/live/123
ffmpeg -f dshow -i video="USB2.0 PC CAMERA":audio="麦克风 (2- USB2.0 MIC)" -vcodec libx264 -r 25 -preset:v ultrafast -tune:v zerolatency -f flv rtmp://127.0.0.1:1935/live/123
FFmpeg指定NVIDIA显卡硬件加速进行编解码
ffmpeg -hwaccel cuvid -hwaccel_device 0 -c:v h264_cuvid -i <input> -c:v h264_nvenc -r 120 -b:v 2048k -vf scale_npp=1280:-1 -y <output>
-hwaccel cuvid:指定使用cuvid硬件加速,"dxva2"指定使用D3D进行加速
-hwaccel_device 0 :指定显卡解码
-c:v h264_cuvid: 使用h264_cuvid进行视频解码
-c:v h264_nvenc: 使用h264_nvenc进行视频编码
-c:v h264_amf: 使用h264_amf进行视频编码
-r 120 :视频补帧至120fps
-vf scale_npp=1280:-1:指定输出视频的宽高,注意,这里和软解码时使用的-vf scale=x:x不一样
FFmpeg为视频添加关键帧
//每隔10帧设置一个关键帧,如果是30帧的视频,则代表每秒3个关键帧
ffmpeg -i 2.mp4 -c:v libx264 -x264opts keyint=10 -y keyint10.mp4
//每帧都是关键帧
ffmpeg -i 2.mp4 -c:v libx264 -x264opts keyint=1 -y keyint11.mp4
//每秒一个关键帧
ffmpeg -i 2.mp4 -c:v libx264 -x264opts keyint=30 -y keyint12.mp4
-i 2.mp4 :输入文件
-c:v libx264 :编码器使用libx264
-x264opts keyint=10 :视频文件每隔 10帧设置一个关键帧
-y keyint10.mp4 :输出文件
1. FFMPEG录像
1.1 h264 over rtsp-保存NAL流
ffmpeg -rtsp_transport tcp -i "rtsp://192.168.5.33/ch5001_Stream_main" -c:v copy -f h264 foo.264
注意在FFMPEG 3.3.2上测试发现,如果-rtsp_transport tcp放到-i "rtsp://192.168.5.33/ch5001_Stream_main"之后,
会依然使用UDP传输RTP,而不是TCP。
按照时间间隔录像:
ffmpeg -rtsp_transport tcp -i rtsp://admin:trkj88888@192.168.5.248 -codec copy -map 0
-f segment -segment_time 10 -segment_format mp4 "device-19-%03d.mp4"
1.2 h264 over rtsp-保存为MP4封装
ffmpeg -rtsp_transport tcp -i "rtsp://admin:trkj88888@192.168.5.64:554/Streaming/Channels/101?transportmode=unicast&profile=Profile_1" -c:v copy -f mp4 foo.mp4
1.3 mpeg4 over rtsp-保存为MP4封装
和上面一样
1.4 h264文件封装为MP4文件
ffmpeg -i "foo.h264" -c:v copy -f mp4 foo.mp4
1.5 解封装MP4文件为h264文件
ffmpeg -i foo.mp4 -c:v copy -f h264 foo.h264
1.6 10次循环录像,每个录像文件10分钟
## 如附件:record_rtsp.bat
SET hour=%time:~0,2%
IF "%hour:~0,1%"==" " (
SET hour_prefix=0
) ELSE (
SET hour_prefix=%hour:~0,1%
)
SET hour=%hour_prefix%%hour:~1,1%
SET timestamp=%date:0,4%%date:5,2%%date:8,2%%hour%%time:3,2%%time:~6,2%
for /l %%x in (1, 1, 10) do (
ffmpeg.exe -rtsp_transport tcp -i "rtsp://192.168.5.4:554/ch5001_Stream_sub" -acodec copy -vcodec copy -ss 00:00:00 -t 00:10:00 record%timestamp%%%x.h264
)
2. FFMPEG解码
2.1 ffplay-列出解码器
ffplay -decoders
2.2 ffplay-列出cuvid相关解码器
ffplay -decoders | grep cuvid
输出
V..... h264_cuvid Nvidia CUVID H264 decoder (codec h264)
V..... hevc_cuvid Nvidia CUVID HEVC decoder (codec hevc)
V..... mjpeg_cuvid Nvidia CUVID MJPEG decoder (codec mjpeg)
V..... mpeg1_cuvid Nvidia CUVID MPEG1VIDEO decoder (codec mpeg1video)
V..... mpeg2_cuvid Nvidia CUVID MPEG2VIDEO decoder (codec mpeg2video)
V..... mpeg4_cuvid Nvidia CUVID MPEG4 decoder (codec mpeg4)
V..... vc1_cuvid Nvidia CUVID VC1 decoder (codec vc1)
V..... vp8_cuvid Nvidia CUVID VP8 decoder (codec vp8)
V..... vp9_cuvid Nvidia CUVID VP9 decoder (codec vp9)
2.3. ffmpeg-列出nvidia相关编码器
ffmpeg -encoders | grep nvenc
输出
V..... h264_nvenc NVIDIA NVENC H.264 encoder (codec h264)
V..... nvenc NVIDIA NVENC H.264 encoder (codec h264)
V..... nvenc_h264 NVIDIA NVENC H.264 encoder (codec h264)
V..... nvenc_hevc NVIDIA NVENC hevc encoder (codec hevc)
V..... hevc_nvenc NVIDIA NVENC hevc encoder (codec hevc)
2.4 ffplay 3.3.2-Nvidia显卡解码h264视频
ffplay -vcodec h264_cuvid -rtsp_transport tcp -i "rtsp://admin:trkj88888@192.168.5.249:554/Streaming/Channels/10 1?transportmode=unicast&profile=Profile_1" -x 1200 -y 600
2.5 ffplay低延迟播放RTSP
ffplay -fflags nobuffer -rtsp_transport tcp -i "rtsp://admin:trkj88888@192.168.5.248:554/Streaming/Channels/101?transportmode=unicast&profile=Profile_1" -x 1200 -y 600
3. 播放
3.1 播放YUV文件
I420格式:ffplay -f rawvideo -video_size 1920x1080 foo.yuv
yuv420格式:ffplay -f rawvideo -video_size 5760x1080 -pix_fmt yuv420p foo.yuv
NV12格式:ffplay -f rawvideo -pix_fmt nv12 -video_size 5760*1080 foo.yuv -x 1500 -y 600
3.2 缩放YUV
ffmpeg -s:v 1920x1080 -r 25 -i HeavyHand_1080p.yuv -vf scale=5760:1080 -c:v rawvideo -pix_fmt yuv420p foo_output.yuv
3.3 播放pcm文件
ffplay -ar 44100 -ac 2 -f s16le -i audio1.pcm
-ar 采样率
-ac 通道数
-f 音频格式
- 转码
转码为原始YUV
把foo.h265转为foo.yuvffmpeg -i foo.h265 foo.yuv
播放YUVffplay -f rawvideo -video_size 5760x4320 foo.yuv -x 800 -y 600
转码MP4-降低码率
通过OBS做视频,用剪映添加字幕后,发现3分钟视频变得很大,下面用ffmpeg降视频码率为300Kbps,并保持音频不变:ffmpeg -i source.mp4 -acodec copy -b:v 0.3M dst.mp4
降延时,减少GOP长度
GPU转码,用nvidia显卡ffmpeg -i in.h264 -an -vcodec h264_nvenc -g 25 -b:v 2M -f h264 out.h264
CPU转码,libx264ffmpeg -i in.h264 -an -vcodec libx264 -g 25 -b:v 2M -f h264 out.h264
视频截断
把视频的第60秒~70秒,截取保存为out.mp4ffmpeg -ss 00:01:00.000 -t 10 -i in.mp4 -codec copy out.mp4
5. 编码
ffmpeg -s 5760x1080 -pix_fmt yuv420p -i foo.yuv -r 25 foo.h264
6. 推流
6.1. 推送h264文件到TCP端口、并关闭音频
ffmpeg -re -i "d://a.h264" -c:v copy -an -f h264 tcp://127.0.0.1:14011
6.2. 推送h265文件到TCP端口:
ffmpeg -re -stream_loop -1 -i "d://ch5001_Stream_main_20180927_093305.h265" -c:v copy -f hevc tcp://127.0.0.1:14011
6.3. RTSP->FFMPEG->TS
接收RTSP,转为MPEG TS:ffmpeg -fflags nobuffer -rtsp_transport tcp -i "rtsp://admin:trkj88888@192.168.5.248" -c copy -f mpegts tcp://127.0.0.1:9000
播放:ffplay -i "tcp://127.0.0.1:9000?listen=1" -f mpegts -x 1920 -y 1080
6.4. RTSP->FFMPEG->RTP
接收RTSP,转为RTP:ffmpeg -rtsp_transport tcp -i "rtsp://admin:trkj88888@192.168.5.248" -an -c copy -f rtp rtp://192.168.5.188:14011 -sdp_file live.sdp
播放:ffplay -protocol_whitelist “file,rtp,udp” -i live.sdp -x 1920 -y 1080
6.5. RTSP->FFMPEG->HLS,HLS直播
ffmpeg -rtsp_transport tcp -i rtsp://192.168.1.2 -codec copy -f hls -hls_time 5 -hls_list_size 10 -hls_flags delete_segments live.m3u8
实现如下功能:
rtsp转为hls,codec不变
每个ts文件5秒
m3u8中提供10个ts的引用
当ts文件过期于整个m3u8播放列表的时长时,删除该ts文件
6.6 flv -> m3u8
** **ffmpeg -i "323050694-1-112.flv" -hls_time 10 -hls_list_size 0 -hls_segment_filename ./hls/sanyue_%05d.ts ./hls/index.m3u8** **
-hls_time 10 //每一个切片长度是10,单位为秒
-hls_list_size 0 //表示ts文件的个数,设置为0表示保存所有分片
-hls_segment_filename //生成ts文件名称
-single_file // 表示生成一个文件,1表示开启,0表示关闭
6.7 HLS多路分辨率不同的流
ffmpeg -threads 2 -i "323050694-1-112.flv" -c:v:0 libx264 -s:0 1920x1080 -profile:v:0 main -c:a:0 aac -ac 2 -b:v:0 2000k -b:a:0 128k -maxrate:0 2000k -bufsize:0 4000k -r 24 -ar 44100 -g 48 -c:v:1 libx264 -s:2 1280x720 -profile:v:1 main -c:a:0 aac -ac 2 -b:v:1 1000k -b:a:1 128k -maxrate:2 1000k -bufsize:2 2000k -r 24 -ar 44100 -g 48 -c:v:2 libx264 -s:4 720x480 -profile:v:2 main -c:a:0 aac -ac 2 -b:v:2 600k -b:a:2 128k -maxrate:4 600k -bufsize:4 1000k -r 24 -ar 44100 -g 48 -map 0:v -map 0:a -map 0:v -map 0:a -map 0:v -map 0:a -f hls -var_stream_map "v:0,a:0 v:1,a:1 v:2,a:2" -hls_segment_type mpegts -start_number 10 -hls_time 10 -hls_list_size 0 -hls_start_number_source 1 -master_pl_name "index.m3u8" -hls_segment_filename ./hls/sanyue_%v-%09d.ts ./hls/index_%v.m3u8
分别设置不同的参数信息。
ffmpeg -i 5760x4320_xy.h265 -vbsf remove_extra -vcodec copy -an 5760x4320_xy_no_extra.h265
-vbsf
表示bitstream filters , ffmpeg -bsfs
可查看支持的过滤器列表:
aac_adtstoasc
chomp
dump_extra
dca_core
extract_extradata
h264_mp4toannexb
hevc_mp4toannexb
imxdump
mjpeg2jpeg
mjpegadump
mp3decomp
mpeg4_unpack_bframes
mov2textsub
noise
remove_extra
text2movsub
vp9_superframe
7.2 把已有的Extra Data,加到每个关键帧
ffmpeg -i 5760x4320_xy.h265 -vbsf dump_extra=freq=keyframe -vcodec copy -an 5760x4320_xy_no_extra.h265
7.3 去掉每个GOP都带的VPS/SPS/PPS
从文件中提取VPS/SPS/PPS
到独立文件:dd if=5760x4320_xy.h265 of=5760x4320_extra.h265 count=1 bs=95
从文件中移除所有VPS/SPS/PPS
到独立文件:ffmpeg -i 5760x4320_xy.h265 -vbsf remove_extra -vcodec copy -an 5760x4320_xy_no_extra.h265
合并5760x4320_extra.h265和5760x4320_xy_no_extra.h265
。
参考:ffmpeg-bitstream-filters
7.4. 打印每一帧信息
ffmpeg -i -c:v copy -bsf:v trace_headers -f null -
7.5. h264加入SEI
ffmpeg -i original.mp4 -c copy -bsf:v h264_metadata=sei_user_data='086f3693-b7b3-4f2c-9653-21492feee5b8+hello' file_with_h264_metadata.mp4
8. 直播方案
8.1 rtsp to m3u8/ts,支持文件名和目录的时间戳
ffmpeg -rtsp_transport tcp -i rtsp://admin:trkj88888[@192.168.5.234 ](/192.168.5.234 ) -hls_time 5 -hls_list_size 3 -strftime 1 -strftime_mkdir 1 -hls_segment_filename 'd://leopard/record/device_19/%Y%m%d/device_19-%Y%m%d_%H%M%S.ts' -f hls d://leopa rd/record/device_19/out.m3u8
8.2 rtsp to mp4
ffmpeg -rtsp_transport tcp -i rtsp://admin:trkj88888[@192.168.5.248 ](/192.168.5.248 ) -codec copy -map 0 -f segment -segment_time 10 -segment_format mp4 "device-19-%03d.mp4"
遗留问题
-f segment
形式时无法利用-fs 102400来指定文件长度。-f hls
则既可以按照时间,也可以按照文件长度,考虑中。
9. 转码
把a.h264文件转码为分辨率640x360的sub.h264文件。ffmpeg -i a.h264 -vcodec libx264 -s 640x360 -preset ultrafast sub.h264
10. 保存图片
JPGffmpeg -rtsp_transport tcp -i rtsp://admin:trkj88888[@192.168.5.250 ](/192.168.5.250 ) -f image2 -vframes 1 -y 250.jpg
-y表示强制覆盖已存在的250.jpg。
10个JPGffmpeg -rtsp_transport tcp -i rtsp://admin:trkj88888[@192.168.5.250 ](/192.168.5.250 ) -f image2 -vframes 10 -y 250_%d.jpg
BMP
修改上面命令中后缀为.bmp即可。
YUVffmpeg -rtsp_transport tcp -i rtsp://admin:trkj88888[@192.168.5.250 ](/192.168.5.250 ) -f image2 -vframes 1 -y 250.y
除250.y之外,还会产生250.u和250.v。
11. 合并MP4文件
ffmpeg -i 1.mp4 -i 2.mp4 -filter_complex "[0:v:0][0:a:0][1:v:0][1:a:0]concat=n=2:v=1:a=1[outv][outa]" -map "[outv]" -map "[outa]" output.mp4
其他方式如ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.mp4
等要么只有第一个文件,要么音频混淆了。
12. 播放
12.1. [4倍速]
ffplay -f h264 file.264 -vf "setpts=0.25*N/FRAME_RATE/TB"
12.2. [1/4倍速]
ffplay -f h264 file.264 -vf "setpts=4*N/FRAME_RATE/TB"