FFmpeg 循环推流

  1. ffmpeg -re -stream_loop -1 -i sysj_0QuI4OYme98ha.ts -c copy -f rtsp rtsp://192.168.48.180:8554/mystream
  2. #简单对参数说明
  3. -re 是以流的方式读取
  4. -stream_loop -1 表示无限循环读取(最后那个是数字)
  5. -i 就是输入的文件
  6. -f 格式化输出到哪里

FFmpeg 对设备的查看及使用

  1. ffmpeg -list_devices true -f dshow -i dummy # 查看本机设备列表
  2. ffplay -f dshow -i video="HIK 2K USB CAMERA" # 播放本机设备
  3. ffmpeg -list_options true -f dshow -i video="USB2.0 PC CAMERA" # 查询摄像头信息
  4. ffmpeg -list_options true -f dshow -i audio="麦克风 (2- USB2.0 MIC)" # 查询麦克风信息
  5. # 文件推流 (-flvflags no_duration_filesize 这个参数告诉ffmpeg不要抛出duration_filesize 警告)
  6. ffmpeg -re -i 1.mp4 -f flv -c copy -flvflags no_duration_filesize rtmp://127.0.0.1:1935/live
  7. # 摄像头推流rtmp
  8. 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 查看视频流、音频流信息

  1. ./ffprobe -select_streams a:0 -show_packets -of json 1.ts
  2. 如果是音频,改 -select_streams a
  3. 如果要选择音轨,可以这样 -select_streams a:0

FFmpeg同时推相机视频流和音频流

  1. 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
  2. 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显卡硬件加速进行编解码

  1. 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>
  2. -hwaccel cuvid:指定使用cuvid硬件加速,"dxva2"指定使用D3D进行加速
  3. -hwaccel_device 0 :指定显卡解码
  4. -c:v h264_cuvid: 使用h264_cuvid进行视频解码
  5. -c:v h264_nvenc: 使用h264_nvenc进行视频编码
  6. -c:v h264_amf: 使用h264_amf进行视频编码
  7. -r 120 :视频补帧至120fps
  8. -vf scale_npp=1280:-1:指定输出视频的宽高,注意,这里和软解码时使用的-vf scale=x:x不一样

FFmpeg为视频添加关键帧

  1. //每隔10帧设置一个关键帧,如果是30帧的视频,则代表每秒3个关键帧
  2. ffmpeg -i 2.mp4 -c:v libx264 -x264opts keyint=10 -y keyint10.mp4
  3. //每帧都是关键帧
  4. ffmpeg -i 2.mp4 -c:v libx264 -x264opts keyint=1 -y keyint11.mp4
  5. //每秒一个关键帧
  6. ffmpeg -i 2.mp4 -c:v libx264 -x264opts keyint=30 -y keyint12.mp4
  7. -i 2.mp4 :输入文件
  8. -c:v libx264 :编码器使用libx264
  9. -x264opts keyint=10 :视频文件每隔 10帧设置一个关键帧
  10. -y keyint10.mp4 :输出文件

1. FFMPEG录像

1.1 h264 over rtsp-保存NAL流

  1. ffmpeg -rtsp_transport tcp -i "rtsp://192.168.5.33/ch5001_Stream_main" -c:v copy -f h264 foo.264
  2. 注意在FFMPEG 3.3.2上测试发现,如果-rtsp_transport tcp放到-i "rtsp://192.168.5.33/ch5001_Stream_main"之后,
  3. 会依然使用UDP传输RTP,而不是TCP
  4. 按照时间间隔录像:
  5. ffmpeg -rtsp_transport tcp -i rtsp://admin:trkj88888@192.168.5.248 -codec copy -map 0
  6. -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分钟

  1. ## 如附件:record_rtsp.bat
  2. SET hour=%time:~0,2%
  3. IF "%hour:~0,1%"==" " (
  4. SET hour_prefix=0
  5. ) ELSE (
  6. SET hour_prefix=%hour:~0,1%
  7. )
  8. SET hour=%hour_prefix%%hour:~1,1%
  9. SET timestamp=%date:0,4%%date:5,2%%date:8,2%%hour%%time:3,2%%time:~6,2%
  10. for /l %%x in (1, 1, 10) do (
  11. 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
  12. )


2. FFMPEG解码

2.1 ffplay-列出解码器

ffplay -decoders

2.2 ffplay-列出cuvid相关解码器

ffplay -decoders | grep cuvid
输出

  1. V..... h264_cuvid Nvidia CUVID H264 decoder (codec h264)
  2. V..... hevc_cuvid Nvidia CUVID HEVC decoder (codec hevc)
  3. V..... mjpeg_cuvid Nvidia CUVID MJPEG decoder (codec mjpeg)
  4. V..... mpeg1_cuvid Nvidia CUVID MPEG1VIDEO decoder (codec mpeg1video)
  5. V..... mpeg2_cuvid Nvidia CUVID MPEG2VIDEO decoder (codec mpeg2video)
  6. V..... mpeg4_cuvid Nvidia CUVID MPEG4 decoder (codec mpeg4)
  7. V..... vc1_cuvid Nvidia CUVID VC1 decoder (codec vc1)
  8. V..... vp8_cuvid Nvidia CUVID VP8 decoder (codec vp8)
  9. V..... vp9_cuvid Nvidia CUVID VP9 decoder (codec vp9)


2.3. ffmpeg-列出nvidia相关编码器

ffmpeg -encoders | grep nvenc

输出

  1. V..... h264_nvenc NVIDIA NVENC H.264 encoder (codec h264)
  2. V..... nvenc NVIDIA NVENC H.264 encoder (codec h264)
  3. V..... nvenc_h264 NVIDIA NVENC H.264 encoder (codec h264)
  4. V..... nvenc_hevc NVIDIA NVENC hevc encoder (codec hevc)
  5. 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 音频格式

  1. 转码
    转码为原始YUV

把foo.h265转为foo.yuv
ffmpeg -i foo.h265 foo.yuv

播放YUV
ffplay -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转码,libx264
ffmpeg -i in.h264 -an -vcodec libx264 -g 25 -b:v 2M -f h264 out.h264

视频截断
把视频的第60秒~70秒,截取保存为out.mp4
ffmpeg -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** **

  1. -hls_time 10 //每一个切片长度是10,单位为秒
  2. -hls_list_size 0 //表示ts文件的个数,设置为0表示保存所有分片
  3. -hls_segment_filename //生成ts文件名称
  4. -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
分别设置不同的参数信息。

  1. 处理Extra

    7.1 Extra Data通常是指h264和h265的VPS/SPS/PPS等。

    如果想要去掉Extra和Audio数据如下操作:

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. 保存图片

JPG
ffmpeg -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个JPG
ffmpeg -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即可。

YUV
ffmpeg -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"