首页
/
每日頭條
/
生活
/
ffmpeg 特效
ffmpeg 特效
更新时间:2024-11-26 19:53:07

ffmpeg是許多音視頻入門書籍都會推薦學習的一套多媒體框架,其集封裝、解封裝、編碼、解碼、播放和濾鏡等多項功能于一身,堪稱音視頻領域的「瑞士軍刀」。

今天,我們将不再遵循常規教程的套路,而是将以表情包界名垂青史的名場面、電影《旺角卡門》中的經典片段——「吔屎啦你」為講解素材,通過GIF表情包創作的場景化教學,來講解FFmpeg命令行工具的實際運用。

若本教程成功地激起了你對FFmpeg命令行工具的探索興趣,記得說聲多謝老舅點贊、收藏、評論三連支持一下。

Hello, GIF!

首先,舉一個最簡單的例子,即,直接把一個任意格式的視頻片段轉為GIF圖像:

ffmpeg -i as_tears_go_by.mp4 as_tears_go_by.gif

-i 選項用于指定任意數量的輸入流,可以是本地文件也可以是網絡文件。

而輸出流也可以是任意數量的,其指定的方式則相對粗暴得多,隻要是命令行中無法解釋為「選項」的内容,都會被FFmpeg命令行工具視為輸出流

大多數情況下,FFmpeg命令行工具會根據輸入輸出流的擴展名去自動檢測格式,如果需要強制指定輸入或輸出流的格式,可以使用-f 選項,比如:

ffmpeg -i as_tears_go_by.mp4 -f gif as_tears_go_by.gif

效果都是一樣的。

名場面往往就是那幾秒

在誕生這些表情包名場面的電影中,你經常會發現有那麼一群“合影黨”,喜歡把播放進度拖動到表情包畫面出現的前後幾秒,然後在公屏上打上“合影留念”的彈幕(說的是不是你?),仿佛一開始就是奔着這幾秒去看這部電影的。

而我們創作表情包的第一步,自然也是先截取出這些全片中最精彩的片段。

要截取視頻中的特定位置與時長的片段,我們可以用以下命令行實現:

ffmpeg -i {input} -ss {position} -t {duration} {output}

其中,

-ss 選項用于定位到指定的視頻位置,可以是「HH:MM:SS」這種格式,也可以是「2.3」這種表示第2.3秒的格式。

-t 選項用于表示截取的視頻時長,也同樣支持以上2種時間格式。

例如,「吔屎啦你」這一名場面發生在上述視頻片段的第11秒,持續時間約為2.3秒,那我們就可以這樣子編寫命令行:

ffmpeg -i as_tears_go_by.mp4 -ss 00:11 -t 2.3 as_tears_go_by-trim.gif

到位了到位了哈!可是有一個問題出現了,盡管經過截取處理,轉出的GIF圖像文件仍有11.6MB,作為一個表情包來講,實在是太大了。

ffmpeg 特效(FFmpeg創作GIF表情包教程來了)1

而相同時長的MP4視頻文件大小卻隻有664KB,為什麼兩者能相差這麼大呢?這其實跟二者采用的壓縮算法有關,後面系列文章中會專門講到,這裡就先不展開說了。

鬥圖,講究一個「快」字

你肯定有過這樣的經曆,本來和暧昧對象在微信上聊得好好的,不知怎的突然就沒話題了。與其繼續尬聊下去,我們更多會選擇開啟「鬥圖」模式,來緩解和過渡這一尴尬的時刻。

鬥圖除了考驗你表情包彈藥庫的存量之外,表情包連發的“攻速”也很重要。

想象一下,對方的表情包如機關槍般“哒哒哒”密集地發來,而你的表情包卻因為GIF格式下的文件過大,到了對方的聊天面闆還要轉圈下載好一陣,氣勢上就輸了一大截。

因此,壓縮表情包文件的大小,很重要。

壓縮大法第一式——縮放

ffprobe是FFmpeg提供的多媒體信息查看工具,我們可以先使用ffprobe來查看上一步中截取了名場面,并轉換了格式後的GIF圖像信息:

ffprobe as_tears_go_by-trim.gif

Input #0, gif, from 'as_tears_go_by-cut.gif':

Duration: 00:00:02.32, start: 0.000000, bitrate: 40101 kb/s

