android提取視頻多張圖片和視頻信息實(shí)例
話說2016年的直播比較火,2017年短視頻又火了。但對于開發(fā)者來說隱藏在這背后的技術(shù)才是我們所關(guān)心的,畢竟我們是靠技術(shù)吃飯的。
現(xiàn)在在安卓中多媒體服務(wù)比較強(qiáng)大,而與視頻有關(guān)的視頻基本處理技術(shù)有必要學(xué)習(xí)一下。我前段時間也在做有關(guān)視頻的一些需求,當(dāng)然也涉及本文的標(biāo)題內(nèi)容。
經(jīng)測試和研究發(fā)現(xiàn)在android中提取視頻圖片的方法只有MediaMetadataRetriever這個類比較靠譜簡單實(shí)用。當(dāng)然OpenGL-也可以做到哈?。ê笳卟徽归_介紹),
最后會把完整的demo獻(xiàn)上。
效果圖
技術(shù)需求
- 需求一:給你一個視頻提取第一個關(guān)鍵幀圖片作為視頻的封面,好處呢!?就是當(dāng)沒有播放的時候顯示視頻的首幀圖片,當(dāng)點(diǎn)擊播放按鈕時(或者自動播放)視頻和首幀圖片能連慣起來,是個很不錯的體驗(yàn)。
- 需求二:提取多張圖片,用戶可以滑動這些縮略圖來查看視頻的大體內(nèi)容,然后截取指定的視頻區(qū)域進(jìn)行編輯,這個需求類似:微信的小視頻編輯界面。這個會在第二篇文章中實(shí)現(xiàn)。實(shí)現(xiàn)高速度提取視頻圖片。
- 需求三:提取視頻的基本信息,比如寬高,視頻的時長。這個主要用于上傳視頻文件時的參數(shù)提交,然后展示的時候用視頻寬高做UI特效,比如不規(guī)則之美-瀑布流
調(diào)研
先看第3個問題,這個比較簡單。主要是MediaMetadataRetriever這個系統(tǒng)API類。
大體意思就是:給定一個媒體文件,它能檢索/輸出一些元數(shù)據(jù)和幀。有點(diǎn)意思哈,它加載了動態(tài)庫media_jni,可見它是一個十分接近底層的一個類。
技術(shù)實(shí)現(xiàn)-視頻基本信息的獲取
看一下類結(jié)構(gòu),有一些常量,作為一線碼農(nóng),我懂你哦。
//1.初始化 mMetadataRetriever = new MediaMetadataRetriever(); //2.設(shè)置視頻源文件mMetadataRetriever.setDataSource(file.getAbsolutePath()); //3.獲取視頻的寬 String w = mMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH); //獲取視頻的高 String h = mMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT); //獲取視頻的時長,ms mMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION); // 等等...一些其它屬性,比如媒體類型(3gp,mp4) ,視頻旋轉(zhuǎn)角度 //4.釋放資源,防止內(nèi)存泄漏,養(yǎng)成好習(xí)慣 mMetadataRetrieve.release();
我自己簡單了寫了一個util類,最后會獻(xiàn)上。
技術(shù)實(shí)現(xiàn)-獲取視頻關(guān)鍵幀
直接上代碼-我懂你
public Bitmap extractFrame(long timeMs) { //第一個參數(shù)是傳入時間,只能是us(微秒) //OPTION_CLOSEST ,在給定的時間,檢索最近一個幀,這個幀不一定是關(guān)鍵幀。 //OPTION_CLOSEST_SYNC 在給定的時間,檢索最近一個同步與數(shù)據(jù)源相關(guān)聯(lián)的的幀(關(guān)鍵幀) //OPTION_NEXT_SYNC 在給定時間之后檢索一個同步與數(shù)據(jù)源相關(guān)聯(lián)的關(guān)鍵幀。 //OPTION_PREVIOUS_SYNC 在給定時間之前檢索一個同步與數(shù)據(jù)源相關(guān)聯(lián)的關(guān)鍵幀。 // Bitmap bitmap = mMetadataRetriever.getFrameAtTime(timeMs * 1000, MediaMetadataRetriever.OPTION_CLOSEST_SYNC); Bitmap bitmap = null; for (long i = timeMs; i < fileLength; i += 1000) { bitmap = mMetadataRetriever.getFrameAtTime(i * 1000, MediaMetadataRetriever.OPTION_CLOSEST_SYNC); if (bitmap != null) { break; } } return bitmap; }
實(shí)用的時候直接: Bitmap bitmap = extractFrame(0); fileLength為視頻的時長( 毫秒數(shù)),返回bitmap ,然后你用可以操作bitmap了,比如保存到sd卡上,看你愛好了。有人問:咿,怎么for循環(huán)?。渴沁@樣的,我遇到過有時候你傳入的0,它有時候返回的bitmap為null,找不到關(guān)鍵幀,因此你需要多次遞增1秒獲取。
那么需求一的實(shí)現(xiàn)也OK了,但是有一點(diǎn)需要注意就是展示視頻的控件的寬和高和蓋在上面的圖片的控件的寬和高一樣才有你播放的時候就連貫了。
技術(shù)實(shí)現(xiàn)-獲取視頻多張圖片
我相信大家都能想到需求一的for循環(huán)一下不就可以了嗎,是的,沒錯。
首先提取圖片遇到高清視頻可能耗時,我經(jīng)過測試用vivo-xplay-5a ,1080高清視頻,提取一張圖片也就是mMetadataRetriever.getFrameAtTime()方法大概90-120ms之間。
- 方案:因此你需要一個工作線程+handler,每提取一張保存到sd卡中,然后用handeler發(fā)送保存圖片的路徑展示到UI上。demo中會展示到recycleview上,然后用glide圖片加載框架一張一張的顯示出來。當(dāng)然你也可以自己緩存mMetadataRetriever.getFrameAtTime 返回的bitmap,不過不建議這么做。
- 怎么循環(huán)提取,假設(shè)視頻文件長度是60s,需要提取10張圖片,也就是1張圖片代表了6s,60/10,
for (int i = 0; i < thumbnailsCount; i++) { if (stop) { metadataRetriever.release(); break; } long time = startPosition + interval * i; if (i == thumbnailsCount - 1) { if (interval > 1000) { String path = extractFrame(metadataRetriever, endPosition - 800, OutPutFileDirPath); sendAPic(path, endPosition - 800); } else { String path = extractFrame(metadataRetriever, endPosition, OutPutFileDirPath); sendAPic(path, endPosition); } } else { String path = extractFrame(metadataRetriever, time, OutPutFileDirPath); sendAPic(path, time); } }
stop是停止提取圖片的標(biāo)志,extractFrame方法就是metadataRetriever.getFrameAtTime()返回bitmap然后 bitmap.compress()返回保存到sd卡上的圖片路徑,最后sendAPic將提取的圖片路徑和時間加工為一個對象借助handler更新到UI線程中去,然后展示到recycleview上去,具體代碼可以參考demo。這里保存的圖片沒有進(jìn)行壓縮,第二篇文章會具體講到。
demo地址:https://github.com/ta893115871/MediaMetadataRetrieverDemo
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android開發(fā)之多媒體文件獲取工具類實(shí)例【音頻,視頻,圖片等】
- Android多媒體之VideoView視頻播放器
- Android多媒體教程之播放視頻的四種方法
- Android開發(fā)之MediaPlayer多媒體(音頻,視頻)播放工具類
- Android開發(fā)實(shí)現(xiàn)的IntentUtil跳轉(zhuǎn)多功能工具類【包含視頻、音頻、圖片、攝像頭等操作功能】
- Android中簡單調(diào)用圖片、視頻、音頻、錄音和拍照的方法
- android 獲取視頻,圖片縮略圖的具體實(shí)現(xiàn)
- Android獲取SD卡上圖片和視頻縮略圖的小例子
- Android編程獲取圖片和視頻縮略圖的方法
- Android如何獲取圖片或視頻略縮圖
- Android編程實(shí)現(xiàn)獲取多媒體庫視頻、音頻、圖片的方法
相關(guān)文章
android studio3.3.1代碼提示忽略大小寫的設(shè)置
這篇文章主要介紹了android studio3.3.1代碼提示忽略大小寫的設(shè)置,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-03-03Android 開機(jī)直接運(yùn)行app并當(dāng)做手機(jī)桌面的實(shí)例
今天小編就為大家分享一篇Android 開機(jī)直接運(yùn)行app并當(dāng)做手機(jī)桌面的實(shí)例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-08-08使用RoundedBitmapDrawable生成圓角圖片的方法
由于RoundedBitmapDrawable類沒有直接提供生成圓形圖片的方法,所以生成圓形圖片首先需要對原始圖片進(jìn)行裁剪,將圖片裁剪成正方形,最后再生成圓形圖片,具體實(shí)現(xiàn)方法,可以參考下本文2016-09-09Android利用OpenGLES繪制天空盒實(shí)例教程
這篇文章主要給大家介紹了關(guān)于Android利用OpenGLES繪制天空盒的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-08-08Android 通過TCP協(xié)議上傳指定目錄文件的方法
這篇文章主要介紹了Android 通過TCP協(xié)議上傳指定目錄文件的方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-03-03Android?ViewPager實(shí)現(xiàn)左右滑動翻頁效果
這篇文章主要為大家詳細(xì)介紹了Android?ViewPager實(shí)現(xiàn)左右滑動翻頁效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-12-12