国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

android提取視頻多張圖片和視頻信息實例

2019-10-23 18:27:50
字體:
來源:轉載
供稿:網友

話說2016年的直播比較火,2017年短視頻又火了。但對于開發者來說隱藏在這背后的技術才是我們所關心的,畢竟我們是靠技術吃飯的。

現在在安卓中多媒體服務比較強大,而與視頻有關的視頻基本處理技術有必要學習一下。我前段時間也在做有關視頻的一些需求,當然也涉及本文的標題內容。

經測試和研究發現在android中提取視頻圖片的方法只有MediaMetadataRetriever這個類比較靠譜簡單實用。當然OpenGL-也可以做到哈!(后者不展開介紹),

最后會把完整的demo獻上。

效果圖

android提取視頻圖片,android視頻提取圖片,android提取視頻信息

技術需求

  1. 需求一:給你一個視頻提取第一個關鍵幀圖片作為視頻的封面,好處呢!?就是當沒有播放的時候顯示視頻的首幀圖片,當點擊播放按鈕時(或者自動播放)視頻和首幀圖片能連慣起來,是個很不錯的體驗。
  2. 需求二:提取多張圖片,用戶可以滑動這些縮略圖來查看視頻的大體內容,然后截取指定的視頻區域進行編輯,這個需求類似:微信的小視頻編輯界面。這個會在第二篇文章中實現。實現高速度提取視頻圖片。
  3. 需求三:提取視頻的基本信息,比如寬高,視頻的時長。這個主要用于上傳視頻文件時的參數提交,然后展示的時候用視頻寬高做UI特效,比如不規則之美-瀑布流

調研

先看第3個問題,這個比較簡單。主要是MediaMetadataRetriever這個系統API類。

android提取視頻圖片,android視頻提取圖片,android提取視頻信息

大體意思就是:給定一個媒體文件,它能檢索/輸出一些元數據和幀。有點意思哈,它加載了動態庫media_jni,可見它是一個十分接近底層的一個類。

技術實現-視頻基本信息的獲取

看一下類結構,有一些常量,作為一線碼農,我懂你哦。

android提取視頻圖片,android視頻提取圖片,android提取視頻信息

//1.初始化   mMetadataRetriever = new MediaMetadataRetriever();//2.設置視頻源文件mMetadataRetriever.setDataSource(file.getAbsolutePath());//3.獲取視頻的寬String w = mMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH); //獲取視頻的高String h = mMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT); //獲取視頻的時長,msmMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);// 等等...一些其它屬性,比如媒體類型(3gp,mp4) ,視頻旋轉角度//4.釋放資源,防止內存泄漏,養成好習慣 mMetadataRetrieve.release();

我自己簡單了寫了一個util類,最后會獻上。

技術實現-獲取視頻關鍵幀

直接上代碼-我懂你

 public Bitmap extractFrame(long timeMs) {    //第一個參數是傳入時間,只能是us(微秒)    //OPTION_CLOSEST ,在給定的時間,檢索最近一個幀,這個幀不一定是關鍵幀。    //OPTION_CLOSEST_SYNC  在給定的時間,檢索最近一個同步與數據源相關聯的的幀(關鍵幀)    //OPTION_NEXT_SYNC 在給定時間之后檢索一個同步與數據源相關聯的關鍵幀。    //OPTION_PREVIOUS_SYNC 在給定時間之前檢索一個同步與數據源相關聯的關鍵幀。// 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;  }

實用的時候直接: Bitmap bitmap = extractFrame(0); fileLength為視頻的時長( 毫秒數),返回bitmap ,然后你用可以操作bitmap了,比如保存到sd卡上,看你愛好了。有人問:咿,怎么for循環啊?是這樣的,我遇到過有時候你傳入的0,它有時候返回的bitmap為null,找不到關鍵幀,因此你需要多次遞增1秒獲取。
那么需求一的實現也OK了,但是有一點需要注意就是展示視頻的控件的寬和高和蓋在上面的圖片的控件的寬和高一樣才有你播放的時候就連貫了。

技術實現-獲取視頻多張圖片

我相信大家都能想到需求一的for循環一下不就可以了嗎,是的,沒錯。

首先提取圖片遇到高清視頻可能耗時,我經過測試用vivo-xplay-5a ,1080高清視頻,提取一張圖片也就是mMetadataRetriever.getFrameAtTime()方法大概90-120ms之間。

  1. 方案:因此你需要一個工作線程+handler,每提取一張保存到sd卡中,然后用handeler發送保存圖片的路徑展示到UI上。demo中會展示到recycleview上,然后用glide圖片加載框架一張一張的顯示出來。當然你也可以自己緩存mMetadataRetriever.getFrameAtTime 返回的bitmap,不過不建議這么做。
  2. 怎么循環提取,假設視頻文件長度是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是停止提取圖片的標志,extractFrame方法就是metadataRetriever.getFrameAtTime()返回bitmap然后 bitmap.compress()返回保存到sd卡上的圖片路徑,最后sendAPic將提取的圖片路徑和時間加工為一個對象借助handler更新到UI線程中去,然后展示到recycleview上去,具體代碼可以參考demo。這里保存的圖片沒有進行壓縮,第二篇文章會具體講到。

demo地址:https://github.com/ta893115871/MediaMetadataRetrieverDemo

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。

 

注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 长治县| 和田县| 玛纳斯县| 万年县| 乌兰察布市| 霍林郭勒市| 望城县| 遂宁市| 清丰县| 安龙县| 梨树县| 疏勒县| 肇庆市| 遵义市| 清水县| 平阳县| 绿春县| 宁城县| 芒康县| 兴山县| 隆德县| 襄樊市| 东阳市| 靖远县| 新邵县| 翁牛特旗| 揭东县| 铅山县| 长春市| 靖安县| 新乐市| 陇川县| 南平市| 航空| 忻州市| 五台县| 旺苍县| 尚义县| 怀宁县| 建宁县| 阜阳市|