У меня есть действие, в котором я использую MediaMetaDataRetriever, чтобы позволить пользователю выбрать обложку для видео.
ImageView отображает текущий кадр, который определяется SeekBar.
Я успешно достиг вывода, где пользователь может выбрать кадр, сдвинув панель поиска.
Проблема в том, что яхочу две вещи.
Поскольку код работает в пользовательском интерфейсе / основном потоке, он немного нервный.Если я выполняю асинхронные задания каждый раз, когда изменяется ход выполнения seekbar, я получаю следующую ошибку.java.util.concurrent.RejectedExecutionException.Я понимаю, что это происходит из-за слишком большого количества асинктаков, чем то, что может обработать ThreadPoolExecuter (одновременно 13 потоков, максимум 128 потоков в очереди)
Я хотел бы сделать это так, как в Instagram, гдепользователь видит несколько кадров для длины панели поиска и текущий кадр для большого пальца панели поиска.вот так https://imgur.com/a/mOD90UF
Я думаю, что могу выделить несколько кадров из видео, а затем объединить их горизонтально в растровое изображение, которое я могу установить в качестве фона панели поиска.Правильно ли задан фон свойства seekbar для этого растрового изображения?
Кроме того, как я могу сделать его гладким, как у instagram?
В настоящее время я использую Android SeekBar для отображения текущего кадра выбранного видео с использованиемMediaMetadataRetriever для извлечения растрового изображения.(Это занимает довольно много времени, когда видео велико ... даже когда я извлекаю растровое изображение кадра каждую третью секунду, а не каждую секунду)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video_thumbnail_selector);
videoPath = "/storage/emulated/0/WhatsApp/Media/WhatsApp Video/VID-20181119-WA0002.mp4";
retriever = new MediaMetadataRetriever();
retriever.setDataSource(videoPath);
coverThumbList = new ArrayList<Bitmap>();
coverPreview = findViewById(R.id.cover_imageview);
btnOk = findViewById(R.id.btn_ok);
btnBack = findViewById(R.id.btn_back);
Const.setTypeFace(btnBack, this);
durationMs = getVideoDuration();
displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
widthInPixels = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 40, displayMetrics);
progressBarDialog = new ProgressBarDialog(this);
progressBarDialog.setMessage("Please wait loading thumbnails...");
progressBarDialog.setCancelable(false);
seekBar = findViewById(R.id.seekbar);
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
setPreviewImage(seekBar.getProgress());
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
setPreviewImage(seekBar.getProgress());
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
setPreviewImage(seekBar.getProgress());
}
});
seekBar.setMax(durationMs);
populateCoverThumbList();
setPreviewImage(0);
}
private int getVideoDuration(){
int durationMs = 0;
if(!TextUtils.isEmpty(videoPath) && retriever != null){
String strDurationMs = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
durationMs = Integer.parseInt(strDurationMs);
}
return durationMs;
}
private void setPreviewImage(int seekbarProgress){
Bitmap bitmap = retriever.getFrameAtTime(seekbarProgress * 1000);
coverPreview.setImageBitmap(bitmap);
//Drawable drawable = new BitmapDrawable(getResources(), Bitmap.createScaledBitmap(bitmap, widthInPixels, widthInPixels, true));
Drawable drawable = new BitmapDrawable(getResources(), Bitmap.createScaledBitmap( getCenterCropBitmap(bitmap), widthInPixels, widthInPixels, true));
seekBar.setThumb(drawable);
}
Панель поиска запаздывает, поскольку код выполняется в главном потоке.AsyncTasks аварийно завершает работу с java.util.concurrent.RejectedExecutionException, так как слишком много асинктасов запускается, если асинктаки выполняются каждый раз, когда изменяется прогресс панели поиска.