Android 獲取視訊某一幀,並且設定為封面

JavaNoober發表於2018-01-19

最近要做一個為視訊設定封面的功能,這裡展示一下簡單的demo。

demo效果

這裡直接將選取的視訊某一時間的bitmap顯示在視訊下方。上面是視訊,下面是所獲取那一幀的截圖。

Android 獲取視訊某一幀,並且設定為封面

具體程式碼

這裡的話主要是靠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來實現。

Demo地址:github.com/JavaNoober/…

相關文章