ffmpeg視頻直播編解碼流程

去年最流行的非視頻直播莫屬,出現了幾百家的直播平臺,畢竟自己也是在直播平臺做開發的,然後就寫一篇關於直播的文章。這裡只說流程,具體的實現就不說了,應付面試應該還是可以的。


先上一張簡單的流程圖:

ffmpeg視頻直播編解碼流程

上面這張圖就是視頻直播的流程圖,想要開發一款自己的視頻直播軟件不麻煩,現在有好多直播sdk,比如騰訊視頻雲,金山視頻雲,易視雲,7牛視頻雲,等等,使用它們的sdk能很快的開發一款自己的視頻直播軟件,個人推薦使用易視雲,定製化你想要的視頻直播軟件,上面流程圖只是說的表面流程,下面說一些涉及到的技術上面一些流程。

不管是哪個視頻雲sdk都是使用的ffmpeg開源的這個庫,這個庫很強大,強大到無所不能,不管是android還是ios還是pc的音視頻的編碼解碼都是用的這個庫,先說一下使用這個庫的編碼也就是音視頻數據的壓縮流程:

下面附一張使用FFmpeg編碼視頻的流程圖。使用該流程,不僅可以編碼H.264的視頻,而且可以編碼MPEG4/MPEG2/VP8等等各種FFmpeg支持的視頻。

ffmpeg視頻直播編解碼流程

簡單介紹一下流程中各個函數的意義:

av_register_all():註冊FFmpeg所有編解碼器。

avformat_alloc_output_context2():初始化輸出碼流的AVFormatContext。

avio_open():打開輸出文件。

av_new_stream():創建輸出碼流的AVStream。

avcodec_find_encoder():查找編碼器。

avcodec_open2():打開編碼器。

avformat_write_header():寫文件頭(對於某些沒有文件頭的封裝格式,不需要此函數。比如說MPEG2TS)。

avcodec_encode_video2():編碼一幀視頻。即將AVFrame(存儲YUV像素數據)編碼為AVPacket(存儲H.264等格式的碼流數據)。

av_write_frame():將編碼後的視頻碼流寫入文件。

flush_encoder():輸入的像素數據讀取完成後調用此函數。用於輸出編碼器中剩餘的AVPacket。

av_write_trailer():寫文件尾(對於某些沒有文件頭的封裝格式,不需要此函數。比如說MPEG2TS)

下面說一下音視頻的解碼(解壓縮)的流程:

ffmpeg視頻直播編解碼流程

ffmpeg 總結

結構

簡介

FFmpeg的名稱來自MPEG視頻編碼標準,前面的“FF”代表“Fast Forward”,FFmpeg是一套可以用來記錄、轉換數字音頻、視頻,並能將其轉化為流的開源計算機程序。可以輕易地實現多種視頻格式之間的相互轉換。

FFmpeg的用戶有Google,Facebook,Youtube,優酷,愛奇藝,土豆等。

組成

1、libavformat:用於各種音視頻封裝格式的生成和解析,包括獲取解碼所需信息以生成解碼上下文結構和讀取音視頻幀等功能,包含demuxers和muxer庫;

2、libavcodec:用於各種類型聲音/圖像編解碼;

3、libavutil:包含一些公共的工具函數;

4、libswscale:用於視頻場景比例縮放、色彩映射轉換;

5、libpostproc:用於後期效果處理;

6、ffmpeg:是一個命令行工具,用來對視頻文件轉換格式,也支持對電視卡實時編碼;

7、ffsever:是一個HTTP多媒體實時廣播流服務器,支持時光平移;

8、ffplay:是一個簡單的播放器,使用ffmpeg 庫解析和解碼,通過SDL顯示;

術語

容器(Container)

容器就是一種文件格式,比如flv,mkv等。包含下面5種流以及文件頭信息。

流(Stream)

是一種視頻數據信息的傳輸方式,5種流:音頻,視頻,字幕,附件,數據。

