一、FFmpeg的故事
1.FFmpeg是什麼?
從百度百科中來看,FFmpeg是一套可以用來記錄、轉換數字音頻、視頻,並能將其轉化爲流的開源計算機程序。採用LGPL或GPL許可證。它提供了錄製、轉換以及流化音視頻的完整解決方案。它包含了非常先進的音頻/視頻編解碼庫libavcodec,爲了保證高可移植性和編解碼質量,libavcodec裏很多code都是從頭開發的。
官網:https://www.ffmpeg.org/
github地址:https://github.com/FFmpeg/FFmpeg
補充知識:音視頻格式的基本概念
音/視頻流
在音視頻領域,我們把一路音/視頻稱爲一路流。如我們小時候經常使用VCD看港片,在裏邊可以選擇粵語或國語聲音,其實就是CD視頻文件中存放了兩路音頻流,用戶可以選擇其中一路進行播放。
容器
我們一般把 MP4、 FLV、MOV等文件格式稱之爲容器。也就是在這些常用格式文件中,可以存放多路音視頻文件。以 MP4 爲例,就可以存放一路視頻流,多路音頻流,多路字幕流。
channel
channel是音頻中的概念,稱之爲聲道。在一路音頻流中,可以有單聲道,雙聲道或立體聲。
2.FFmpeg的組成
構成FFmpeg主要有三個部分。
第一部分
第一部分是三個作用不同的工具軟件,分別是:ffmpeg.exe,ffplay.exe,ffprobe.exe
- ffmpeg.exe:音視頻轉碼、轉換器
- ffplay.exe:簡單的音視頻播放器
- ffprobe.exe:簡單的多媒體碼流分析器
第二部分
第二部分是可以供開發者使用的SDK,爲各個不同平臺編譯完成的庫。如果說上面的四個工具軟件都是完整成品形式的玩具,那麼這些庫就相當於樂高積木一樣,我們可以根據自己的需求使用這些庫開發自己的應用程序。這些庫有:
- libavcodec:包含音視頻編碼器和解碼器
- libavutil:包含多媒體應用常用的簡化編程的工具,如隨機數生成器、數據結構、數學函數等功能
- libavformat:包含多種多媒體容器格式的封裝、解封裝工具
- libavfilter:包含多媒體處理常用的濾鏡功能
- libavdevice:用於音視頻數據採集和渲染等功能的設備相關
- libswscale:用於圖像縮放和色彩空間和像素格式轉換功能
- libswresample:用於音頻重採樣和格式轉換等功能
第三部分
第三部分是整個工程的源代碼,無論是編譯出來的可執行程序還是SDK,都是由這些源代碼編譯出來的。FFmpeg的源代碼由C語言實現,主要在Linux平臺上進行開發。FFmpeg不是一個孤立的工程,它還存在多個依賴的第三方工程來增強它自身的功能。在當前這一系列的博文/視頻中,我們暫時不會涉及太多源代碼相關的內容,主要以FFmpeg的工具和SDK的調用爲主。
3.下載安裝FFmpeg
Linux安裝的方式,請看博客 https://blog.csdn.net/Mind_programmonkey/article/details/104584444.
windows安裝方式:
在官網上我們可以找到"Download"頁面,該頁上可以下載FFmpeg的工具、庫和源代碼等。在選擇"Windows Packages"下的Windows Builds後,會跳轉到Windows版本的下載頁面:
在下載頁面上,我們可以看到,對於32位和64位版本,分別提供了三種不同的模式:static
、shared
和dev
static
: 該版本提供了靜態版本的FFmpeg工具,將依賴的庫生成在了最終的可執行文件中;作爲工具而言此版本就可以滿足我們的需求;
share
: 該版本的工具包括可執行文件和dll,程序運行過程必須依賴於提供的dll文件;
兩者的區別主要是在bin文件裏面,在share文件裏面的bin還有dll文件
dev
: 提供了庫的頭文件和dll的引導庫;
一般下載static
版本即可,下載之後,配置好環境變量即可。
但在windows和ubuntu上錄屏的話,還需要 screen capture recorder 官網
安裝完之後,在命令行輸入:
ffmpeg -list_devices true -f dshow -i dummy
查看到如上圖紅圈中的內容,則安裝正確
4.FFmpeg錄製音視頻
a.只錄制音頻
ffmpeg -f dshow -i audio="virtual-audio-capturer" -acodec libmp3lame window.mp3
上圖所示即在正常錄製。需要停止時按字母鍵“q”。
b.只錄制視頻
ffmpeg -f dshow -i video="screen-capture-recorder" -r 5 -vcodec libx264 -preset:v ultrafast -tune:v zerolatency MyDesktop.mp4
上圖所示即在正常錄製。需要停止時按字母鍵“q”。
c.錄製音視頻
ffmpeg -f dshow -i video="screen-capture-recorder" -f dshow -i audio="virtual-audio-capturer" -vcodec libx264 -acodec libmp3lame -s 1280x720 -r 15 temp.mkv
二、FFmpeg常用命令
首先查看一下FFmpeg處理音視頻的流程:
1.基本信息查詢命令
參數 | 說明 |
---|---|
-version | 顯示版本 |
-formats | 顯示可用的格式(包括設備) |
-demuxers | 顯示可用的demuxers |
-muxers | 顯示可用的muxers |
-devices | 顯示可用的設備 |
-codecs | 顯示libavcodec已知的所有編解碼器 |
-decoders | 顯示可用的解碼器 |
-encoders | 顯示所有可用的編碼器 |
-bsfs | 顯示可用的比特流filter |
-protocols | 顯示可用的協議 |
-filters | 顯示可用的libavfilter過濾器 |
-pix_fmts | 顯示可用的像素格式 |
-sample_fmts | 顯示可用的採樣格式 |
-layouts | 顯示channel名稱和標準channel佈局 |
-colors | 顯示識別的顏色名稱 |
2.抽取音視頻流並轉取視頻格式
a.抽取音頻流
ffmpeg -i input.mp4 -acodec copy -vn out.aac
- acodec: 指定音頻編碼器,copy 指明只拷貝,不做編解碼。
- vn: v 代表視頻,n 代表 no 也就是無視頻的意思。
b.抽取視頻流
ffmpeg -i input.mp4 -vcodec copy -an out.h264
- vcodec: 指定視頻編碼器,copy 指明只拷貝,不做編解碼。
- an: a 代表視頻,n 代表 no 也就是無音頻的意思。
c.合併音視頻流
ffmpeg -i out.h264 -i out.aac -vcodec copy -acodec copy out.mp4
d.轉格式
ffmpeg -i out.mp4 -vcodec copy -acodec copy out.flv
上面的命令表式的是音頻、視頻都直接 copy,只是將 mp4 的封裝格式轉成了flv。
3.視頻水印以及縮放,裁剪,倍速
a.添加水印
ffmpeg -i out.mp4 -vf "movie=icon.jpg,scale=64:48[watermask];[in][watermask] overlay=30:10 [out]" water.mp4
- -vf中的 movie 指定logo位置。scale 指定 logo 大小。overlay 指定 logo 擺放的位置。
b.刪除水印
先通過 ffplay 找到要刪除 LOGO 的位置
ffplay -i test.flv -vf delogo=x=806:y=20:w=70:h=80:show=1
使用 delogo 濾鏡刪除 LOGO
ffmpeg -i test.flv -vf delogo=x=806:y=20:w=70:h=80 output.flv
c.視頻縮放
ffmpeg -i out.mp4 -vf scale=iw/2:-1 scale.mp4
- -vf scale 指定使用簡單過濾器 scale,
- iw/2:-1 中的 iw 指定按整型取視頻的寬度。
- -1 表示高度隨寬度一起變化。
d.視頻裁剪
ffmpeg -i VR.mov -vf crop=in_w-200:in_h-200 -c:v libx264 -c:a copy -video_size 1280x720 vr_new.mp4
crop 格式:crop=out_w:out_h❌y
- out_w: 輸出的寬度。可以使用 in_w 表式輸入視頻的寬度。
- out_h: 輸出的高度。可以使用 in_h 表式輸入視頻的高度。
- x : X座標
- y : Y座標
如果 x和y 設置爲 0,說明從左上角開始裁剪。如果不寫是從中心點裁剪。
倍速播放
e.倍速播放
ffmpeg -i out.mp4 -filter_complex "[0:v]setpts=0.5*PTS[v];[0:a]atempo=2.0[a]" -map "[v]" -map "[a]" speed2.0.mp4
- -filter_complex 複雜濾鏡,[0:v]表示第一個(文件索引號是0)文件的視頻作爲輸入。setpts=0.5*PTS表示每幀視頻的pts時間戳都乘0.5 ,也就是差少一半。[v]表示輸出的別名。音頻同理就不詳述了。
- map 可用於處理複雜輸出,如可以將指定的多路流輸出到一個輸出文件,也可以指定輸出到多個文件。"[v]" 複雜濾鏡輸出的別名作爲輸出文件的一路流。上面 map的用法是將複雜濾鏡輸出的視頻和音頻輸出到指定文件中。
f.對稱視頻
ffmpeg -i out.mp4 -filter_complex "[0:v]pad=w=2*iw[a];[0:v]hflip[b];[a][b]overlay=x=w" duicheng.mp4
- hflip 水平翻轉
如果要修改爲垂直翻轉可以用vflip。
g.畫中畫
ffmpeg -i out.mp4 -i out1.mp4 -filter_complex "[1:v]scale=w=176:h=144:force_original_aspect_ratio=decrease[ckout];[0:v][ckout]overlay=x=W-w-10:y=0[out]" -map "[out]" -movflags faststart new.mp4
4.音視頻的拼接與裁剪
a.裁剪
ffmpeg -i out.mp4 -ss 00:00:00 -t 10 out1.mp4
- -ss 指定裁剪的開始時間,精確到秒
- -t 被裁剪後的時長。
b.合併
首先創建一個 inputs.txt 文件,文件內容如下:
file '1.flv'
file '2.flv'
file '3.flv'
然後執行下面的命令:
ffmpeg -f concat -i inputs.txt -c copy output.flv
5.視頻圖片互轉
a.視頻轉圖片
ffmpeg -i test.flv -r 1 -f image2 image-%3d.jpeg
- -r表示一秒選一幀圖片
b.視頻轉gif
ffmpeg -i out.mp4 -ss 00:00:00 -t 10 out.gif
c.圖片轉視頻
ffmpeg -f image2 -i image-%3d.jpeg images.mp4
6.直播相關
RTMP協議直播源:
- 湖南衛視 rtmp://58.200.131.2:1935/livetv/hunantv
- rtmp://cyberplayerplay.kaywang.cn/cyberplayer/demo201711-L1
a.推流
ffmpeg -re -i out.mp4 -c copy -f flv rtmp://server/live/streamName
b.拉流保存
ffmpeg -i rtmp://server/live/streamName -c copy dump.flv
c.轉流
ffmpeg -i rtmp://server/live/originalStream -c:a copy -c:v copy -f flv rtmp://server/live/h264Stream
7.ffplay播放YUV數據
播放YUV 數據
ffplay -pix_fmt nv12 -s 192x144 1.yuv
播放YUV中的 Y平面
ffplay -pix_fmt nv21 -s 640x480 -vf extractplanes='y' 1.yuv