Saturday, May 25, 2013

Get the current frame in VideoView using MediaMetadataRetriever

Last exercise show a simple example to "Get image frame in video using MediaMetadataRetriever". In this exercise, we will play the video in a VideoView. Then capture the frame at the position when user click on the button.

Get the current frame in VideoView using MediaMetadataRetriever


layout file.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />
    <Button
        android:id="@+id/capture"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="capture video image" />
    <VideoView
        android:id="@+id/videoview"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>


MainActivity.java
package com.example.androidvideoview;

import android.graphics.Bitmap;
import android.media.MediaMetadataRetriever;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.MediaController;
import android.widget.Toast;
import android.widget.VideoView;

public class MainActivity extends Activity {
 
 MediaMetadataRetriever mediaMetadataRetriever;
 MediaController myMediaController;
 VideoView myVideoView;
 String viewSource = "/storage/sdcard0/DCIM/100MEDIA/VIDEO0009.mp4";

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  mediaMetadataRetriever = new MediaMetadataRetriever();
  mediaMetadataRetriever.setDataSource(viewSource);

  myVideoView = (VideoView) findViewById(R.id.videoview);
  myVideoView.setVideoURI(Uri.parse(viewSource));  
  myMediaController = new MediaController(this);
  myVideoView.setMediaController(myMediaController);

  myVideoView.setOnCompletionListener(myVideoViewCompletionListener);
  myVideoView.setOnPreparedListener(MyVideoViewPreparedListener);
  myVideoView.setOnErrorListener(myVideoViewErrorListener);

  myVideoView.requestFocus();
  myVideoView.start();
  
  Button buttonCapture = (Button)findViewById(R.id.capture);
  buttonCapture.setOnClickListener(new OnClickListener(){

   @Override
   public void onClick(View arg0) {
    
    int currentPosition = myVideoView.getCurrentPosition(); //in millisecond
    Toast.makeText(MainActivity.this,
      "Current Position: " + currentPosition + " (ms)", 
      Toast.LENGTH_LONG).show();
    
    Bitmap bmFrame = mediaMetadataRetriever
      .getFrameAtTime(currentPosition * 1000); //unit in microsecond
    
    if(bmFrame == null){
     Toast.makeText(MainActivity.this, 
       "bmFrame == null!", 
       Toast.LENGTH_LONG).show();
    }else{
     AlertDialog.Builder myCaptureDialog = 
       new AlertDialog.Builder(MainActivity.this);
     ImageView capturedImageView = new ImageView(MainActivity.this);
     capturedImageView.setImageBitmap(bmFrame);
     LayoutParams capturedImageViewLayoutParams = 
       new LayoutParams(LayoutParams.WRAP_CONTENT, 
         LayoutParams.WRAP_CONTENT);
     capturedImageView.setLayoutParams(capturedImageViewLayoutParams);
     
     myCaptureDialog.setView(capturedImageView);
     myCaptureDialog.show();
    }
    
   }});
 }

 MediaPlayer.OnCompletionListener myVideoViewCompletionListener = 
   new MediaPlayer.OnCompletionListener() {

  @Override
  public void onCompletion(MediaPlayer arg0) {
   Toast.makeText(MainActivity.this, "End of Video",
     Toast.LENGTH_LONG).show();
  }
 };

 MediaPlayer.OnPreparedListener MyVideoViewPreparedListener = 
   new MediaPlayer.OnPreparedListener() {

  @Override
  public void onPrepared(MediaPlayer mp) {
   
   long duration = myVideoView.getDuration(); //in millisecond
   Toast.makeText(MainActivity.this,
     "Duration: " + duration + " (ms)", 
     Toast.LENGTH_LONG).show();

  }
 };

 MediaPlayer.OnErrorListener myVideoViewErrorListener = 
   new MediaPlayer.OnErrorListener() {

  @Override
  public boolean onError(MediaPlayer mp, int what, int extra) {
   
   Toast.makeText(MainActivity.this, 
     "Error!!!",
     Toast.LENGTH_LONG).show();
   return true;
  }
 };

}


Note: To use MediaMetadataRetriever, minSdkVersion="10" have to be defined in AndroidManifest.xml.

17 comments:

  1. Superb one.. if possible suggest me how to get all frames of the video played.. Thanks in advance.

    ReplyDelete
  2. i'm getting screenshots, but screenshots are not saving in SDcard. please help me

    ReplyDelete
  3. hello Aditya,

    that means you have a bitmap. Please read Save file to SD Card.

    ReplyDelete
  4. i have tried that one , but i'm getting only black screen..

    ReplyDelete
  5. Thanks working for me on android 2.3 and above.
    But what is the solution if android version is 2.2 and below.








    ReplyDelete
  6. Please give the project as a demo

    ReplyDelete
  7. Hi i am using thic code but it crashes at:
    mediaMetadataRetriever = new MediaMetadataRetriever();
    mediaMetadataRetriever.setDataSource(viewSource);


    How can i fix it??

    ReplyDelete
  8. Is it possible to utilize a VideoView to record a video and preview it at the same time? Meaning, the user would click a button, the VideoView would instantly display the recorder within the VideoView and the user could see what was being recorded.

    ReplyDelete
  9. Hi Its not working when set path of remote url..
    Give bitmap Null..How can solve it...

    ReplyDelete
  10. I tried to retrieve sequence of images from video using following code.

    MediaMetadataRetriever retriever = new MediaMetadataRetriever();
    retriever.setDataSource(videofilepath);
    bitmap = retriever.getFrameAtTime(33333*i, MediaMetadataRetriever.OPTION_CLOSEST);

    The above code retrieve sequence of images in lollipop but it's not working in
    Marshmallow.In marsghmallow it reaped same images, Please can any one help me to retrieve images in marshmallow I'm in critical situation please help me.

    ReplyDelete
  11. hello Unknown,

    I have no device running marshmallow. But I test it on emulator, work as expected. Please refer Capture frames in VideoView using MediaMetadataRetriever.

    ReplyDelete
  12. hi friends, using MediaMetadataRetriever I can able to extract frams from video.But its not working in marshmallow. Can any one help me how to use MediaMetadataRetriever in marshmallow to extract frames from video.I'm in very big problem.



    ReplyDelete
  13. i need play to videoview in pop up menu..please help me..

    ReplyDelete
  14. Superb! could you please suggest how we can get all the frames from the video? Thank you.

    ReplyDelete