幀(Frame)

幀代表一幅靜止的圖像,分為I幀,P幀,B幀。

編解碼器(Codec)

是對視頻進行壓縮或者解壓縮,CODEC =COde (編碼) +DECode(解碼)

複用/解複用(mux/demux)

把不同的流按照某種容器的規則放入容器,這種行為叫做複用(mux)

把不同的流從某種容器中解析出來,這種行為叫做解複用(demux).

FFmpeg處理流程

過濾器(Filter)

在多媒體處理中,filter的意思是被編碼到輸出文件之前用來修改輸入文件內容的一個軟件工具。如:視頻翻轉,旋轉,縮放等。

語法:[input_link_label1][input_link_label2]… filter_name=parameters [output_link_label1][output_link_label2]…

過濾器圖link label :是標記過濾器的輸入或輸出的名稱

1.視頻過濾器 -vf

如testsrc視頻按順時針方向旋轉90度

ffplay -f lavfi -i testsrc -vf transpose=1

如testsrc視頻水平翻轉(左右翻轉)

ffplay -f lavfi -i testsrc -vf hflip

2.音頻過濾器 -af

實現慢速播放,聲音速度是原始速度的50%

ffplay p629100.mp3 -af atempo=0.5

過濾器鏈(Filterchain)

基本語法

Filterchain = 逗號分隔的一組filter

語法:“filter1,filter2,filter3,…filterN-2,filterN-1,filterN”

順時針旋轉90度並水平翻轉

ffplay -f lavfi -i testsrc -vf transpose=1,hflip

如何實現水平翻轉視頻和源視頻進行比較? 看過濾器鏈是如何實現的。

第一步: 源視頻寬度擴大兩倍。

ffmpeg -i jidu.mp4 -t 10 -vf pad=2*iw output.mp4

第二步:源視頻水平翻轉

ffmpeg -i jidu.mp4 -t 10 -vf hflip output2.mp4

第三步:水平翻轉視頻覆蓋output.mp4

ffmpeg -i output.mp4 -i output2.mp4 -filter_complex overlay=w compare.mp4

是不是很複雜?用帶有鏈接標記的過濾器圖(Filtergraph)只需一條命令。

過濾器圖(Filtergraph)

基本語法

Filtergraph = 分號分隔的一組filterchain

“filterchain1;filterchain2;…filterchainN-1;filterchainN”

Filtergraph的分類

1、簡單(simple) 一對一

2、複雜(complex)多對一, 多對多

簡單過濾器圖處理流程:


ffmpeg視頻直播編解碼流程

從圖中可以發現複雜過濾器圖比簡單過濾器圖少2個步驟,效率比簡單高,ffmpeg建議儘量使用複雜過濾器圖。

回答上面提的問題,實現水平翻轉視頻和源視頻進行比較:

用ffplay直接觀看結果:

ffplay -f lavfi -i testsrc -vf split[a][b];[a]pad=2*iw[F1: split過濾器創建兩個輸入文件的拷貝並標記為[a],[b]

F2: [a]作為pad過濾器的輸入,pad過濾器產生2倍寬度並輸出到[1].

F3: [b]作為hflip過濾器的輸入,vflip過濾器水平翻轉視頻並輸出到[2].

F4: 用overlay過濾器把 [2]覆蓋到[1]的旁邊.1];[b]hflip[2];[1][2]overlay=w

##選擇媒體流##

一些多媒體容器比如AVI,mkv,mp4等,可以包含不同種類的多個流,如何從容器中抽取各種流呢?

語法:

-map file_number:stream_type[:stream_number]

這有一些特別流符號的說明:

1、-map 0 選擇第一個文件的所有流

2、-map i:v 從文件序號i(index)中獲取所有視頻流, -map i:a 獲取所有音頻流,-map i:s 獲取所有字幕流等等。

