看了那麼多別人寫的FFmpeg命令操作,能完成各種各樣的編碼、解碼、錄屏、推流、分流、合流等操作,就是一直看別人寫,然而當要親自寫一個操作命令的時候,卻無法下手,因此還是必須對FFmpeg的命令有一個更清晰的瞭解,瞭解如何創建、需要哪些構成、創建規則、一些常用選項等等,總之要熟悉到可以很容易的創建自己需要的命令。
操作命令示例
ffmpeg -f v4l2 -s 1280x720 -i /dev/video0 -f alsa -i hw:1,0 -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -ab 16000 -ar 22050 -ac 1 -f mp3 -f flv rtmp://192.168.1.102:1935/live0
這個命令的作用是
命令的輸出信息如下:
ffmpeg version 4.0.2 Copyright (c) 2000-2018 the FFmpeg developers
built with gcc 5.4.0 (Ubuntu 5.4.0-6ubuntu1~16.04.9) 20160609
configuration: --prefix=/usr/local --enable-shared --enable-libx264 --enable-libopencv --enable-gpl
libavutil 56. 14.100 / 56. 14.100
libavcodec 58. 18.100 / 58. 18.100
libavformat 58. 12.100 / 58. 12.100
libavdevice 58. 3.100 / 58. 3.100
libavfilter 7. 16.100 / 7. 16.100
libswscale 5. 1.100 / 5. 1.100
libswresample 3. 1.100 / 3. 1.100
libpostproc 55. 1.100 / 55. 1.100
Input #0, video4linux2,v4l2, from '/dev/video0':
Duration: N/A, start: 688590.974857, bitrate: 110592 kb/s
Stream #0:0: Video: rawvideo (YUY2 / 0x32595559), yuyv422, 640x360, 110592 kb/s, 30 fps, 30 tbr, 1000k tbn, 1000k tbc
Guessed Channel Layout for Input Stream #1.0 : stereo
Input #1, alsa, from 'hw:1,0':
Duration: N/A, start: 1561430261.799069, bitrate: 1024 kb/s
Stream #1:0: Audio: pcm_s16le, 32000 Hz, stereo, s16, 1024 kb/s
Stream mapping:
Stream #0:0 -> #0:0 (rawvideo (native) -> h264 (libx264))
Stream #1:0 -> #0:1 (pcm_s16le (native) -> adpcm_swf (native))
Press [q] to stop, [?] for help
[video4linux2,v4l2 @ 0x16ae480] Thread message queue blocking; consider raising the thread_queue_size option (current value: 8)
[libx264 @ 0x16d6d40] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 AVX2 LZCNT BMI2
[libx264 @ 0x16d6d40] profile High 4:2:2, level 3.0, 4:2:2 8-bit
[libx264 @ 0x16d6d40] 264 - core 148 - H.264/MPEG-4 AVC codec - Copyleft 2003-2016 - http://www.videolan.org/x264.html
- options: cabac=0 ref=1 deblock=0:0:0 analyse=0:0 me=dia subme=0 psy=1 psy_rd=1.00:0.00 mixed_ref=0 me_range=16
chroma_me=1 trellis=0 8x8dct=0 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=0 threads=5 lookahead_threads=5
sliced_threads=1 slices=5 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=0 weightp=0
keyint=250 keyint_min=25 scenecut=0 intra_refresh=0 rc=crf mbtree=0 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4
ip_ratio=1.40 aq=0
[alsa @ 0x16b0900] Thread message queue blocking; consider raising the thread_queue_size option (current value: 8)
Output #0, flv, to 'rtmp://192.168.1.102:1935/live0':
Metadata:
encoder : Lavf58.12.100
Stream #0:0: Video: h264 (libx264) ([7][0][0][0] / 0x0007), yuv422p(progressive), 640x360, q=-1--1, 30 fps, 1k tbn, 30 tbc
Metadata:
encoder : Lavc58.18.100 libx264
Side data:
cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: -1
Stream #0:1: Audio: adpcm_swf ([1][0][0][0] / 0x0001), 22050 Hz, mono, s16, 88 kb/s
Metadata:
encoder : Lavc58.18.100 adpcm_swf
[flv @ 0x16d0740] Failed to update header with correct duration.ate= 842.7kbits/s speed=1.02x
[flv @ 0x16d0740] Failed to update header with correct filesize.
frame= 1028 fps= 30 q=24.0 Lsize= 3664kB time=00:00:35.29 bitrate= 850.4kbits/s speed=1.01x
video:3245kB audio:382kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 1.002358%
[libx264 @ 0x16d6d40] frame I:5 Avg QP:18.80 size: 33174
[libx264 @ 0x16d6d40] frame P:1023 Avg QP:21.69 size: 3086
[libx264 @ 0x16d6d40] mb I I16..4: 100.0% 0.0% 0.0%
[libx264 @ 0x16d6d40] mb P I16..4: 3.0% 0.0% 0.0% P16..4: 45.6% 0.0% 0.0% 0.0% 0.0% skip:51.4%
[libx264 @ 0x16d6d40] coded y,uvDC,uvAC intra: 30.6% 55.9% 12.7% inter: 14.8% 19.7% 1.0%
[libx264 @ 0x16d6d40] i16 v,h,dc,p: 18% 52% 18% 11%
[libx264 @ 0x16d6d40] i8c dc,h,v,p: 45% 33% 13% 9%
[libx264 @ 0x16d6d40] kb/s:775.72
Exiting normally, received signal 2.
輸出了這麼一大串,都是些什麼鬼?
命令解釋
總的來說以上的命令示例含義是:獲取v4l2設備/dev/video0的視頻分辨率是1280*720,獲取alsa設備hw:1,0的音頻,音頻採樣參數爲單聲道16K;視頻採用libx264編碼爲H264幀,音頻採用MP3編碼,音頻編碼參數爲雙聲道,22050採樣率;然後將視頻與音頻合成爲flv格式的音視頻流,通過rtmp方式推送。
命令選項 | 命令參數 | 命令釋義 |
---|---|---|
-f | v4l2 | -f 是個很常用的選項,指示一個設備類型,或者文件的格式,dshow來表示Windows的音視頻設備 |
-s | 1280*720 | 用於指示視頻的分辨率 |
-i | /dev/video0 | -i 選項用於指示一個數據輸入源的設備或者具體的音視頻文件 |
-f | alsa | 指示Linux下的音頻設備類型 |
-i | hw:1,0 | 指示Linux下的ALSA類型音頻設備 |
-vcodec | libx264 | 指示一個視頻編碼器 |
-preset:v | ultrafast | x264編碼器預設參數,ultrafast表示最快的編碼方式 |
-tune:v | zerolatency | 編碼調優參數,zerolatency表示無延遲 |
-ab | 16000 | 表示音頻的碼率 |
-ar | 22050 | 表示音頻的採樣率 |
-ac | 1 | 音頻採樣通道數 |
-f | mp3 | 文件格式MP3 |
-f | flv | 文件格式flv |
簡單介紹一下命令行中輸出的信息:
- FFmpeg首先輸出編譯這個FFmpeg命令時的編譯選項、gcc版本、庫版本等信息
Input #0
:表示第一個輸入文件,是v4l2
格式的/dev/video0
設備文件Stream #0:0
:表示第一個輸入文件的第一個輸入流Input #1, alsa, from 'hw:1,0'
:表示第二個輸入文件,格式爲alsa
,設備是hw:1,0
,這種設備格式,是alsa
的設備選擇方式Stream #1:0: Audio: pcm_s16le, 32000 Hz, stereo, s16, 1024 kb/s
:表示音頻數據格式pcm,16bit,小端存儲方式,採樣率爲32K,stereo表示雙聲道,碼率是1024kb/sStream mapping
:給出了輸入與輸出流之間的映射關係,仔細看其後面的Stream #0:0
與Stream #1:0
的輸出信息,就明白兩個輸入流的要經過怎樣的處理,本例中Stream #0:0
原生視頻流要被編碼成H264
視頻流,Stream #1:0
原生音頻流,轉換成adpcm_swf
可被flv
識別的音頻流,並未經過音頻編碼[video4linux2,v4l2 @ 0x16ae480]
:表示通過v4l2
操作,讀取視頻流的線程輸出的相關信息,大致意思是,線程消息隊列被阻塞,考慮提升當前線程的消息隊列數量,當前值是8[libx264 @ 0x16d6d40]
:這是libx264編碼庫輸出的信息,主要是檢查當前CPU下可提供的編碼能力,H264編碼profile、level選擇,編碼參數選項等信息[alsa @ 0x16b0900]
:音頻處理線程的輸出信息,基本與視頻線程輸出信息一致Output #0, flv, to 'rtmp://192.168.1.102:1935/live0'
:表示輸出文件的格式,目標文件是一個rtmp
網絡流
Stream #0:0: Video: h264 (libx264) ([7][0][0][0] / 0x0007), yuv422p(progressive), 640x360, q=-1--1, 30 fps, 1k tbn, 30 tbc
:表示輸出文件的第1個索引的流信息,h264
,並給出基本的視頻分辨率,幀率等信息
Stream #1:0:Audio: adpcm_swf ([1][0][0][0] / 0x0001), 22050 Hz, mono, s16, 88 kb/s
:表示輸出文件的第2個索引的流信息,audio
,格式adpcm_swf
,[flv @ 0x16d0740]
:輸出文件flv
,音視頻合成muxer
的輸出信息,主要關注文件的總體碼率、幀率等信息[libx264 @ 0x16d6d40]
:後續輸出一些在進行H264編碼時的狀態信息,主要是一些統計信息
FFmpeg命令創建規則
要理解一條FFmpeg命令,我們首先應該知道FFmpeg命令由那幾部分組成,每一部分的用途,有哪些選項、參數可供使用等;命令的格式,選項與參數如何表示、關聯關係等,只有明白這些之後才能很好的理解一條FFmpeg命令。
FFmpeg命令組成
FFmpeg的命令由簡到繁,主要包含以下以幾個部分
- FFmpeg的信息查詢:主要用於查詢編碼器、解碼器、合成器、分解器等版本、支持的操作參數等信息
- FFmpeg的公用操作部分:主要是封裝、格式轉換、編碼、解碼等都可以使用的參數
- 文件操作:主要用於指定輸入文件、輸出文件、文件類型、文件格式
- 音頻操作:主要用於指定音頻的格式、採樣、量化、編碼、解碼、合成、提取等操作
- 視頻操作:主要用於指定視頻的格式、分辨率、幀率、編碼、解碼、合成、提取等操作
- 字幕操作:主要用於指定字幕的格式、文件,將字幕合成到視頻,或者從視頻中提取字幕
一個完整的FFmpeg操作命令,包含以上一個或多個部分。
FFmpeg命令基本格式與規則
ffmpeg [全局選項] {[輸入文件選項] -i 輸入文件} ... {[輸出文件選項] 輸出文件} ...
- 命令格式中
[]
括號內的內容爲可選項,可有可無 - 命令格式中
{}
括號內的內容爲必選項,必須存在 - 命令中必須至少包含一個輸入文件、一個輸出文件;可以同時存在多個輸入文件、或者輸出文件
- 命令中輸入文件必須用
-i
選項指定,輸出文件無須用選項指定 - 任何在命令中不能被解釋爲選項、參數的信息,都將被作爲輸出文件
- 每個輸入或輸出文件都可包含數量不同的數據流(視頻/音頻/字幕/附件/數據等),具體文件中包含流的數量、數據類型是文件的容器格式限定的,即我們看到的文件後綴名
- 具體選擇那些流從輸入文件到輸出文件,是自動或者依據
-map
選項來指定 - 輸入與輸出文件的索引從
0
開始,同理一個輸入與輸出文件中的流索引也是從0
開始 - 命令的規則中,選項位於其作用的輸入或者輸出文件之前,且只能作用於一個輸入或者輸出文件,若需要作用於其它輸入與輸出文件,必須重複指定選項
- 命令必須先指定輸入文件,當有多個輸入輸出文件時,輸入文件指定完畢之後才能指定輸出文件
- 以上規則也適用於
ffplay
、ffproble
命令
FFmpeg常用參數選項
命令選項 | 命令釋義 |
---|---|
-f | -f 是個很常用的選項,指示一個設備類型,或者文件的格式,dshow來表示Windows的音視頻設備 |
-s | 設置視頻的分辨率 |
-ss | 設置命令動作開始時間 |
-t | 設置命令操作時間長度 |
-i | -i 選項用於指示一個數據輸入源的設備或者具體的音視頻文件,可以與-i 聯合指定一個設備文件 |
-vcodec | 指示一個視頻編碼器 |
-acodec | 指示一個視頻編碼器 |
-b | 設置音頻與視頻加起來的碼率,可以用b:a 設置音頻碼率,b:v 設置視頻碼率 |
-ab | 設置音頻碼率 |
-ar | 設置音頻採樣率 |
-ac | 設置音頻通道數 |
-r | 設置視頻幀率 |
-g | 設置視頻GOP數值 |
-bf | 設置視頻連續編碼爲B幀的個數 |
-an | 設置禁用音頻 |
-vn | 設置禁用視頻 |
-aspect | 設置視頻畫面寬高比,一般是4:3,16:9等 |
ffpaly命令
新版本的FFMpeg源碼需要SDL-2.0的支持,才能編譯出ffplay
工具,其主要是一個播放器,用於播放多媒體文件,同時可以查看視頻圖像的運動方向估計,音頻數據的波形。
ffplay
不僅可以用作播放器,還可以測試FFmpeg的codec引擎、format引擎、filter引擎的工具
ffplay
命令的常用選項如下:
命令選項 | 命令釋義 |
---|---|
-formats | 列出所有可用的格式 |
-muxers | 列出所有的複用器 |
-demuxers | 列出所有的解複用器 |
-devices | 顯示所有設備 |
-codecs | 顯示所有編解碼 |
-decoders | 顯示所有解碼器 |
-encoders | 顯示所有編碼器 |
-protocols | 顯示所有協議 |
-filters | 顯示所有濾鏡 |
-pix_fmts | 顯示所有像素格式 |
-layouts | 顯示標準channel佈局 |
-sample_fmts | 設置音頻採樣格式 |
-loglevel | 設置日誌登記 |
-x | 設置視頻顯示寬度 |
-y | 設置視頻顯示高度 |
-ast | 設置將要播放的音頻流 |
-vst | 設置將要播放的視頻流 |
-sst | 設置將要播放的字幕流 |
-stats | 輸出多媒體播放狀態 |
-fast | 非標準的多媒體播放優化 |
-sync | 設置音視頻同步,可根據音頻、視頻、外部時鐘進行同步 |
-autoexit | 多媒體播放完畢後自動退出,默認不自動退出 |
-exitonkeydown | 任意按鍵按下,播放器退出 |
-exitonmousedown | 鼠標鍵按下,播放器退出 |
-loop | 設置循環播放次數 |
-framedrop | CPU佔用過高時,自動丟幀 |
-infbuf | 設置無極限的播放器buffer,主要用於播放實時流媒體 |
-vf | 設置視頻濾鏡 |
-acodec | 設置音頻解碼器 |
-vcodec | 設置視頻解碼器 |
-scodec | 設置字幕解碼器 |
命令示例
ffpaly -ss 30 -t 10 input.mp4
:從輸入文件的第30S開始播放,播放時長爲10Sffpaly showmode 1 input.mp3
:將輸入的音頻MP3文件,以波形的方式進行播放ffplay input.mp4 -vf codecview=mv=pf+bf+bb
:查看B幀和P幀預測信息
ffprobe命令
ffprobe
命令工具主要用於查看多媒體文件的信息,其參數選項大部分與ffpaly
命令一致,這裏僅列出我們跟關心的不同的參數選項:
命令選項 | 命令釋義 |
---|---|
-print_format | 設置輸出信息的打印格式 |
-select_streams | 選擇流 |
-show_data | 顯示packet的數據 |
-show_format | 顯示容器(即多媒體文件格式)的信息 |
-show_frames | 顯示幀信息,解碼前 |
-show_packets | 顯示數據包信息,解碼後 |
-count_frames | 計算幀數量 |
-count_packts | 計算包數量 |
命令示例
ffprobe -show_packets input.flv
:探測輸入文件的包信息ffprobe -show_packets -show_data input.flv
:選項配合,顯示更精確的信息ffprobe -show_format input.flv
:探測輸入文件的封裝信息
以上就是關於FFmpeg命令的創建於規則的解析,至此我大概明白了FFmpeg的命令該如何使用,希望對感興趣的小夥伴有點用。