kivy
kivy

Reputation: 1037

Only loading video into VideoView without instantly playing

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?

Upvotes: 7

Views: 15594

Answers (7)

Hardik Vora
Hardik Vora

Reputation: 414

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>

Upvotes: 0

hansonchris
hansonchris

Reputation: 211

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();
    }
  });
}

Upvotes: 1

mironov
mironov

Reputation: 1

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();
    }
});

Upvotes: 0

Kai
Kai

Reputation: 39631

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.

Upvotes: 15

Sean Moore
Sean Moore

Reputation: 181

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

Upvotes: 0

sghael
sghael

Reputation: 1277

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;
            }
        }
    });

Upvotes: 7

CommonsWare
CommonsWare

Reputation: 1006614

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().

Upvotes: 5

Related Questions