Stream #0:0: Video: gif, bgra, 1920x1080 [SAR 64:64 DAR 16:9], 25 fps, 25 tbr, 100 tbn

可以看到,由于我們是直接将視頻片段轉為GIF圖像的,文件的尺寸大小高達1920x1080!和一般的靜态圖片一樣,GIF格式的文件大小也是受尺寸大小影響的,尺寸越大相應的文件也就越大,但作為表情包我們往往不需要追求如此高清的效果。

因此,我們壓縮工作的第一步,就是縮減GIF文件的尺寸。

可以使用以下命令行來實現:

ffmpeg -i {input} -s {WxH} {output}

可以看到,由于我們是直接将視頻片段轉為GIF圖像的,文件的尺寸大小高達1920x1080!和一般的靜态圖片一樣,GIF格式的文件大小也是受尺寸大小影響的,尺寸越大相應的文件也就越大,但作為表情包我們往往不需要追求如此高清的效果。

【更多音視頻學習資料,點擊下方鍊接免費領取↓↓,先碼住不迷路~】

點擊領取→音視頻開發基礎知識和資料包

因此,我們壓縮工作的第一步,就是縮減GIF文件的尺寸。

可以使用以下命令行來實現:

ffmpeg -i {input} -s {WxH} {output}

-s 選項用于指定輸出文件的尺寸大小,格式上是「寬度(W)x高度(H)」

例如,我們可以拿到前面的GIF圖像文件,将其寬高均縮放至原先的1/6:

ffmpeg -i as_tears_go_by-cut.gif -s 320x180 as_tears_go_by-scale.gif

ffmpeg 特效(FFmpeg創作GIF表情包教程來了)2

ffmpeg 特效(FFmpeg創作GIF表情包教程來了)3

可以看到,經過縮放後的文件大小已減少至1.6M,約為原先大小的1/7,效果還是比較明顯的。

壓縮大法第二式——抽幀

GIF是連續的動态圖像,可以視作是一張一張完整的圖像按一定速率播放,然後利用人眼的視覺殘留效應所形成的效果。每秒鐘依次播放的圖像數量叫做幀率,單位是fps(frame per second,幀每秒)。

前面我們用ffprobe工具查看後可得知,輸出的GIF圖像的幀率是25fps,這是由于我們是直接将視頻片段轉為GIF圖像的,而電影中的常見幀率為24/25幀,因此輸出的GIF圖像也保留了相同的幀率。

幀率越高,GIF圖像的動效相對就越流暢,但相應的要儲存的圖片幀也會更多,可能導緻文件大小直線上升。通過減少幀數,犧牲一點連貫性,可以顯著優化文件的大小。

可以使用以下命令行來實現:

ffmpeg -i {input} -r {fps} {output}

-r 選項用于指定幀率,支持整數和分數格式。

例如,我們可以将上一步幀率為25fps的GIF圖像減少至8fps:

ffmpeg -i as_tears_go_by-scale.gif -r 8 as_tears_go_by-frameextract.gif

幀率減少後的GIF圖像效果如下:

ffmpeg 特效(FFmpeg創作GIF表情包教程來了)4

ffmpeg 特效(FFmpeg創作GIF表情包教程來了)5

可以看到,經過抽幀處理後的GIF圖像大小得到了進一步的壓縮。

壓縮大法第三式——裁剪

裁剪同樣是為了縮減GIF圖像的尺寸,隻不過和單純的縮放相比,裁剪還有去除冗餘元素、突出目标主體的附加效果。

借助FFmpeg命令行工具實現對圖像/視頻的裁剪,我們需要用到Filter(濾鏡、過濾器)模塊。

濾鏡模塊提供了許多音視頻特效處理的功能,比如crop(裁剪)、scale(縮放)、overlay(疊加)、rotate(旋轉),trim(截取)等。可以說,前面幾個步驟提到的功能,都有相應的濾鏡可以實現。

如果要為視頻類型的輸入流指定使用的濾鏡,需要使用-vf 選項。可指定的濾鏡按輸入輸出流的數量和類型可分為「簡單濾鏡」和「複雜濾鏡」兩種。

所謂「簡單濾鏡」,指的是那種剛好隻有一個輸入流、一個輸出流的的濾鏡,且兩者都是同一類型的情況:

