Reputation: 1037
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
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
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
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
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
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
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
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