Выбор обложки для видео с использованием панели поиска для просмотра предварительного просмотра кадра - PullRequest
0 голосов
/ 24 декабря 2018

У меня есть действие, в котором я использую MediaMetaDataRetriever, чтобы позволить пользователю выбрать обложку для видео.

ImageView отображает текущий кадр, который определяется SeekBar.

Я успешно достиг вывода, где пользователь может выбрать кадр, сдвинув панель поиска.

Проблема в том, что яхочу две вещи.

  1. Поскольку код работает в пользовательском интерфейсе / основном потоке, он немного нервный.Если я выполняю асинхронные задания каждый раз, когда изменяется ход выполнения seekbar, я получаю следующую ошибку.java.util.concurrent.RejectedExecutionException.Я понимаю, что это происходит из-за слишком большого количества асинктаков, чем то, что может обработать ThreadPoolExecuter (одновременно 13 потоков, максимум 128 потоков в очереди)

  2. Я хотел бы сделать это так, как в 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, так как слишком много асинктасов запускается, если асинктаки ​​выполняются каждый раз, когда изменяется прогресс панели поиска.

...