使用JavaCV(ffmpeg)錄制視頻
JavaCV是對各種常用計算機視覺庫的封裝后的一組jar包,其中封裝了ffmpeg、OpenCV、libdc1394、OpenKinect、videoInput和ARToolKitPlus等計算機視覺編程人員常用庫的接口,可以通過其中的utility類方便的在包括Android在內(nèi)的Java平臺上調(diào)用這些接口。其中使用最多的應(yīng)該就是ffmpeg了。
起初Javacv是googlecode下面的一個項目,后續(xù)遷移到了github,并且包名也由com.googlecode.javacv
改為org.bytedeco.javacv
,網(wǎng)上的demo主要有兩個:
https://github.com/peirenlei/FFmpegRecorder
https://github.com/CrazyOrr/FFmpegRecorder
我是參考的上面那個,但是使用的是最新的版本1.3.1 。
集成過程中遇到很多問題,弄了一個多星期,在此就記錄一下。
集成:
https://github.com/bytedeco/javacv/releases
直接下載打包好的jar文件,如下圖
其中,javacpp.jar 和 javacv.jar是必須的兩個包,然后需要什么功能就添加額外的包。例如我需要用到ffmpeg進(jìn)行視頻錄制,則需要添加ffmpeg.jar和ffmpeg-android-arm.jar(打包的arm平臺so庫)。這里很方便的地方是,so庫文件都放在了jar文件里面,所以在集成的時候很簡潔明了。
把需要的jar包拷貝到項目的libs目錄下就可以直接使用了,
具體的使用則參考demo:https://github.com/brian512/AndroidDemo
下面就說一下遇到的坑:
在Android M平臺,會有異常
java.lang.UnsatisfiedLinkError: org.bytedeco.javacpp.avutil
這個問題對應(yīng)的issue:
https://github.com/bytedeco/javacv/issues/245
https://github.com/bytedeco/javacv/issues/579
我的解決方案是在這個帖子里找到的,但是遇到這個問題的人太多,導(dǎo)致這個問題的原因也比較多,例如版本、平臺等。而我遇到的這個情況是,在Android M以下版本都是正常的,所以不會是javacv的版本和打包的問題。
最終是通過ReLinker解決的,這是作者的說明:https://github.com/bytedeco/javacpp-presets/wiki/The-UnsatisfiedLinkError-X-File-%28a-real-experience%29
這是意料之外的,之前從未想過說System.loadLibrary("")
會不可靠,但是僅僅替換為ReLinker.recursively().loadLibrary()
,問題就迎刃而解。錄制時的參數(shù)設(shè)置
初始化Frame的參數(shù):
private int frameDepth = Frame.DEPTH_UBYTE; //DEPTH_UBYTE=8
private int frameChannels = 2;
FFmpegFrameRecorder支持很多格式的錄制,所以在進(jìn)行錄制時需要指定數(shù)據(jù)的格式,這些格式定義在org.bytedeco.javacpp.avutil.AV_PIX_FMT_XXX
,如果是相機預(yù)覽回調(diào)的YUV格式,則只需要用默認(rèn)的。如果是RGBA的則需要指定為mVideoRecorder.record(mFrameData, AV_PIX_FMT_RGBA);
錄制時需要注意視頻預(yù)覽尺寸與視頻錄制尺寸混淆,特別是相機預(yù)覽的寬高的顛倒問題。
- javacv庫比較大,所以盡量不用gradle的方式集成
- 錄制比較耗時
錄制540*960的視頻需要60ms左右,這個性能已經(jīng)不太能接受,所以盡量使用獨立的線程進(jìn)行錄制。如果后續(xù)發(fā)現(xiàn)優(yōu)化方法再更新,也歡迎留言補充!
CodeBlog是我做的一個編程技術(shù)學(xué)習(xí)客戶端,集成了很多技術(shù)網(wǎng)站上的博客,應(yīng)用寶詳情頁