I am using MediaPlayer to play a video in my app. The video takes a while to buffer and the videoview is blank for that time.
Is there a way to start the buffering when the user is in the previous screen, so that when he comes to the video playing screen, the video is ready to play?
Thanks
Chris
MediaPlayer lets you register an OnPreparedListener and an OnBufferingUpdateListener.
I've not tried it, but you could try calling MediaPlayer.prepareAsync() while the user is on the previous screen, then call .start() when the user moves to the right screen. Not sure where the media player can live during this process... You might need to do this all within one activity that you dynamically update when the user wants to see the video.
like below:
mp.setOnInfoListener(new OnInfoListener() {
#Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
if (what == MediaPlayer.MEDIA_INFO_BUFFERING_START) {
loadingDialog.setVisibility(View.VISIBLE);
} else if (what == MediaPlayer.MEDIA_INFO_BUFFERING_END) {
loadingDialog.setVisibility(View.GONE);
}
return false;
}
});
mediaPlayer.setOnInfoListener(new OnInfoListener() {
#Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
if (what == 703) {
// Not documented :(
// See http://stackoverflow.com/a/9622717/435605
isBuffering = true;
} else if (what == MediaPlayer.MEDIA_INFO_BUFFERING_END) {
isBuffering = false;
}
return false;
}
});
Related
The wording on this is most likely wrong, but I want to play this video without having the background black. If you look at this webpage you will see that the video is on a white background which leads me to believe that it is cropped or masked. Which view would I use to do this? I have tried both TextureView and VideoView but both have a black background by default.
I solve it with this:
#Override
public void onPrepared(MediaPlayer mp) {
mp.setOnInfoListener(new MediaPlayer.OnInfoListener() {
#Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
Log.d(TAG, "onInfo, what = " + what);
if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) {
// video started; hide the placeholder.
placeholder.setVisibility(View.GONE);
return true;
}
return false;
}
});
I think onPrepared just means the video is ready to play, but not means video started playing. If hide placeholder in onPrepared, the screen still show a black screen.
On my Note4 and Nexus, this solution works well.
Below is the piece of my code for handling the error of my video player. This error callback listener gets triggered for the first time only. After that, it's not capturing the error.
videoPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Toast.makeText(getApplicationContext(),
getResources().getString(R.string.msgPleaseNoConnection),
Toast.LENGTH_SHORT).show();
vVideoBufferLoader.setVisibility(View.INVISIBLE);
return false;
}
});
Note:
I tried returning true from that callback which means I handled the error. But it doesn't solve the problem too.
The goal of the MediaPlayer's OnErrorListener is to signal when an error has occurred, at which point the MediaPlayer object is in an end state.
http://developer.android.com/reference/android/media/MediaPlayer.html
If you are using the MediaPlayer constructor to 'reset' the object elsewhere in the code, you are essentially creating a new MediaPlayer object and saving it over the older one. If this is the case, then you also need to reassign the OnErrorListener.
Here's a short snippet of how I've been using OnErrorListener in my app:
private MediaPlayer.OnErrorListener vidVwErrorListener = new MediaPlayer.OnErrorListener() {
#Override
public boolean onError(MediaPlayer mp, int what, int extra) { //if there was an error in trying to play the intro video
if (tryLrgClip) { // If the larger-resolution clip failed to play, try playing the backup (lower-resolution) clip.
tryLrgClip = false;
trySmClip = true;
vidVwSplashView.setVideoURI(Uri.parse("android.resource://" + getPackageName() + "/" + SPLASH_VIDEOS));
vidVwSplashView.start();
} else { // If that didn't work either, give up on playing a video, and do something else
tryLrgClip = trySmClip = false;
vidVwSplashView.setVisibility(View.GONE);
//Something else
}
return true;
}
};
I hope that helps!
I tried the below code but did not worked for me
videoView.setOnInfoListener(new MediaPlayer.OnInfoListener() {
#Override
public boolean onInfo(MediaPlayer mediaPlayer, int what, int i2) {
if (what == mediaPlayer.MEDIA_INFO_BUFFERING_START){
progressBarWait.setVisibility(View.VISIBLE);
}
if (what == mediaPlayer.MEDIA_INFO_BUFFERING_END){
progressBarWait.setVisibility(View.GONE);
}
return false;
}
});
I have to get every state when videoview stop playing video due to buffering so that I can show progressbar for buffering state.
Any help would be appreciable.
I have a VideoView and I am streaming videos from a remote server. Most of the times It would play the videos very smoothly. But sometimes, it displays an error message "Sorry, This video cannot be played". I have a hunch that this is more on the supported video formats. However, I don't know which are the supported formats. My question is "How can I catch this error (e.g. Prevent the error message from appearing)"? I am using Android 2.2 on this project. Any advice would be greatly appreciated. :)
Try using setOnErrorListener: the documentation says If no listener is specified, or if the listener returned false, VideoView will inform the user of any errors., so I'm assuming if you set one and return true it will not show the user error.
The code I used for this:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
vView = (VideoView) findViewById(R.id.videoView1);
vSource = "android.resource://com.domain.android/"
+ R.raw.introductionportrait;
vView.setVideoURI(Uri.parse(vSource));
vView.setOnErrorListener(mOnErrorListener);
vView.requestFocus();
vView.start();
}
private OnErrorListener mOnErrorListener = new OnErrorListener() {
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
// Your code goes here
return true;
}
};
you can add code like below, it will close video view screen if any error occurred.
Also, it will not display default popup of saying video can't play :)
videoview.setOnErrorListener(new MediaPlayer.OnErrorListener() {
#Override
public boolean onError(MediaPlayer mediaPlayer, int i, int i1) {
finish();
return true;
}
});
I prefer setting listeners like this within onCreate method. Hopefully helps someone out
videoView.setOnErrorListener(new OnErrorListener () {
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Log.e(TAG, "Error playing video");
return true;
}
});
Here's the problem, I want to change play button to pause button when the video stream starts playing in videoview but I don't know how to detect that event?
There is a great article about MediaPlayer in here - http://www.malmstein.com/blog/2014/08/09/how-to-use-a-textureview-to-display-a-video-with-custom-media-player-controls/
You can set infoListener on your VideoView
setOnInfoListener(new MediaPlayer.OnInfoListener() {
#Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) {
// Here the video starts
return true;
}
return false;
}
I ended up using VideoView.setOnPreparedListener. This was enough to cover my problem (play button drawable change to pause)
accepted answer here is not 100% accurate.
sometimes onprepared is call 3 seconds before first frame is being rendered. i suggest having a callback on that event (MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START)
mMediaPlayer.setOnInfoListener(new MediaPlayer.OnInfoListener() {
#Override
public boolean onInfo(MediaPlayer mediaPlayer, int i, int i1) {
if (i == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START){
//first frame was bufered - do your stuff here
}
return false;
}
});
see media info documantaion for more callbacks of info/warning:
https://developer.android.com/reference/android/media/MediaPlayer.html#MEDIA_INFO_VIDEO_RENDERING_START
As far as I know, there is no event sent when video start playing in VideoView, but I can think of two options:
Create a version of VideoView by yourself, that sends event in those cases.
Use MediaController (which is default in VideoView)
If you want to follow option one - you can get the source of VideoView from here
isPlaying() can be called to test whether the MediaPlayer object is in the Started
Android MediaPlayer.isPlaying()
Another way to detect if videoview started is using videoView.getCurrentPosition(). getCurrentPosition() returns 0 if streaming not started.
protected Runnable playingCheck = new Runnable() {
public void run() {
while (true) {
if (vw.getCurrentPosition() != 0) {
// do what you want when playing started
break;
} else {
try {
Thread.sleep(250);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
};
Then call:
new Thread(playingCheck).start();
Please try this :
final Handler h = new Handler();
h.postDelayed( new Runnable() {
public void run() {
if (videoView.getCurrentPosition() != 0) {
((ProgressBar) rootView.findViewById(R.id.pgStreaming)).setVisibility(View.GONE);
} else {
h.postDelayed(this, 250);
}
}
}, 250);