ffmpeg 特效(FFmpeg創作GIF表情包教程來了)6

相對的,「複雜濾鏡」指的則是那些具有多個輸入流/輸出流,或者輸出流類型與輸入流類型不同的情況:

ffmpeg 特效(FFmpeg創作GIF表情包教程來了)7

比如我們現在要實現的裁剪功能,就是一個典型的「簡單濾鏡」:

ffmpeg -i as_tears_go_by-frameextract.gif -vf "crop=180:180:100:0" as_tears_go_by-crop.gif

這條命令行的完整釋義如下:

  • 輸入一個名為“as_tears_go_by-frameextract”的GIF圖像文件
  • 創建一個提供裁剪功能的視頻濾鏡,用于過濾輸入流。
  • 裁剪區域的寬度為180,高度為180,從以左上角為原點、x軸向右偏移量為100、y軸向下偏移量為0的位置開始裁剪。
  • 将裁剪完成的内容輸出到一個名為“as_tears_go_by-cut”的GIF圖像文件

經過裁剪後輸出的GIF圖像效果如下:

ffmpeg 特效(FFmpeg創作GIF表情包教程來了)8

ffmpeg 特效(FFmpeg創作GIF表情包教程來了)9

【更多音視頻學習資料,點擊下方鍊接免費領取↓↓,先碼住不迷路~】

點擊領取→C 程序員必看,抓住音視頻開發的大浪潮!沖擊年薪60萬

更騷的操作

FFmpeg濾鏡的強大之處,在于它可以通過不同濾鏡的排列組合,實現各種各樣複雜的功能

FFmpeg濾鏡共包含以下3個層級:

filter -> filterchain -> filtergraph 也即 濾鏡 -> 濾鏡鍊 -> 濾鏡圖

多個濾鏡可以串聯成一條濾鏡鍊,多條濾鏡鍊可以組合成一個濾鏡圖

我們可以基于FFmpeg的官方示例進行改造,實現“裁剪出視頻的左半部分,并鏡像疊加到視頻的右半部分”的效果,來演示一下三者的關系,以及如何結合使用,流程圖如下:

ffmpeg 特效(FFmpeg創作GIF表情包教程來了)10

  1. 首先,使用split濾鏡将輸入流分割為兩個流[main]和[tmp] (你可以理解為copy了一份);
  2. 将其中一個流[tmp]先通過crop濾鏡裁剪出左半部分;
  3. 将步驟2的輸出再經過hflip濾鏡進行水平翻轉,并輸出為[flip];
  4. 把步驟3的輸出[flip]疊加到[main]的右半部分。

這個流程使用命令行實現如下:

ffmpeg -i as_tears_go_by-crop.gif -vf "split[main][tmp];[tmp]crop=iw/2:ih:0:0,hflip[flip];[main][flip]overlay=W/2:0" as_tears_go_by-graph.gif

是不是看着這麼多的參數有點懵圈了?不要怕,這個涉及到濾鏡模塊的語法,我們一個一個來解釋:

首先,[main][tmp][flip]是為輸入輸出流所打的标簽,可以任意命名,打标簽是可選的,為了連接其他濾鏡時方便使用。

split、crop、hflip、overlay都是具體使用的濾鏡,濾鏡的各種參數在=号後面指定。

濾鏡的參數之間用冒号:分隔,可以是純值的形式,也可以是“鍵=值”的形式,還可以是二者混用的形式。

比如crop濾鏡的參數也可以這樣指定:crop=w=iw/2:h=ih:x=0:y=0,iw和ih這兩個變量分别指的是輸入幀的寬度和高度。

同一濾鏡鍊内的不同濾鏡之間用逗号,分隔。

比如[tmp]crop=iw/2:ih:0:0,hflip[flip]這一濾鏡鍊中就包含crop和hflip這兩個濾鏡,兩者之間使用逗号,分隔。

同一濾鏡圖内的不同濾鏡鍊之間用分号;分隔。

比如上面的濾鏡圖就包含split;crop,flip;overlay三條濾鏡鍊,彼此之間使用用分号;分隔。

最終輸出的效果如下——忍法·雙頭嘲諷:

ffmpeg 特效(FFmpeg創作GIF表情包教程來了)11

嗯......看着有點詭異呢!

表情包的經典二創