3、特殊參數-an,-vn,-sn分別排除所有的音頻,視頻,字幕流。


ffmpeg視頻直播編解碼流程

查看幫助

FFmpeg工具有一個巨大的控制檯幫助。下表描述了可用的一些選項,斜體字表示要被替換的項,ffplay和ffprobe也有一些類似的選項。

幫助

可用的bit流 :ffmpeg –bsfs

可用的編解碼器:ffmpeg –codecs

可用的解碼器:ffmpeg –decoders

可用的編碼器:ffmpeg –encoders

可用的過濾器:ffmpeg –filters

可用的視頻格式:ffmpeg –formats

可用的聲道佈局:ffmpeg –layouts

可用的license:ffmpeg –L

可用的像素格式:ffmpeg –pix_fmts

可用的協議:ffmpeg -protocals


ffmpeg視頻直播編解碼流程

參數

FFmpeg可使用眾多參數,參數內容會根據ffmpeg版本而有差異,使用前建議先參考參數及編解碼器的敘述。此外,參數明細可用 ffmpeg -h 顯示;編解碼器名稱等明細可用 ffmpeg -formats 顯示。

下列為較常使用的參數。

主要參數

-i 設定輸入檔名。

-f 設定輸出格式。

-y 若輸出檔案已存在時則覆蓋檔案。

-fs 固定大小(fixed size),超過指定的檔案大小時則結束轉換。

-ss 從指定時間開始轉換。

-t 錄製時間

-title 設定標題。

-timestamp 設定時間戳。

-vsync 增減Frame使影音同步。

影像參數

-b 設定影像流量,默認為200Kbit/秒。

-qscale 以質量為基礎的VBR,取值0.01-255,越小質量越好。較新版本中修改為 -q:v . 例如 -q:v 0 則指定輸出與輸入是相同的quality.

-qmin 設定最小質量,與-qmax(設定最大質量)共用,比如-qmin 10 -qmax 31

-sameq 使用和源同樣的質量

-r 設定FrameRate值,默認為25。

-s 設定畫面的寬與高。

-aspect 設定畫面的比例。

-vn 不處理影像,於僅針對聲音做處理時使用。

-vcodec 設定影像影像編解碼器,未設定時則使用與輸入檔案相同之編解碼器。較新版本中修改為**-c:v **。例如 -c:v libx264 指定編解碼器為libx264.

聲音參數

-ab 設定每Channel (最近的SVN 版為所有Channel的總合)的流量。( 單位 請參照下方注意事項 )

-ar 設定採樣率。

-ac 設定聲音的Channel數。

-acodec 設定聲音編解碼器,未設定時與影像相同,使用與輸入檔案相同之編解碼器。

-an 不處理聲音,於僅針對影像做處理時使用。

-vol 設定音量大小,256為標準音量。(要設定成兩倍音量時則輸入512,依此類推。)

注意事項##

以-b及ab參數設定流量時,根據使用的ffmpeg版本,須注意單位會有kbits/sec與bits/sec的不同。(可用ffmpeg -h顯示說明來確認單位。)

例如,單位為bits/sec的情況時,欲指定流量64kbps時需輸入‘ -ab 64k ’;單位為kbits/sec的情況時則需輸入‘ -ab 64 ’。

以-acodec及-vcodec所指定的編解碼器名稱,會根據使用的ffmpeg版本而有所不同。例如使用AAC編解碼器時,會有輸入aac與 libfaac的情況。此外,編解碼器有分為僅供解碼時使用與僅供編碼時使用,因此一定要利用ffmpeg -formats 確 認輸入的編解碼器是否能運作。

範例

將MPEG-1影片轉換成MPEG-4格式之範例

ffmpeg -i inputfile.mpg -f mp4 -acodec libfaac -vcodec mpeg4 -b 256k -ab 64k outputfile.mp4

將MP3聲音轉換成MPEG-4格式之範例

