幾行代碼利用Camera2實現(xiàn)點擊拍照,長按錄像桨菜!

寫在前面:關(guān)于什么是Camera2這里我就不多介紹了倒得,大家可以自行去百度夭禽。公司項目因為需要實現(xiàn)一個類似微信拍小視頻的功能,所以搗騰了一段時間的Camera2菩彬,期間遇到很多坑。今天這篇文章主要是記錄下我所遇到的問題以及對此做出的解決方法骗灶,同時為了方便耙旦,這里我也將此功能封裝成了library供大家使用。

一免都、先看一下效果圖:

capture.gif
record.gif

二氓鄙、3步集成到自己的項目中:

1.在AndroidManifest.xml申明所需要的權(quán)限:
(注:請確保進入Camera2的時候已經(jīng)擁有這三項權(quán)限了业舍,Android6.0需要動態(tài)去申請權(quán)限)

   <uses-permission android:name="android.permission.CAMERA" />
   <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
   <uses-permission android:name="android.permission.RECORD_AUDIO" />

2.在project的build.gradle和app的build.gradle下分別申明如下代碼:
project的build.gradle:

allprojects {
    repositories {
        maven { url 'https://jitpack.io' }//這句代碼
    }
}

app的build.gradle:

dependencies {
    compile 'com.github.CKTim:Camera2Record:v1.0.0'
}

3.打開Camera2:
因為每個人對拍完照或者錄完像后的處理都不一樣,所以這里我采用拍完跳轉(zhuǎn)activity的方式态罪,將拍照錄像后的地址傳遞給了下一個activity下面,當然這個activty界面邏輯什么的都是由你自己去編寫的,你可以對獲取到的圖片視頻地址進行你需要的編輯耗啦,例如再次壓縮或者重拍等操作:
getIntent().getStringExtra(Camera2Config.INTENT_PATH_SAVE_PIC);//獲取圖片地址
getIntent().getStringExtra(Camera2Config.INTENT_PATH_SAVE_VIDEO);//獲取視頻地址

如下用法:

    //配置Camera2相關(guān)參數(shù)帜讲,
    Camera2Config.RECORD_MAX_TIME = 10;//最長錄制時間
    Camera2Config.RECORD_MIN_TIME=2;//最短錄制時間
    Camera2Config.RECORD_PROGRESS_VIEW_COLOR=R.color.colorAccent;//錄制進度條顏色
    Camera2Config.PREVIEW_MAX_HEIGHT=1000;////最大高度預覽尺寸椒拗,默認大于1000的第一個
    Camera2Config.PATH_SAVE_VIDEO=;//視頻保存地址,注意需要以/結(jié)束在验,例如Camera2/
    Camera2Config.PATH_SAVE_PIC=;圖片保存地址腋舌,注意需要以/結(jié)束渗蟹,例如Camera2/
    Camera2Config.ENABLE_CAPTURE=true;//是否開啟拍照功能
    Camera2Config.ENABLE_RECORD=true;//是否開啟錄像功能
    //拍完照需要跳轉(zhuǎn)的activity赞辩,這個activity自己編寫诗宣,可以獲取到保存的視頻或者圖片地址
    Camera2Config.ACTIVITY_AFTER_CAPTURE = Camera2RecordFinishActivity.class;
    btnOpenCamera2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
               //進入Camera2界面
                Camera2RecordActivity.start(MainActivity.this);
            }
        });

三召庞、Camera2Record library的優(yōu)缺點:

缺點:
1.因為Camera2是安卓5.0以后的api来破,所以如果你的應用需要兼顧到5.0以下,這個library就不適合了诅诱。
2.錄制界面不好自定義娘荡,如果對界面沒有特殊需求的可以直接用驶沼,如果你對Camera2有一定了解或者界面需要自己自定義,我建議還是直接copy源碼去用大年,然后自己修改布局翔试,其實核心的代碼就一個Camera2RecordActivity而已。