一個表情包之所以經久不衰,除了表情包本身很有“梗”之外,網友們富有想象力的“二次創作”,也是表情包能再次迸發出生命力的原因之一。

比如讓人忍俊不禁的「欲吔又止」:

ffmpeg 特效(FFmpeg創作GIF表情包教程來了)12

這種類似連環畫的表情包叙事感很強,如果采用FFmpeg來創作的話,可以分為以下幾步進行:

視頻截圖手動截圖

手動截圖的工作需要先借助前面提到的-ss 選項,定位到視頻片段指定的位置,然後再借助-vframe 選項來輸出指定數量的視頻幀,最後當然還要再對輸出的視頻幀的進行一波同樣的裁剪和縮放。

具體的命令行示例如下:

ffmpeg -i as_tears_go_by.mp4 -ss 00:13 -vframes 1 -vf "crop=ih:ih:iw/4:0" -s 180x180 as_tears_go_by-screenshot.jpg

得到的處理後的視頻截圖如下:

ffmpeg 特效(FFmpeg創作GIF表情包教程來了)13

定時截圖

【更多音視頻學習資料,點擊下方鍊接免費領取↓↓,先碼住不迷路~】

點擊領取→音視頻開發基礎知識和資料包

但如果你想偷一下懶,不想一張張手動去截,我們也可以借助fps濾鏡實現來定時截圖,然後再從輸出的圖片集裡找符合預期的截圖即可,命令行如下:

ffmpeg -i as_tears_go_by.mp4 -vf "fps=2,crop=ih:ih:iw/4:0" -s 180x180 screenshot/out%d.jpg

此命令行執行後,每過0.5秒就會生成一張JPG格式的圖片,并進行一波同樣的裁剪和縮放。

ffmpeg 特效(FFmpeg創作GIF表情包教程來了)14

從中我們最終挑出以下四張截圖作為素材:

ffmpeg 特效(FFmpeg創作GIF表情包教程來了)15

添加文字

添加文字的工作同樣可借助濾鏡功能完成,使用到的濾鏡是「drawtext」濾鏡。

我們先拿前面經過裁剪之後生成的GIF圖像來做下實驗:

ffmpeg -i as_tears_go_by-crop.gif -vf "drawtext=fontsize=30:text='吔屎啦你':fontcolor=white:x=25:y=100:fontfile=JingNanYuanMoTi/KNFONTYUANMO-2.otf" as_tears_go_by-text.gif

添加文字後的效果如下:

ffmpeg 特效(FFmpeg創作GIF表情包教程來了)16

fontsize、fontcolor、text等從字面意義就可以知曉其作用的參數我就不再贅述了,這裡需要提到的是,如果默認的字體風格不符合預期,drawtext濾鏡也支持使用「fontfile」參數來指定所采用的字體文件,比如上面的otf文件。

以下是挑選出的4張截圖添加文字後的效果:

ffmpeg 特效(FFmpeg創作GIF表情包教程來了)17

多宮格處理

多宮格處理的工作實際就是前面所提到的「複雜濾鏡」的使用場景,我們需要整合多個輸入流(此處是靜态圖),并拼接到一個畫布上輸出。

先丢出處理的命令行:

ffmpeg -i 1.jpg -i 2.jpg -i 3.jpg -i 4.jpg -filter_complex "nullsrc=size=360x360[base];[base][0:v]overlay=0:0[tmp1];[tmp1][1:v]overlay=180:0[tmp2];[tmp2][2:v]overlay=0:180[tmp3];[tmp3][3:v]overlay=180:180" -frames:v 1 output.jpg

命令行很長,但是了解過前面的濾鏡語法以後,相信也不難理解,我們來一步步解釋:

ffmpeg 特效(FFmpeg創作GIF表情包教程來了)18

  • 首先,通過-i 選項輸入4張待處理的靜态圖素材;
  • 其次,通過-filter_complex 選項創建一個複雜濾鏡;
  • 該複雜濾鏡首先創建了一個360x360的空白畫布,并指定輸出流的标簽為[base];
  • [0:v]表示取第一個輸入流(第1張靜态圖),然後使用overlay濾鏡,将第1張靜态圖疊加到左上角原點的位置(也即左上角),并指定疊加處理輸出流的标簽為[tmp1];
  • 繼續使用overlay濾鏡,将第2張靜态圖疊加到以左上角原點,x軸向右偏移量為180、y軸向下偏移量為0的位置(也即右上角),并指定疊加處理輸出流的标簽為[tmp2];
  • 繼續使用overlay濾鏡,将第3張靜态圖疊加到以左上角原點,x軸向右偏移量為0、y軸向下偏移量為180的位置(也即左下角),并指定疊加處理輸出流的标簽為[tmp3];
  • 繼續使用overlay濾鏡,将第4張靜态圖疊加到以左上角原點,x軸向右偏移量為180、y軸向下偏移量為180的位置(也即右下角);
  • 将全部處理完成的内容輸出到一個名為“output.jpg”的文件
  • 【更多音視頻學習資料,點擊下方鍊接免費領取↓↓,先碼住不迷路~】
  • 點擊領取→C 程序員必看,抓住音視頻開發的大浪潮!沖擊年薪60萬

最終産出的效果圖如下:

ffmpeg 特效(FFmpeg創作GIF表情包教程來了)19

命令行的優勢

可能有人想說了,我幹嘛要去寫這麼一大串晦澀難懂的命令行呢?要創作表情包,使用有可視化界面的軟件操作不香嗎?

誠然,可視化界面有可視化界面的優勢,像前面添加文字的操作,鼠标或手指點點拖拖就可以完成了。但是别忘了,許多所謂的擁有可視化界面的軟件,其隻不過是在命令行工具上披一層皮而已

換句話說,隻要熟悉了FFmpeg命令行工具的使用之後,我們就完全可以自己做一個擁有可視化界面,而功能底層使用FFmpeg命令行來實現的軟件。

比如在Android平台上,我們就可以通過手動将FFmpeg源碼編譯成so庫,并抽取ffmpeg編解碼工具的相關文件,借助NDK開發自行封裝成一個FFmpeg命令行工具庫,然後集成到我們的App中去,從而實現一個功能豐富的視頻編輯工具App。(後續文章将講到,敬請關注)。

看到這裡,你還不想打開FFmpeg命令行工具實際操作一番嗎?

,
Comments
Welcome to tft每日頭條 comments! Please keep conversations courteous and on-topic. To fosterproductive and respectful conversations, you may see comments from our Community Managers.
Sign up to post
Sort by
Show More Comments
推荐阅读
聯通大王卡日租寶不能關嗎
聯通大王卡日租寶不能關嗎
,
2024-11-26
鄧亞萍多大開始打乒乓球
鄧亞萍多大開始打乒乓球
近日,鄧亞萍在社交平台曬出一家三口一起打乒乓球的視頻,視頻中,鄧亞萍和丈夫林志剛站在一邊,兒子站在一邊。三個人穿着運動衣,非常認真地在打乒乓球。14歲的兒子在父母的訓練之下技術十分娴熟。并且鄧亞萍還逗趣到:"兩位昔日世界冠軍,如今淪...
2024-11-26
黑龍江省早熟旱稻品種
黑龍江省早熟旱稻品種
黑龍江省早熟旱稻品種?新華社哈爾濱9月27日電(記者侯鳴)記者從黑龍江省農業科學院了解到,黑龍江省農業科學院水稻研究所培育的早熟粳稻新品種“龍粳3010”近日經過測産驗收,平均畝産758.81公斤,連續兩年達到東北早熟粳型超級稻産量指标,我...
2024-11-26
什麼時候測體重是最準的
什麼時候測體重是最準的
對于減肥和健身的人來說,每天監測自己的體重都是一件比較重要的事情。大多數人就是往體重秤上一站一看數值就行,但是這樣會發現自己的體重變化有些大,早上和晚上稱出來的體重不一樣,不知道哪一個是準确的。那麼到底應該在什麼時候測體重是更準确的呢?我們...
2024-11-26
跆拳道宋潔奪冠全運會
跆拳道宋潔奪冠全運會
跆拳道宋潔奪冠全運會?中新網成都9月20日電(記者賀劭清)記者20日從四川體育職業學院獲悉,北京時間9月18日深夜,2022年世界跆拳道聯盟斯洛文尼亞公開賽在盧布爾雅那舉行來自四川體育職業學院的女子67公斤以下級選手宋潔表現尤為亮眼,先後在...
2024-11-26
Copyright 2023-2024 - www.tftnews.com All Rights Reserved