ffmpeg -i inputfile.mp3 -f mp4 -acodec libaac -vn -ab 64k outputfile.mp4

將DVD的VOB檔轉換成VideoCD格式的MPEG-1檔之範例

ffmpeg -i inputfile.vob -f mpeg -acodec mp2 -vcodec mpeg1video -s 352x240 -b 1152k -ab 128k outputfile.mpg

將AVI影片轉換成H.264格式的M4V檔之範例

ffmpeg -i inputfile.avi -f mp4 -acodec libfaac -vcodec libx264 -b 512k -ab 320k outputfile.m4v

連接複數的AVI影片檔之範例(在此範例中須一度暫時將AVI檔轉換成MPEG-1檔(MPEG-1, MPEG-2 PSDV格式亦可連接)、

ffmpeg -i input1.avi -sameq inputfile_01.mpg

ffmpeg -i input2.avi -sameq inputfile_02.mpg

cat inputfile_01.mpg inputfile_02.mpg > inputfile_all.mpg

ffmpeg -i inputfile_all.mpg -sameq outputfile.avi

實例

視頻

查看視頻格式信息


ffmpeg視頻直播編解碼流程

查看視頻有多少幀

<code>ffprobe -v error -select_streams v:0 -show_entries stream=nb_frames -of default=nokey=1:noprint_wrappers=1 input.mp/<code>

注意不是所有格式都可以用這種方法,這需要container(這裡是mp4)支持。

格式轉換 (將file.avi 轉換成output.flv)

ffmpeg -i file.avi output.flv

-i 表示輸入文件

1

2

將視頻video.avi 和音頻 audio.mp3 合併成output.avi

ffmpeg -i video.avi -vcodec copy -an video2.avi

ffmpeg -i video2.avi -i audio.mp3 -vcodec copy -acodec copy output.avi

1

2

-vcodec copy 表示 force video codec (‘copy’ to copy stream) 這個不知怎麼譯 ,估計是直接copy

方法2. 好像可以直接指定兩個輸入文件:

ffmpeg -i /tmp/a.wav -i /tmp/a.avi /tmp/a.avi

兩個文件的順序很重要。

從視頻裡提取視頻或圖片

ffmpeg -i test.avi -f image2 -ss 8 -t 0.001 -s 350x240 -vf format=gray test.jpg

第8秒處 截一張灰度圖。該命令也可以截取視頻,只需要把時間參數-t改成具體的秒數即可。例如從第3分35秒片截取15秒的視頻,可以這樣這樣寫

ffmpeg -i test.avi -ss 3:35 -t 15 out.mp4

圖片轉成視頻

ffmpeg -r 60 -f image2 -s 1920x1080 -start_number 1 -i pic%04d.png -vframes 1000 -vcodec libx264 -crf 25 -pix_fmt yuv420p test.mp4

ffmpeg -i pic%04d.png -vcodec libx264 -preset veryslow -crf 0 output.avi # lossless compression


ffmpeg視頻直播編解碼流程

去掉視頻中的聲音

ffmpeg -i example.mkv -c copy -an example-nosound.mkv

視頻調整為兩倍速

ffmpeg -i input.mkv -filter:v “setpts=0.5*PTS” output.mkv

視頻文件的連接

如兩個flv 文件連接成一個。好像必須先將文件 轉成mpg ,dv 等格式的文件後才能進行連接。

連接複數的AVI影片檔之範例(在此範例中須一度暫時將AVI檔轉換成MPEG-1檔(MPEG-1, MPEG-2 PS, DV格式亦可連接))

ffmpeg -i input1.avi -sameq inputfile_01.mpg -r 20

ffmpeg -i input2.avi -sameq inputfile_02.mpg -r 20

cat inputfile_01.mpg inputfile_02.mpg > inputfile_all.mpg

ffmpeg -i inputfile_all.mpg -sameq outputfile.avi

上面-sameq 表示 相同的質量

碼率、幀率和文件大小

幀率:幀率也叫幀頻率,幀率是視頻文件中每一秒的幀數,肉眼想看到連續移動圖像至少需要15幀。

碼率:比特率(也叫碼率,數據率)是一個確定整體視頻/音頻質量的參數,秒為單位處理的字節數,碼率和視頻質量成正比,在視頻文件中中比特率用bps來表達。

幀率

用 -r 參數設置幀率

ffmpeg –i input –r fps output

用fps filter設置幀率

ffmpeg -i clip.mpg -vf fps=fps=25 clip.webm

例如設置碼率為29.97fps,下面三種方式具有相同的結果:

ffmpeg -i input.avi -r 29.97 output.mpg

ffmpeg -i input.avi -r 30000/1001 output.mpg

ffmpeg -i input.avi -r netsc output.mpg

設置碼率 –b 參數

ffmpeg -i film.avi -b 1.5M film.mp4

音頻:-b:a 視頻: - b:v

設置視頻碼率為1500kbps

ffmpeg -i input.avi -b:v 1500k output.mp4

控制輸出文件大小

-fs (file size首字母縮寫)

ffmpeg -i input.avi -fs 1024K output.mp4

改變分辨率

將輸入視頻的分辨率改成640x480

ffmpeg -i input.avi -vf scale=640:480 output_half_width.avi

在未知視頻的分辨率時,保證調整的分辨率與源視頻有相同的橫縱比。寬度固定400,高度成比例:

ffmpeg -i input.avi -vf scale=400:400/a

ffmpeg -i input.avi -vf scale=400:-1

將輸入視頻的分辨率減半

ffmpeg -i input.avi -vf scale = iw/2:ih/2 output_half_width.avi

裁剪/填充視頻

裁剪視頻crop filter

從輸入文件中選取你想要的矩形區域到輸出文件中,常見用來去視頻黑邊。(x,y以左上角為零點)

語法:crop:ow[:oh[:x[:y:[:keep_aspect]]]]

比較裁剪後的視頻和源視頻比較

ffplay -i jidu.mp4 -vf split[a][b];[a]drawbox=x=(iw-300)/2:(ih-300)/2:w=300:h=300:c=yellow[A];[A]pad=2iw[C];[b]crop=300:300:(iw-300)/2:(ih-300)/2[B];[C][B]overlay=w2.4:40

自動檢測裁剪區域

cropdetect filter 自動檢測黑邊區域,然後把檢測出來的參數填入crop filter

ffplay jidu.mp4 -vf cropdetect

填充視頻(pad)

在視頻幀上增加一快額外額區域,經常用在播放的時候顯示不同的橫縱比

語法:pad=width[:height:[:x[:y:[:color]]]]

– 創建一個30個像素的粉色寬度來包圍一個SVGA尺寸的圖片:

ffmpeg -i photo.jpg -vf pad=860:660:30:30:pink framed_photo.jpg

– 同理可以製作testsrc視頻用30個像素粉色包圍視頻

ffplay -f lavfi -i testsrc -vf pad=iw+60:ih+60:30:30:pink

翻轉和旋轉

翻轉

– 水平翻轉語法: -vf hflip

ffplay -f lavfi -i testsrc -vf hflip

– 垂直翻轉語法:-vf vflip

ffplay -f lavfi -i testsrc -vf vflip

旋轉

語法:transpose={0,1,2,3}

0:逆時針旋轉90°然後垂直翻轉

1:順時針旋轉90°

2:逆時針旋轉90°

3:順時針旋轉90°然後水平翻轉

模糊,銳化

模糊

語法:boxblur=luma_r:luma_p[:chroma_r:chram_p[:alpha_r:alpha_p]]

ffplay -f lavfi -i testsrc -vf boxblur=1:10:4:10

注意:luma_r和alpha_r半徑取值範圍是0~min(w,h)/2, chroma_r半徑的取值範圍是0~min(cw/ch)/2

銳化

語法:

-vf unsharp=l_msize_x:l_msize_y:l_amount:c_msize_x:c_msize_y:c_amount

所有的參數是可選的,默認值是5:5:1.0:5:5:0.0

l_msize_x:水平亮度矩陣,取值範圍3-13,默認值為5

l_msize_y:垂直亮度矩陣,取值範圍3-13,默認值為5

l_amount:亮度強度,取值範圍-2.0-5.0,負數為模糊效果,默認值1.0

c_msize_x:水平色彩矩陣,取值範圍3-13,默認值5

c_msize_y:垂直色彩矩陣,取值範圍3-13,默認值5

c_amount:色彩強度,取值範圍-2.0-5.0,負數為模糊效果,默認值0.0

舉例

– 使用默認值,亮度矩陣為5x5和亮度值為1.0

ffmpeg -i input -vf unsharp output.mp4

– 高斯模糊效果(比較強的模糊):

ffplay -f lavfi -i testsrc -vf unsharp=13:13:-2

覆蓋(畫中畫)

覆蓋

語法:overlay[=x[:y]

所有的參數都是可選,默認值都是0


ffmpeg視頻直播編解碼流程


舉例

– Logo在左上角

ffmpeg -i pair.mp4 -i logo.png -filter_complex overlay pair1.mp4

– 右上角:

ffmpeg -i pair.mp4 -i logo.png -filter_complex overlay=W-w pair2.mp4

– 左下角:

ffmpeg -i pair.mp4 -i logo.png -filter_complex overlay=0:H-h pair2.mp4

– 右下角:

ffmpeg -i pair.mp4 -i logo.png -filter_complex overlay=W-w:H-h pair2.mp4

刪除logo

語法:-vf delogo=x:y:w:h[:t[:show]]

x:y 離左上角的座標

w:h logo的寬和高

t: 矩形邊緣的厚度默認值4

show:若設置為1有一個綠色的矩形,默認值0.

ffplay -i jidu.mp4 -vf delogo=50:51:60:600

添加文本

語法:

drawtext=fontfile=font_f:text=text1[:p3=v3[:p4=v4[…]]]

常用的參數值

x:離左上角的橫座標

y: 離左上角的縱座標

fontcolor:字體顏色

fontsize:字體大小

text:文本內容

textfile:文本文件

t:時間戳,單位秒

n:幀數開始位置為0

draw/enable:控制文件顯示,若值為0不顯示,1顯示,可以使用函數

簡單用法

在左上角添加Welcome文字

ffplay -f lavfi -i color=c=white -vf drawtext=fontfile=arial.ttf:text=Welcom

在中央添加Good day

ffplay -f lavfi -i color=c=white -vf drawtext=“fontfile=arial.ttf:text=‘Goodday’:x=(w-tw)/2:y=(h-th)/2”

設置字體顏色和大小

ffplay -f lavfi -i color=c=white -vf drawtext=“fontfile=arial.ttf:text=‘Happy Holidays’:x=(w-tw)/2:y=(h-th)/2:fontcolor=green:fontsize=30”

動態文本

用 t (時間秒)變量實現動態文本

頂部水平滾動

ffplay -i jidu.mp4 -vf drawtext=“fontfile=arial.ttf:text=‘Dynamic RTL text’:x=w-t*50:fontcolor=darkorange:fontsize=30”

底部水平滾動

ffplay -i jidu.mp4 -vf drawtext=“fontfile=arial.ttf:textfile=textfile.txt:x=w-t*50:y=h-th:fontcolor=darkorange:fontsize=30”

垂直從下往上滾動

ffplay jidu.mp4 -vf drawtext="textfile=textfile:fontfile=arial.ttf:x=(w-tw)/2:y=h-t*100:fontcolor=white:fontsize=30“

想實現右上角顯示當前時間?

在右上角顯示當前時間 localtime

ffplay jidu.mp4 -vf drawtext="fontfile=arial.ttf:x=w-tw:fontcolor=white:fontsize=30:text=’%{localtime:%H\\:%M\\:%S}’“

每隔3秒顯示一次當前時間

ffplay jidu.mp4 -vf drawtext=“fontfile=arial.ttf:x=w-tw:fontcolor=white:fontsize=30:text=’%{localtime:%H\\:%M\\:%S}’:enable=lt(mod(t,3),1)”

色彩平衡和變換

色彩平衡

ffplay -i jidu.mp4 -vf curves=vintage

色彩變幻

ffplay -i jidu.mp4 -vf hue="H=2PIt: s=sin(2PIt)+1“

彩色轉換黑白

ffplay -i jidu.mp4 -vf lutyuv=“u=128:v=128”

設置音頻視頻播放速度

3倍視頻播放視頻

ffplay -i jidu.mp4 -vf setpts=PTS/3

3/4速度播放視頻

ffplay -i jidu.mp4 -vf setpts=PTS/(3/4)

2倍速度播放音頻

ffplay -i speech.mp3 -af atempo=2

截圖

每隔一秒截一張圖

ffmpeg -i input.flv -f image2 -vf fps=fps=1 out%d.png

每隔20秒截一張圖

ffmpeg -i input.flv -f image2 -vf fps=fps=1/20 out%d.png

多張截圖合併到一個文件裡(2x3) ?每隔一千幀(秒數=1000/fps25)即40s截一張圖

ffmpeg? -i jidu.mp4 -frames 3 -vf “select=not(mod(n,1000)),scale=320:240,tile=2x3” out.png

馬賽克視頻

用多個輸入文件創建一個馬賽克視頻:

ffmpeg -i jidu.mp4 -i jidu.flv -i “Day By Day SBS.mp4” -i “Dangerous.mp4” -filter_complex “nullclass="lazy" data-original=size=640x480 [base]; [0:v] setpts=PTS-STARTPTS, scale=320x240 [upperleft]; [1:v] setpts=PTS-STARTPTS, scale=320x240 [upperright]; [2:v] setpts=PTS-STARTPTS, scale=320x240 [lowerleft]; [3:v] setpts=PTS-STARTPTS, scale=320x240 [lowerright]; [base][upperleft] overlay=shortest=1 [tmp1]; [tmp1][upperright] overlay=shortest=1:x=320 [tmp2]; [tmp2][lowerleft] overlay=shortest=1:y=240 [tmp3]; [tmp3][lowerright] overlay=shortest=1:x=320:y=240” -c:v libx264 output.mkv

圖像拼接

兩張圖像im0.png (30像素高)和im1.jpg (20像素高)上下拼接:

ffmpeg -i im0.png -i im1.jpg -filter_complex “[0:v] pad=iw:50 [top]; [1:v] copy [down]; [top][down] overlay=0:30” im3.png

視頻拼接

需要將需要拼接的視頻文件按以下格式保存在一個列表 list.txt 中:

file ‘/path/to/file1’

file ‘/path/to/file2’

file ‘/path/to/file3’

相應的命令為:

ffmpeg -f concat -i list.txt -c copy output.mp4

視頻同步播放

將下面這行保存為ffplay2.bat,運行時輸入:ffplay2 video1.mp4 video2.mp4,即可實現左右同步播放。

ffplay -f lavfi “movie=%1,scale=iw/2:ih[v0];movie=%2,scale=iw/2:ih[v1];[v0][v1] hstack”

還可以輸入更多的參數,比如縮小系數、堆疊方式。例如:ffplay2 video1.mp4 video2.mp4 2 vstack 可以將兩個視頻縮小2倍、豎起方向堆疊同步播放。

ffplay -f lavfi “movie=%1,scale=iw/%3:ih/%3[v0];movie=%2,scale=iw/%3:ih/%3[v1];[v0][v1] %4”

Logo動態移動

2秒後logo從左到右移動:

ffplay -i jidu.mp4 -vf movie=logo.png[logo];[in][logo]overlay=x=‘if(gte(t,2),((t-2)*80)-w,NAN)’:y=0

2秒後logo從左到右移動後停止在左上角

ffplay -i jidu.mp4 -vf movie=logo.png[logo];[in][logo]overlay=x=‘if(gte(((t-2)*80)-w,W),0,((t-2)*80)-w)’:y=0

每隔10秒交替出現logo。

ffmpeg -y -t 60 -i jidu.mp4 -i logo.png -i logo2.png -filter_complex “overlay=x=if(lt(mod(t,20),10),10,NAN ):y=10,overlay=x=if(gt(mod(t,20),10),W-w-10,NAN ) :y=10” overlay.mp4

###屏幕錄像###

linux

ffmpeg -f x11grab -s xga -r 10 -i :0.0+0+0 wheer.avi

ffmpeg -f x11grab -s 320x240 -r 10 -i :0.0+100+200 wheer.avi

:0:0 表示屏幕(個人理解,因為系統變量$DISPLAY值就是:0.0) 而100,表示距左端100象素,200表示距上端200

-r 10 設置頻率

ffmpeg -f x11grab -s xga -qscale 5 -r 10 -i :0.0+0+0 wheer.avi

-qscale 8 設定畫面質量,值越小越好

windows

ffmpeg在Linux下用X11grab進行屏幕錄像,在Windows下用DirectShow濾鏡

首先需要安裝一個軟件,screen capture recorder

編譯好的下載地址是:

http://sourceforge.net/projects/screencapturer/files/

源碼地址是:

https://github.com/rdp/screen-capture-recorder-to-video-windows-free

安裝完了之後,在命令行執行:

ffmpeg -list_devices true -f dshow -i dummy

可查看新的Direct Show設備。

然後就可以用FFMPEG來進行錄像了


ffmpeg視頻直播編解碼流程


看到這,你會發現這個命令有多強大。

如果我屏幕上打開了一個窗口,我只想錄這個窗口的內容,如何確定這個窗口的座標位置呢?可以用另外一個命令xwininfo 輸入這個命令後,用鼠標點選目標窗口,就會出現目標窗口的座標,寬高等一系列信息。

音頻

壓縮mp3 文件

如果你覺得mp3 文件 有點大,想變小一點那麼可以通過-ab 選項改變音頻的比特率 (bitrate)

ffmpeg -i input.mp3 -ab 128 output.mp3 //這裡將比特率設為128

你可以用file 命令查看一下源文件 的信息

錄音

(要有可用的麥克風,並且如果用alsa 的話,好像得安alsa-oss,重啟)

ffmpeg -f oss -i /dev/dsp out.avi (should hava oss or alsa-oss)

ffmpeg -f alsa -ac 2 -i hw:0, 0 out.avi (should )

ffmpeg -f alsa -ac 2 -i pulse (should hava PulseAudio)

在alsa 體系中聲卡(也可能是麥克風)叫hw:0,0 而在oss 體系中叫/dev/dsp (用詞可能不太專業) 。Linux在安裝了聲卡後,會有一些設備文件生成,採集數字樣本的/dev/dsp文件,針對混音器的/dev/mixer文件,用於音序器的/dev/sequencer,/dev/audio文件一個基於兼容性考慮的聲音設備文件。只要向/dev/audio中輸入wav文件就能發出聲音。而對/dev/dsp文件讀取就能得到WAV文件格式的聲音文件。

資料內容包括:C/C++,Linux,golang,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒體,CDN,P2P,K8S,Docker,TCP/IP,協程,DPDK,WebRTC,ffmpeg 嵌入式 等。

需要資料的關注+私信“資料”免費領取


分享到:


相關文章: