下載ffmpeg
https://ffmpeg.org/download.html
推一個時鐘文字的影片
ffmpeg的指令如下
ffmpeg -f lavfi -i color=c=0x00ff00:s=800x450 -vf "settb=AVTB, setpts='trunc(PTS/1K)*1K+st(1,trunc(RTCTIME/1K))-1K*trunc(ld(1)/1K)', drawtext=text='STREAM2-%{localtime}.%{eif\:1M*t-1K*trunc(t*1K)\:d}':x=100:y=100:fontsize=32:fontcolor=white" -c:v libx264 -f flv rtmp://192.168.189.11/live/test2
- -f lavfi -i color=c=0x00ff00:s=800×450:這部分使用lavfi作為輸入來源,並創建一個顏色填充的視頻流。 c=0x00ff00指定填充的顏色為綠色,s=800×450指定分辨率為 800×450。
- -vf “settb=AVTB, setpts=’trunc(PTS/1K)1K+st(1,trunc(RTCTIME/1K))-1Ktrunc(ld(1)/1K)’, drawtext=text=’STREAM2 -%{localtime}.%{eif\:1Mt-1Ktrunc(t*1K)\:d}’:x=100:y=100:fontsize=32:fontcolor=white”:這部分使用- vf標誌來應用視頻過濾器。其中有兩個主要的過濾器:
- settb=AVTB, setpts=’trunc(PTS/1K)1K+st(1,trunc(RTCTIME/1K))-1Ktrunc(ld(1)/1K)’:這個過濾器設置視頻時間戳。 settb=AVTB設置時間基準,setpts用於計算新的時間戳,其中包括根據PTS(顯示時間戳)和RTCTIME(實時時鐘時間)進行一些計算。
- drawtext=text=’STREAM2-%{localtime}.%{eif\:1Mt-1Ktrunc(t1K)\:d}’:x=100:y=100:fontsize=32:fontcolor=white “:這個過濾器使用drawtext來在視頻上繪製文本。它在視頻左上角繪製了一個文本,其中包含了時間戳信息。%{localtime}插入本地時間,%{eif\:1Mt-1K* trunc(t*1K)\:d}用於插入一個經過格式化的時間戳。
- -c:v libx264:這部分設置視頻編碼器為libx264,用於將視頻編碼為H.264格式。
- -f flv rtmp://192.168.189.11/live/test2:這部分設置輸出格式為FLV,並指定RTMP服務器的地址。視頻會通過RTMP流式傳輸到指定的地址。在這裡,rtmp://192.168.189.11/live/test2是RTMP服務器的地址。
使用虛擬鏡頭來推流
ffmpeg -f dshow -rtbufsize 200M -i video=OBS-Camera -pix_fmt yuv420p -c:v libx264 -profile:v baseline -level:v 3.1 -preset:v ultrafast -s 480x270 -g 240 -an -f flv -y rtmp://172.16.46.89/live/0101_dealerPC1
- -f dshow -rtbufsize 200M -i video=OBS-Camera:這部分設置輸入來源為DirectShow,並指定攝像頭的名稱為 “OBS-Camera”。 -rtbufsize 200M 設置了實時緩衝區的大小為 200MB。
- -pix_fmt yuv420p:這部分設置輸出視頻的像素格式為YUV 4:2:0,這是常見的視頻格式。
- -c:v libx264 -profile:v baseline -level:v 3.1 -preset:v ultrafast:這部分設置視頻編碼器為libx264,使用baseline配置文件,3.1級別,並設置預設(編碼速度)為ultrafast,這意味著編碼速度非常快。
- -s 480×270:這部分設置輸出視頻的分辨率為 480×270,即寬度為480,高度為270。
- -g 240:這部分設置關鍵幀(I幀)之間的間隔為 240 幀,用於控制視頻的GOP結構。
- -an:這部分錶示不捕獲音頻。
- -f flv:這部分設置輸出格式為FLV格式。
- -y:這部分錶示在輸出文件存在時覆蓋已存在的文件。
- rtmp://172.16.46.89/live/0101_dealerPC1:這部分是輸出URL,指定了通過RTMP傳輸的目標地址。視頻將會通過RTMP協議傳輸到 rtmp://172.16.46.89/live/0101_dealerPC1 這個地址。
極低延遲播放串流
ffplay -fflags nobuffer -flags low_delay -rtmp_buffer 0 -rtmp_live live -framedrop -infbuf %desc%
- -fflags nobuffer: 禁用緩衝。這意味著ffplay將盡可能地減少緩衝,以減少播放的延遲。
- -flags low_delay: 啟用低延遲模式。這將優化播放以減少延遲,適用於實時音視頻流。
- -rtmp_buffer 0: 設置 RTMP 緩衝大小為 0。 RTMP 是一種流媒體協議,這個選項設置緩衝大小為 0 表示盡可能地減少緩衝,從而減少延遲。
- -rtmp_live live: 表示要播放的是實時流。
- -framedrop: 如果幀太多,ffplay 將刪除一些幀以避免播放過慢。這有助於保持播放的實時性。
- -infbuf: 禁用緩衝輸入。與 -fflags nobuffer 相似,這有助於減少延遲。
- %desc%: 這可能是一個佔位符,用於指定音視頻流的 URL 或描述符。
把虛擬鏡頭和某個線上串流做綠幕合成
ffmpeg -f dshow -rtbufsize 1M -i video="OBS Virtual Camera" -f flv -i rtmp://172.17.22.89/live/test1 -filter_complex "[0:v]colorkey=0x00ff00:0.3:0.2[keyed];[1:v][keyed]overlay[o]" -map "[o]" -c:v h264_nvenc -f flv rtmp://127.0.0.1/live/test3
- -f dshow: 指定輸入的多媒體設備類型為 DirectShow(Windows 平台上的多媒體框架)。
- -rtbufsize 1M: 設置輸入緩衝區大小為 1MB。這可能有助於減少輸入的延遲。
- -i video=”OBS Virtual Camera”: 指定輸入的視頻設備名稱為 “OBS Virtual Camera”。這是一個虛擬攝像頭,通常由 OBS(Open Broadcaster Software)等軟件創建,用於虛擬攝像頭設備的捕獲。
- -f flv -i rtmp://172.17.22.89/live/test1: 指定輸入的媒體流為 RTMP 流,其 URL 為 rtmp://172.17.22.89/live/test1。這是從另一個 RTMP 流獲取的視頻。
- -filter_complex “[0:v]colorkey=0x00ff00:0.3:0.2[keyed];[1:v][keyed]overlay[o]”: 使用濾鏡複雜處理,這裡進行了以下操作:
- [0:v]colorkey=0x00ff00:0.3:0.2[keyed]:應用顏色鍵(chroma key)效果來移除綠色(0x00ff00)背景。生成一個帶有透明背景的圖像。
[1:v][keyed]overlay[o]:將第一個輸入流(來自虛擬攝像頭)與經過顏色鍵處理的圖像進行疊加,產生混合後的圖像。
-map “[o]”: 從混合後的圖像中選擇 [o] 這個輸出流。 - -c:v h264_nvenc: 使用 NVIDIA GPU 的硬件編碼器 h264_nvenc 進行視頻編碼。這將利用 GPU 進行加速,提高編碼效率。
- -f flv rtmp://172.17.22.89/live/test3: 指定輸出為 RTMP 流,其 URL 為 rtmp://172.17.22.89/live/test3。這是輸出混合後的視頻流。
更多詳細設置串流的方式
set ffmpegBin=C:\apps\ffmpeg\
set PATH=%PATH%;%ffmpegBin%
set camName="OBS Virtual Camera"
set camBufferSize=1000
set desc=rtmp://127.0.0.1:1935/live/demo
set codec=libx264
set fps=24
set /a "keyint=%fps%*5"
set x264opts=keyint=120:min-keyint=%fps%:scenecut=0
set preset=medium
set profile=baseline
set level=3.1
set resolution=800x450
set bitrate=700
:: publish stream
ffmpeg -f dshow -rtbufsize %camBufferSize%M -i video=%camName% ^
-vf format=yuv420p ^
-vcodec %codec% -x264-params %x264opts% ^
-preset %preset% -profile:v %profile% -level:v %level% ^
-tune:v zerolatency ^
-s %resolution% ^
-r %fps% ^
-b:v %bitrate%k -minrate %bitrate%k -maxrate %bitrate%k -bufsize %bitrate%k ^
-an ^
-f flv %desc%
`-r` 轉成多少 fps
`-y` (global) Overwrite output files without asking.
`-i` 輸入檔案
`-c:v` video codec
`-profile:v` video profile, streaming 用 baseline
`-level:v` video level, streaming 用 3.1
`-preset:v` 編碼速度 streaming 用 ultrafast
`-b:v` 設定 bitrate, 例如 700k 486k
`-s` 尺寸
`-g` GOP size (-4 24 -g 240 相當於 Keyframe frequency = 10s)
`-an` 不需要 audio
`-f flv` flv 格式
`-f dshow -i video=OBS-Camera` window 使用 direct show來抓 camera
`-rtbufsize 200M` 設定 buffer size 避免 drop frame
`-re` 串流轉碼會變慢 因為要求 encoder 根據 native frame rate 讀檔按維持品值,要做串流轉發不要延遲時要拿掉。
https://www.wowza.com/docs/how-to-restream-using-ffmpeg-with-wowza-streaming-engine
FFREPORT 環境變數設好 ffmpeg 就會根據設定存log
linux format for date
https://www.opencli.com/linux/linux-date-format-shell-script
偵測 video frame 資訊
取得 stream 資訊
ffprobe -v quiet -show_streams -select_streams v:0 input.flv
抓出所有 i-frame
ffprobe -show_frames input.flv | grep pict_type | grep -n I
FME 設定 24fps, keyframe frequency = 10s
在理想狀況,會每 240 frame 插入一個 i-frame
example:
1:pict_type=I
241:pict_type=I
481:pict_type=I
721:pict_type=I
961:pict_type=I
1201:pict_type=I