優(yōu)點:
1.代碼總共4個類垦缅,無其他第三方庫失都,都是系統(tǒng)的api幸冻。
2.拍照和錄制都是參考谷歌官方Demo(這算優(yōu)點?)
2.錄制視頻小咳焚,質(zhì)量還可以,10s大概1.2M左右碑定,可能會存在波動。之前打算采用FFMPEG壓縮漫试,C++不行就沒再研究下去了碘赖,這里采用的是對MediaRecorder進行了一些配置,這里坑也很多播掷,后面我會分析出來歧匈。
3.可以進行預覽尺寸的配置砰嘁,對預覽進行了一些處理矮湘,防止預覽變形。
4.支持錄制中開啟閃關(guān)燈宫静,雙指縮放

四、踩過的坑:

關(guān)于預覽變形
預覽變形是很多人都會遇到的問題孤里,這里主要是因為預覽的尺寸和TextureView或者Surfaceview的尺寸不匹配導致的捌袜,例如你的TextureView是4:3比例的,然后用16:9的預覽尺寸的話炸枣,他就會變形了虏等,必須保證TextureView的尺寸和預覽尺寸是一樣的。像我在library中處理的一樣适肠,先設(shè)置了activity為全屏模式霍衫,包括導航欄,保證TextureView是覆蓋整個屏幕的侯养,然后每次獲取TextureView的寬高比敦跌,再從本機相機所支持的尺寸中獲取和TextureView一樣比例的,以此來避免變形的情況逛揩。

由于預覽尺寸過大導致卡頓
因為一個比例下他是有多個尺寸的柠傍,就像16:9這個比例麸俘,它有1280×720、1920×1080等等的尺寸从媚,如果尺寸過大拜效,就會給我們的預覽造成很大的卡頓,說是預覽預覽稻励,我覺得只要選擇一個合適的尺寸就行了望抽,針對這個,我在庫中也封裝了一個參數(shù)辑奈,即是
Camera2Config.PREVIEW_MAX_HEIGHT=1000
它表示會從在你屏幕的比例下的相機map中鸠窗,取出第一個高度超過1000的尺寸稍计,理論上我們只需要1280×720或者1920×1080這種預覽尺寸就行了,而不需要像在有些三星手機預覽達到3000多那么大硅则,這個看你自己自定義。

錄制視頻過大的問題
視頻壓縮最火的應該就是FFmpeg了吧揪垄,不過這個庫從編譯到運用都不是一件簡單的事,C++功底不行酷愧,弄了兩天沒弄出來就放棄了溶浴。。自帶的MediaRecorder錄制出來的視頻比較大谅将,雖然我們可以通過

        mMediaRecorder.setVideoEncodingBitRate(2500000);
        mMediaRecorder.setVideoFrameRate(20);
        mMediaRecorder.setVideoSize(width,height);

來對MediaRecorder進行一些配置以此來達到壓縮視頻的目的,但是這些方法并不是在所有機型上都是通用的隅熙,有時候會出現(xiàn)一些問題,就像在一加手機上弯淘,我設(shè)置了setVideoSize后就出現(xiàn)無法錄制的現(xiàn)象了,針對這個問題态鳖,我是采用如下方法代碼解決:

            // 這里有點投機取巧的方式浆竭,不過證明方法也是不錯的
            // 錄制出來10S的視頻,大概1.2M肌索,清晰度不錯,
            // 而且避免了因為手動設(shè)置參數(shù)導致無法錄制的情況
            // 手機一般都有這個格式CamcorderProfile.QUALITY_480P,
            // 因為單單錄制480P的視頻還是很大的站宗,
            // 所以我們在手動根據(jù)預覽尺寸配置一下videoBitRate,值越高越大
            // QUALITY_QVGA清晰度一般,不過視頻很小或辖,一般10S才幾百K
            // 判斷有沒有這個手機有沒有這個參數(shù)
            if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_480P)) {
                CamcorderProfile profile = CamcorderProfile.get(CamcorderProfile.QUALITY_480P);
                profile.videoBitRate = mPreviewSize.getWidth() * mPreviewSize.getHeight();
                mMediaRecorder.setProfile(profile);
                mMediaRecorder.setPreviewDisplay(new Surface(mTextureView.getSurfaceTexture()));
            } else if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_720P)) {
                CamcorderProfile profile = CamcorderProfile.get(CamcorderProfile.QUALITY_720P);
                profile.videoBitRate = mPreviewSize.getWidth() * mPreviewSize.getHeight();

                mMediaRecorder.setProfile(profile);
                mMediaRecorder.setPreviewDisplay(new Surface(mTextureView.getSurfaceTexture()));
            } else if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_QVGA)) {
                mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_QVGA));
                mMediaRecorder.setPreviewDisplay(new Surface(mTextureView.getSurfaceTexture()));
            } else if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_CIF)) {
                mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_CIF));
                mMediaRecorder.setPreviewDisplay(new Surface(mTextureView.getSurfaceTexture()));
            } else {
                mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
                mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
                mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
                mMediaRecorder.setVideoEncodingBitRate(2500000);
                mMediaRecorder.setVideoFrameRate(20);
                mMediaRecorder.setVideoSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
            }

