6

I got a question is it possible in Android to load the video data into a VideoView without it instantly starting to play? If so, how could I do that?

Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
kivy
  • 987
  • 2
  • 12
  • 17

7 Answers7

15

I was also thinking about showing a thunbnail as sghael stated. But I think this might result in reduced performance.

So what I'm doing now is just call

videoView.seekTo(1);

to forward the video to the first millisecond. This works fine for me and is fast to implement.

Kai
  • 38,985
  • 14
  • 88
  • 103
  • This wont work because video must be in playback state. – Danpe Nov 22 '14 at 19:26
  • `seekTo(1)` seems to be important to me. Without the seeking my video will display a random frame, usually the frame 1 sec later, at the very beginning when I invoked `start()` – jayatubi Jun 14 '15 at 03:01
7

I also wanted my VideoView to be in a paused state when the activity started. I could not find a simple way to have the VideoView show the first (non-black) frame of the video.

As a workaround, I created a bitmap thumbnail from the video resource, and then place that thumbnail as the background to the VideoView on activity start. Then when the Video begins playing, you only need to null out the background (or else your playing video is hidden behind your background image).

Bitmap thumbAsBitmap = null;
BitmapDrawable thumbAsDrawable = null;
private String current;

private void setupVideo() {
    try {

        setVideoFilePath();

        if (current == null || current.length() == 0) {
            Toast.makeText(PreviewMessage.this, "File URL/path is empty",
                    Toast.LENGTH_LONG).show();
        } else {
            keepScreenOn();

            mVideoView.setVideoPath(getDataSource(current));
            mVideoView.setOnCompletionListener(this);

            // create and place a thumbnail for the start state
            thumbAsBitmap = ThumbnailUtils.createVideoThumbnail(current, MediaStore.Images.Thumbnails.MINI_KIND);
            thumbAsDrawable = new BitmapDrawable(thumbAsBitmap);
            mVideoView.setBackgroundDrawable(thumbAsDrawable);

            mVideoView.pause();
            isPlaying = false;
        }

    } catch (Exception e) {
        if (mVideoView != null) {
            mVideoView.stopPlayback();
        }

    }
}

Then whereever your playbutton is, you can do something like

    mPlay.setOnClickListener(new OnClickListener() {
        public void onClick(View view) {
            if(!isPlaying){
                keepScreenOn();
                mPlay.setText("Pause");

                // make sure to null the background so you can see your video play
                mVideoView.setBackgroundDrawable(null);

                mVideoView.start();
                isPlaying = true;
            } else {
                mPlay.setText("Play");
                mVideoView.pause();
                isPlaying = false;
            }
        }
    });
sghael
  • 1,277
  • 1
  • 15
  • 18
4

VideoView will not start playback automatically, at least if you have a MediaController attached. You need to call start() to have it start playback. Hence, if you do not want it to start playback, do not call start().

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • The only problem I got now is that the Video doesn't show at all in the view, what I mean is that I would like it to show up (only the first frame) and have controls (play/pause, stop, forward and backward) right underneath it... – kivy Jul 23 '10 at 13:09
  • `MediaController` is a pop-up thing -- the user has to tap your `VideoView` for it to appear. If you want always-visible controls, you probably have to do that yourself. See http://github.com/commonsguy/vidtry for a project using `MediaPlayer` and a `SurfaceView` with a custom "controller" panel. With respect to the first frame, other than starting playback, you have no way to force that frame to display, AFAIK. – CommonsWare Jul 23 '10 at 14:37
  • how do i get to know when video is loaded ? So, that i can handle some other action or show something to user. – xaif Jan 05 '21 at 13:09
  • @xaif: I do not know what you consider "loaded" to mean, but there is https://developer.android.com/reference/android/widget/VideoView#setOnPreparedListener(android.media.MediaPlayer.OnPreparedListener) – CommonsWare Jan 05 '21 at 13:23
1

I have found that just doing VideoView.seekTo(n) isn't sufficient on all devices to show the video's first frame.

If all that you need to do is show the first frame, but not play the video, then you can just do this, which is helpful to render a video's thumbnail:

MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
mediaMetadataRetriever.setDataSource(context, uri);
Bitmap firstFrame = MediaMetadataRetriever.getFrameAtTime(0);
// Set firstFrame bitmap to ImageView...

However, to reliably show the first frame in cases where you want to play the video at some point after rendering, such as from a user interaction, my solution is to register an OnPreparedListener, and then call start(). I also register an OnInfoListener so that I can be notified when rendering starts. I then check if the info is indeed a "rendering start" event, and I check if this is the first time that the VideoView has started rendering. If so, I pause() and then seekTo(0).

Here's how that would look:

private void showFirstFrame(final VideoView videoView, Uri uri) {
  videoView.setVideoURI(uri);

  final AtomicBoolean showedFirstFrame = new AtomicBoolean(false);

  videoView.setOnInfoListener(new MediaPlayer.OnInfoListener() {
    @Override
    public boolean onInfo(MediaPlayer mp, int what, int extra) {
      // If this is our first time starting video rendering, pause and show first frame
      if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START
          && showedFirstFrame.compareAndSet(false, true)) {
        videoView.pause();
        videoView.seekTo(0);
      }

      return false;
    }
  });

  videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
    @Override
    public void onPrepared(MediaPlayer mp) {
      videoView.start();
    }
  });
}
hansonchris
  • 211
  • 4
  • 5
0

I suggest you for the following Code wherein I am running my application successfully

The Code is as Follows:

XML file:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#f0f0f0" >

    <Button
        android:id="@+id/btnVideoGallery"
        android:layout_width="75dp"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="15dp"
        android:text="@string/gallery" />

    <Button
        android:id="@+id/btnCancel"
        android:layout_width="120dp"
        android:layout_height="wrap_content"
        android:layout_below="@+id/btnVideoGallery"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="22dp"
        android:text="@string/cancel" />

    <TextView
        android:id="@+id/lblDisplayImage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/btnCancel"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="10dp"
        android:text="@string/below_this_text_video_will_be_displayed"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:textColor="#000000"
        android:textSize="13dp" />

    <VideoView
        android:id="@+id/vvDisplayVideo"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/lblDisplayImage"
        android:layout_marginTop="15dp" />

</RelativeLayout>

Java File:

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.MediaController;
import android.widget.VideoView;

public class VideoActivity extends Activity {

    private Button btnVideoGallery,btnCancel;
    private VideoView vvDisplayVideo;
    /** The Constant PICK_VIDEO. */
    private static final int PICK_VIDEO=1;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_video_options);

        btnVideoGallery=(Button)findViewById(R.id.btnVideoGallery);
        vvDisplayVideo=(VideoView)findViewById(R.id.vvDisplayVideo);
        btnCancel=(Button)findViewById(R.id.btnCancel);
        vvDisplayVideo.setVisibility(View.GONE);

        btnVideoGallery.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {

                Intent video=new Intent();
                video.setAction(Intent.ACTION_PICK);
                video.setType("video/*");
                startActivityForResult(video, PICK_VIDEO);

            }
        });

        btnCancel.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {

                Intent goStartUp=new Intent(VideoActivity.this, StartUpActivity.class);
                goStartUp.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(goStartUp);
                finish();
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // TODO Auto-generated method stub
        if (resultCode==Activity.RESULT_OK && requestCode == PICK_VIDEO) {

            vvDisplayVideo.setVisibility(View.VISIBLE);
            vvDisplayVideo.setVideoURI(data.getData());
            vvDisplayVideo.setFocusable(true);
            MediaController mc=new MediaController(this);
            vvDisplayVideo.setMediaController(mc);
            Log.i("True", "Executed");
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        // TODO Auto-generated method stub

        Intent goStartUp=new Intent(VideoActivity.this, StartUpActivity.class);
        goStartUp.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(goStartUp);
        finish();
        return super.onKeyDown(keyCode, event);
    }
}

Also you can modify the Manifest File as per your use:

<manifest>
    ...
    <uses-sdk...  />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.RECORD_VIDEO" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

    <uses-feature
        android:name="android.hardware.camera"
        android:required="false" />

    <application>...</application>

</manifest>
MMG
  • 3,226
  • 5
  • 16
  • 43
Hardik Vora
  • 414
  • 2
  • 9
0

i found it possible by starting the video, waiting for 1 millisecond and pausing:

mediaController = new MediaController(this);
//set the path for video here                        
Uri video = Uri.parse(tempPath);
//set the VideoView id in xml file here    
vv_item = (VideoView) findViewById(R.id.itemdetails_vv_item);
vv_item.setMediaController(mediaController);
vv_item.setVideoURI(video);
vv_item.setOnPreparedListener(new OnPreparedListener() {
    public void onPrepared(MediaPlayer mp) {
        //first starting the video, when loaded
        vv_item.start();
        //then waiting for 1 millisecond
        try {
            Thread.sleep(1);
        } 
        catch (InterruptedException e) {
            //     TODO Auto-generated catch block
            e.printStackTrace();
        }
        //then pausing the video. i guess it's the first frame
        vv_item.pause();
        //showing the control buttons here                          
        mediaController.show();
    }
});
mironov
  • 1
  • 2
0

I was using the MediaController for my play button so I used the below link answer combined with this background bitmap for my solution.

Event for VideoView playback state or MediaController play/pause

Community
  • 1
  • 1
Sean Moore
  • 181
  • 2
  • 4