FFmpeg是很是強大的音視頻處理工具,咱們可使用它來處理視頻合成、剪輯、加特效等等操做。html
官方文檔至上 FFmpeg的官方文檔git
FFmpeg的官方文檔命令真的是太多太多,並且都是英文,感受精通完這些命令,都夠學一門新語言了!github
SO 爲了讓一些小夥伴們快速的用上FFmpeg,我整理了一些FFmpeg的經常使用的知識和大部分平常用到的命令供你們查閱!算法
還不收藏嗎?廢話很少說上乾貨!bash
FFmpeg的環境集成挺麻煩的推薦你們使用這個庫,一鍵集成FFmpeg! Skr~ide
RxFFmpeg工具
在音視頻領域,咱們把一路音/視頻稱爲一路流。如咱們小時候常用VCD看港片,在裏邊能夠選擇粵語或國語聲音,其實就是CD視頻文件中存放了兩路音頻流,用戶能夠選擇其中一路進行播放。oop
咱們熟悉的mp4,rmvb,mkv,avi是多媒體容器文件格式(或稱多媒體封裝格式),所謂容器是指將不一樣的數據流(視頻流,音頻流,字幕流等)封裝在一個文件(載體)中。 播放時各類流分別進行解碼等處理後,而後輸出到顯示器和音響等設備進行播放。多媒體容器格式不一樣於編碼格式,一個容器中能夠封裝多種編碼格式的媒體流。 流封裝了實際的媒體數據,如視頻流,音頻流和字幕流等。通常狀況下,流中的數據只能使用一種編碼格式。性能
是音頻中的概念,稱之爲聲道。在一路音頻流中,能夠有單聲道,雙聲道或立體聲。測試
幀率(frames per second, fps)是每秒畫面刷新的次數,幀率越高視頻越流暢。通常來講30fps就是能夠接受的,60fps則能夠明顯提高交互感和逼真感,可是通常超過75fps通常就不容易察覺到有明顯的流暢度提高了。
分辨率表示畫面的精細程度,一般用像素密度來表示,經常使用的單位爲ppi(像素每英寸)。一般像素密度越高畫面越精細,模糊程度越低。對於視頻文件而言,像素密度是沒法控制的(由播放器和顯示設備決定)。咱們一般用視頻的像素數來表示它的分辨率如1080x640, 640x320等。
比特率(bit rate)又稱碼率,表示多媒體流每秒輸出的字節數,單位爲KB/s,Kbps等。一樣的壓縮算法下,比特率越高音視頻的質量越好。
指的是編碼器的輸出碼率能夠根據輸入源信號的複雜度進行自適應調整,以在輸出質量保持不變的條件下儘量減小數據量。VBR適用於存儲,不太適用流式傳輸。
指的是編碼器輸出碼率固定,CBR不適合存儲,對於複雜內容可能沒有足夠碼率進行編碼,從而致使質量降低,同時會在簡單內容部分浪費一些碼率。
每秒鐘對音頻信號的採樣次數,採樣頻率越高聲音還原度越高,聲音更加天然,單位是赫茲 Hz。音頻文件通常使用的採樣率是 44.1kHz,也就是一秒鐘採樣44100次,實驗發現低於這個值就會有較明顯的損失,而高於這個值人的耳朵已經很難分辨,並且增大了數字音頻所佔用的空間。
視頻流能夠看作圖片的序列,咱們把這個序列中的一張圖片稱爲一幀。若存儲視頻中全部幀則會數據量過大,不便於存儲和傳輸。所幸統計代表大多數視頻相鄰幀之間的區別並不大,因此對於一段變化不大的視頻,咱們能夠先完整編碼幀A,其後的B幀只須要編碼與A幀不一樣的部分,B幀後的C幀則只編碼與B幀的差別。如此遞推,將一段視頻編碼爲一個序列。當某個圖像與以前的圖像變化很大沒法參考前面的幀來生成,咱們就結束上一個序列將該幀完整編碼開始一個新的序列。
過濾器會對已解碼的幀進行處理,處理後的幀會被從新編碼輸出
指定操做源的大小,iw指定按整型取視頻的寬度,ih指定按整型取視頻的高度。-1爲按原圖比例變化 例:iw/2:-1視頻縮小一倍
指定操做源擺放的位置 overlay=30:10 main_w和main_h爲底層視頻的寬和高,overlay_w和overlay_h爲疊加視頻的寬和高
刪除水印 例:delogo=x=800:y=20:w=70:h=80
裁剪 格式:crop=out_w:out_h: x :y out_w: 輸出的寬度。可使用 in_w 表式輸入視頻的寬度。 out_h: 輸出的高度。可使用 in_h 表式輸入視頻的高度。 x : X座標 y : Y座標 x和y 設置爲 0,說明從左上角開始裁剪。若是不寫是從中心點裁剪
setpts=0.5*PTS表示每幀視頻的pts時間戳都乘0.5,也就是視頻加快一倍
可用於處理複雜輸出,如能夠將指定的多路流輸出到一個輸出文件,也能夠指定輸出到多個文件。"[v]" 複雜濾鏡輸出的別名做爲輸出文件的一路流。上面 map的用法是將複雜濾鏡輸出的視頻和音頻輸出到指定文件中。
crop=iw/2:ih:0:0,split[left][tmp];[tmp]hflip[right]
curves='vintage'(復古) 'strong_contrast'(強對比度)'lighter'(變亮) 'negate'(底片) 'none' 'color_negative'(彩色底片);
colorlevels=rimin=0.058:gimin=0.058:bimin=0.058
fftfilt=dc_Y=0:weight_Y='exp(-4 * ((Y+X)/(W+H)))
hqdn3d=luma_spatial=15.0
fftfilt=dc_Y=0:weight_Y='1+squish(1-(Y+X)/100)'
fftfilt=dc_Y=0:weight_Y='squish((Y+X)/100-1)'
fftfilt=dc_Y=128:weight_Y='squish(1-(Y+X)/100)'
例:fade=in:0:25, fade=out:975:25 從0楨開始淡入25幀,從975開始淡出25幀 fade=in:5:20:color=yellow 開始淡入前爲黃色 fade=in:0:25:alpha=1 淡入完成後過去15幀的透明度 fade=t=in:st=5.5:d=0.5 5.5秒開始,淡入0.5秒 d爲時長
fps濾鏡經過刪除幀或者複製幀的方法強制設置幀率 例:ffmpeg -y -i test.mp4 -vf "fps=60" out.mp4
ffmpeg -i out.mp4 -y out.avi
視頻轉Gif
ffmpeg -i out.mp4 -y out.gif
從0開始截10s轉Gif
ffmpeg -i out.mp4 -ss 00:00:00 -t 10 -y out.gif
ffmpeg -i input_test.mp4 -vf fps=1 out%03d.png
ffmpeg -i input_test.mp4 -vf fps=1/60 out%03d.png
ffmpeg -ss 2 -i test.mp4 -t 10 -y -f out_test.mp4
截取從2s開始10秒的視頻
ffmpeg -i test.mp4 -c copy -map 0 -f segment -segment_time 10 video/part-%d.mp4
ffmpeg -ss 2 -i test.mp4 -r 1 -t 2 -y -f image2 image-%3.jpeg
ffmpeg -loop 1 -i img%3d.png -t 10-y output.mp4
ffmpeg -i input.gif -y output.mp4
ffmpeg -i "concat:input1.mp4|input2.mp4|input3.mp4" -c copy output.mp4
ffmpeg -i input_test.mp4 -s 320*240 out_test.mp4
ffmpeg -i input.mp4 -i input1.mp3 -y output.mp4
ffmpeg -i test.mp4 -vn -a:c copy out.mp3
ffmpeg -i input.mp4 -vn -vcodec copy output.mp4
ffmpeg -i "concat:test1.mp3|test2.mp3" -acodec copy output.mp3
ffmpeg -i input_01.wav -i input_02.wav -filter_complex amix=inputs=2:duration=shortest:dropout_transition=3 output.wav
以兩個音頻文件時長較短的音頻文件時長做爲最終輸出的時長
ffmpeg -y -i test.mp4 -vf "drawtext=fontfile=CourierNew.ttf:text='hello world':x=100:y=50:fontsize=24" out.mp4
因爲Android端字體庫的緣由,我能夠經過把文字轉成圖片,再加到視頻上的方式來添加,如下是文字轉圖片的源碼:
/**
* 文本轉成Bitmap
* @param text 文本內容
* @param context 上下文
* @return 圖片的bitmap
*/
private static Bitmap textToBitmap(String text , Context context) {
float scale = context.getResources().getDisplayMetrics().scaledDensity;
TextView tv = new TextView(context);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
tv.setLayoutParams(layoutParams);
tv.setText(text);
tv.setTextSize(scale * TEXT_SIZE);
tv.setGravity(Gravity.CENTER_HORIZONTAL);
tv.setDrawingCacheEnabled(true);
tv.setTextColor(TEXT_COLOR);
tv.setBackgroundColor(Color.WHITE);
tv.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
tv.layout(0, 0, tv.getMeasuredWidth(), tv.getMeasuredHeight());
tv.buildDrawingCache();
Bitmap bitmap = tv.getDrawingCache();
int rate = bitmap.getHeight() / 20;
return Bitmap.createScaledBitmap(bitmap, bitmap.getWidth()/rate, 20, false);
}
/**
* 文字生成圖片
* @param filePath filePath
* @param text text
* @param context context
* @return 生成圖片是否成功
*/
public static boolean textToPicture(String filePath, String text , Context context){
Bitmap bitmap = textToBitmap(text , context);
FileOutputStream outputStream = null;
try {
outputStream = new FileOutputStream(filePath);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, outputStream);
outputStream.flush();
} catch (IOException e) {
e.printStackTrace();
return false;
}finally {
try {
if(outputStream != null){
outputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return true;
}
複製代碼
添加單個圖片水印
ffmpeg -i input.mp4 -i water.png -filter_complex "[0:v][1:v]overlay=main_w-overlay_w-10:10" -y output.mp4
添加多個圖片水印
ffmpeg -i input.mp4 -i photo1.png -i photo2.png -filter_complex "[0:v]fade=in:st=0:d=2,curves=vintage[img];[1:v]scale=300:-1[img1];[img][img1]overlay=10:10[out1];[out1][2:v]overlay=main_w:main_h" -y output.mp4
添加了兩張圖片圖片,第一張設置爲寬度300,高度-1爲根據原圖片比例縮放,在視頻左上角,第二張圖片在視頻右下角,fade是淡入淡出效果器,視頻效果爲從0s開始淡入,淡入2s,視頻爲復古效果curves=vintage
ffmpeg -i video2.mp4 -i logo.png -filter_complex "[1:v]scale=50*50[logo];[0:v]scale=200*200[bg];[bg][logo]overlay=x='if(gte(t,0),-overlay_w+(mod(n,main_w+overlay_w))+5,NAN)':y=0" -y output.mp4
含義: 時間t大於0,那麼就開始從子內容的寬度的x-overlay_w位置開始,而後每一幀n計數,幀數n除以(背景main_w+子內容背景overlay_w)求除數+1設置爲x座標,便可循環 overlay=30:10 main_w和main_h爲底層視頻的寬和高,overlay_w和overlay_h爲疊加視頻的寬和高
ffmpeg -i test.flv -vf delogo=x=20:y=20:w=70:h=80 output.flv
x,y :指定水印的位置,即圖片左上角的座標 w,h:給出水印的寬高
ffmpeg -y -i test.mp4 -t 10 -loop 1 -framerate 6 -i test_%3d.png -filter_comple 'overlay=10:main_h-overlay_h-10' out.mp4
將多張圖片(test_001.png, ani002.png...)組成動畫, 而後將這個動畫疊加在視頻的左下角。-t 10 -loop 1會循環播放動畫,持續10s
ffmepg -i input.wav -filter_complex afade=t=in:ss=0:d-4 output.wav
(淡入)把 input 文件的前5s 作一個淡入效果,輸出到 output.wav 中
ffmpeg -i input.wav -filter_complex afade=t=out:st=200:d=5 output.wav
(淡出)將input.wav文件從200s開始,作5s的淡出效果,並放到output.wav文件中
ffmpeg -i input.flv -c:v libx264 -b:v 800k -c:a libfdk_aac -vf eq=brightness=0.25 -f mp4 output.mp4
提亮參數是brightness,取值範圍是從-1.0到1.0,默認值是0
ffmpeg -i input.flv -c:v libx264 -b:v 800k -c:a libfdk_aac -vf eq=contrast=1.5 -f mp4 output.mp4
對比度參數是contrast,取值範圍是從-2.0到2.0,默認值是1.0
ffmpeg -i input.mp4 -an -vf "crop=480:480:120:0" -vcodec libx264 -b:v 800k output.mp4
ffmpeg -i input.mp4 -vf "transpose=1" -b:v 600k output.mp4
ffmpeg -i input.mp4 -af 'volume=0.5' output.mp4
視頻壓縮主要是改變視頻的碼率和分辨率去壓縮,可是須要控制好縮小的碼率和分辨率,以保證視頻的質量符合你的需求 ffmpeg -i input.mp4 -b:v 600k -y output.mp4
FFmpeg十分強大,本文的知識只是FFmpeg的一小部分,對於初識FFmpeg的同窗用於常見的視頻操做仍是徹底OK的,精通音視頻仍是有很長的路要走,更多的FFmpeg知道請移步FFmpeg的官方文檔!
歡迎靚仔靚女們收藏一波,謝謝~