點擊和長按的手勢處理問題
有兩種方式,第一種是監(jiān)聽ontouch事件县爬,在down事件發(fā)生時,延遲個幾百毫秒開啟長按監(jiān)聽線程耳高,在up事件進行統(tǒng)一處理,如果線程已經(jīng)開啟了碌燕,則判斷是長按事件愈捅,否則為點擊事件改鲫,其次壶冒,還有一種方式是使用系統(tǒng)自帶的GestureDetector去監(jiān)聽事件,這里我采用的是第一種方式咸作。

華為榮耀錄制小視頻截圖:


視頻截圖.png

五、總結(jié):

開源出來是好事桐智,但更重要的還是提供一種解決方法和思路給大家刊驴。這是我的第一次開源庫捆憎,可能還有很多做的不好的地方,歡迎大家提建議知举。
聯(lián)系方式:471497226@qq.com
github地址(含Demo和library):https://github.com/CKTim/Camera2Record

Camera2谷歌官方拍照Demo: https://github.com/googlesamples/android-Camera2Basic
Camera2谷歌官方錄像Demo: https://github.com/googlesamples/android-Camera2Video

確保開啟前app已經(jīng)獲取到上面所說的三個權(quán)限C烫帷!!H邗濉>辛臁!;锴浴7潘睢PB渌堋A肌!!!!!!其屏!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蛤袒,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子练般,更是在濱河造成了極大的恐慌晴及,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件及皂,死亡現(xiàn)場離奇詭異,居然都是意外死亡又跛,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門谱秽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來近哟,“玉大人,你說我怎么就攤上這事熙掺「В” “怎么了董瞻?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵斗躏,是天一觀的道長隧饼。 經(jīng)常有香客問我拐格,道長撞叨,這世上最難降的妖魔是什么法希? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮辽话,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘逮诲。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪就轧。 梳的紋絲不亂的頭發(fā)上乎莉,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天绒瘦,我揣著相機與錄音搏色,去河邊找鬼。 笑死九火,一個胖子當著我的面吹牛键痛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播痢缎,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼嵌洼,長吁一口氣:“原來是場噩夢啊……” “哼褐啡!你這毒婦竟也來了懂盐?” 一聲冷哼從身側(cè)響起莉恼,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤残家,失蹤者是張志新(化名)和其女友劉穎陪捷,沒想到半個月后舷丹,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡退个,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年精肃,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片帜乞。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖筐眷,靈堂內(nèi)的尸體忽然破棺而出黎烈,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布照棋,位于F島的核電站资溃,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏烈炭。R本人自食惡果不足惜溶锭,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望符隙。 院中可真熱鬧趴捅,春花似錦、人聲如沸霹疫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽丽蝎。三九已至猎拨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間屠阻,已是汗流浹背红省。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留国觉,地道東北人吧恃。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像蛉加,于是被迫代替她去往敵國和親蚜枢。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,509評論 25 707
  • 喜歡坐火車针饥,坐在火車上一站一站的慢慢南下或者北上厂抽。在旅途中,我既不屬于起點也不屬于終點丁眼。在只屬于我的時刻筷凤,我...
    Mystery阿翔閱讀 377評論 8 4
  • 接觸式,而非控制式的 互聯(lián)網(wǎng)多邊節(jié)點生存機制與關(guān)鍵通訊協(xié)議與接口API 沒有疆域苞七,只有管道沒有邊界藐守,只有核心
    咸叔說閱讀 316評論 0 2
  • http://www.reibang.com/p/42e11515c10f
    上海第一擼碼少年閱讀 172評論 0 0