2

I was able to make a video thumbnail using Glide if the source can be found in phone storage. However, code is not working if accessing a remote url instead of a local file.

        Glide.with(mContext)
                .load(message)
                .into(mVideoThumbnailView);

I am trying to access an mp4 file. Thanks for your advice.

Woppi
  • 5,303
  • 11
  • 57
  • 81

2 Answers2

1

I haven't tried with Glide. However as mentioned in this issue you'd need to write a custom model and DataFetcher to retrieve the image using Glide.

However, a workaround method that has worked for me is by using MediaMetadataRetriever. Here's how I retrieved the thumbnail bitmap without downloading the file:

public static Bitmap retriveVideoFrameFromVideo(String videoPath)
                throws Throwable
        {
            Bitmap bitmap = null;
            MediaMetadataRetriever mediaMetadataRetriever = null;
            try
            {
                mediaMetadataRetriever = new MediaMetadataRetriever();
                if (Build.VERSION.SDK_INT >= 14)
                    mediaMetadataRetriever.setDataSource(videoPath, new HashMap<String, String>());
                    else
                        mediaMetadataRetriever.setDataSource(videoPath);
             //   mediaMetadataRetriever.setDataSource(videoPath);
                bitmap = mediaMetadataRetriever.getFrameAtTime();
            }
            catch (Exception e)
            {
                e.printStackTrace();
                throw new Throwable(
                        "Exception in retriveVideoFrameFromVideo(String videoPath)"
                                + e.getMessage());

            }
            finally
            {
                if (mediaMetadataRetriever != null)
                {
                    mediaMetadataRetriever.release();
                }
            }
            return bitmap;
        }
OBX
  • 6,044
  • 7
  • 33
  • 77
  • Hello @OBX, where exactly do you use this? In an Activity (does it matter)? I'm currently applying this in an Adapter. Using this code, I am receiving an `java.lang.IllegalArgumentException 02-07 18:23:13.150 12240-12240/com.woppi.myapp W/System.err: at android.media.MediaMetadataRetriever.setDataSource(MediaMetadataRetriever.java:73) 02-07 18:23:13.150 12240-12240/com.woppi.myapp W/System.err: at com.woppi.myapp.RoomMessageAdapter.retrieveVideoFrameFromVideo(RoomMessageAdapter.java:635)` – Woppi Feb 07 '17 at 10:27
  • hmm, can be a permission issue, try this as well, http://stackoverflow.com/questions/27566480/mediametadataretriever-setdatasource-throws-illegalargumentexception and lemme know if you've already added permission! If you are using a higher api, downgrade the version and try without runtime permission – OBX Feb 07 '17 at 10:31
  • I have `INTERNET, WRITE_EXTERNAL_STORAGE, READ_EXTERNAL_STORAGE, RECORD_AUDIO, CAMERA` I'm using API level 21 but app should support 4.2.2 Jellybean and up. – Woppi Feb 07 '17 at 10:55
  • maybe MediaMetadataRetriever doesn't support https? have you used this retrieving files under SSL – Woppi Feb 07 '17 at 11:04
0

A VERY dirty way of doing this I found is by playing the first 100ms of the video and pausing it:

private void playSelectedVideoFrom(String url, boolean asThumbnail){

    try {
        Uri uri = Uri.parse(url);
        video.setVideoURI(uri);
        video.setOnPreparedListener(mediaPlayer -> {
            if (!asThumbnail)
                buffering.show();
            mediaPlayer.setLooping(false);
            mediaPlayer.start();
            mediaPlayer.setVideoScalingMode(MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT);
            if (asThumbnail) {
                mediaPlayer.seekTo(100);
                mediaPlayer.setOnSeekCompleteListener(mediaPlayer1 -> {
                    mediaPlayer1.pause();
                });
            }else {
                if (mediaPlayer.isPlaying()) buffering.hide();
            }
        });

    }catch (Exception ex){
        ex.printStackTrace();
    }
}

it worked for me.