android 獲取視訊某一時間的幀,並獲取bitmap
阿新 • • 發佈:2018-11-22
最近要做一個為視訊設定封面的功能,這裡展示一下簡單的demo。
demo效果
這裡直接將選取的視訊某一時間的bitmap顯示在視訊下方。上面是視訊,下面是所獲取那一幀的截圖。
具體程式碼
這裡的話主要是靠videoView來顯示視訊內容,seekBar來控制視訊的進度,使用MediaMetadataRetriever來獲取所選中進度的時間的視訊畫面。
佈局程式碼
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.se.palegreen.ui.activity.UploadActivity"> <VideoView android:id="@+id/vv_player" android:layout_width="match_parent" android:layout_height="wrap_content"/> <SeekBar android:id="@+id/sb_select" android:layout_width="match_parent" android:layout_height="wrap_content"/> <ImageView android:id="@+id/iv_head" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout>
具體程式碼
public class UploadActivity extends ActivitySupport { @BindView(R.id.vv_player) VideoView videoView; @BindView(R.id.sb_select) SeekBar sbVideo; @BindView(R.id.iv_head) ImageView ivHead; boolean isTouch = false; int totalTime; int currentTime; @Override protected int getLayoutResId() { return R.layout.activity_upload; } @Override protected void initData() { String mp4Path = Environment.getExternalStorageDirectory().getPath() + "/qwwz.mp4"; MediaMetadataRetriever mmr = new MediaMetadataRetriever(); mmr.setDataSource(mp4Path); videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { totalTime = videoView.getDuration();//毫秒 } }); sbVideo.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if(isTouch){ currentTime = (int)(((float) progress / 100) * totalTime); videoView.seekTo(currentTime); } } @Override public void onStartTrackingTouch(SeekBar seekBar) { isTouch = true; } @Override public void onStopTrackingTouch(SeekBar seekBar) { isTouch = false; //獲取第一幀影象的bitmap物件 單位是微秒 Bitmap bitmap = mmr.getFrameAtTime((long) (currentTime * 1000), OPTION_PREVIOUS_SYNC); ivHead.setImageBitmap(bitmap); } }); videoView.setVideoPath(mp4Path); }
}
問題
很簡單,這樣就完成了gif所展示的內容。
但是也有明顯不足之處:seekBar的progress範圍是0 - 100也就是視訊獲取截圖的最小時間單位是視訊總時間長度 / 100,這樣的單位是滿足不了長視訊的截圖要求的,這裡還需要優化,可以通過一個自定義view來實現。