i am displaying images and video in imageview and videoview but the issue is when video is
playing onpreparedlistener called but when video finish oncompletion listener not called
when videoview complete i increment the i for next video or images
also it gives me error in logcat like this but video is playing
10-29 20:12:47.770: E/MediaPlayer(3975): error (1, -2147483648)
private void nextVideo(String path){
mImageview.setVisibility(View.GONE);
if(mVideoview.getVisibility()==View.GONE){
mVideoview.setVisibility(View.VISIBLE);
}
controller = new MediaController(HomeActivityNewViewPager.this);
mVideoview.setVideoURI(Uri.parse(path));
mVideoview.setMediaController(null);
controller.setMediaPlayer(mVideoview);
mVideoview.setOnPreparedListener(new OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
mVideoview.start();
long duration = mVideoview.getDuration();
second=duration;
//handler.removeCallbacks(runnable);
//handler.postDelayed(runnable,second);
}
});
mVideoview.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
Log.v("video view completed","---"+i);
mp.reset();
if(automode){
if(i==myplaylistlocal.size() || i>myplaylistlocal.size())
{
String checkcount=spreferences.getString("roundcount", "");
Log.v("roundcount==Before Integer.parseInt","---->"+roundcount);
if(roundcount>=Integer.parseInt(checkcount))
{
roundcount=0;
Log.v("roundcount==After Integer.parseInt","---->"+roundcount);
updateplaylist();
}
i=0;
indexplus();
imagesautomode();
i++;
}
else if(i==myplaylistlocal.size()-1)
{
imagesautomode();
i++;
}
else{
imagesautomode();
}
}
else{
i++;
images();
}
}
});
mVideoview.setOnErrorListener(new OnErrorListener() {
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Log.v("Error in video playing","----->"+i);
return true;
}
});
}
Either way, the error referenced above is MEDIA_ERROR_UNKNOWN. If this video was made for this app, I would make sure that it is properly encoded for Android. Also make sure that is clearly defines its endpoint.
http://developer.android.com/reference/android/media/MediaPlayer.html#MEDIA_ERROR_UNKNOWN
this is a work around but could possbly work in your situation:
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
if(what == MediaPlayer.MEDIA_ERROR_UNKNOWN)
//ERROR UNKNOWN - COULD BE IMPROPERLY FORMATTED VIDEO {
//MOVE ON TO NEXT VIDEO
//DO LOGGING
}
}
Related
String fileName = "android.resource://" + getPackageName() + "/raw/oryx1001";
MediaController videoMediaController = new MediaController(this);
//mVideoView.setVideoPath( Uri.parse());
mVideoView.setVideoURI(Uri.parse(fileName));
mVideoView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
return true;
}
});
videoMediaController.setVisibility(View.GONE);
videoMediaController.setMediaPlayer(mVideoView);
mVideoView.setMediaController(videoMediaController);
mVideoView.requestFocus();
mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
//Close the progress bar and play the video
public void onPrepared(MediaPlayer mp) {
mVideoView.start();
}
});
mVideoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
//jump();
//System.out.println("dksadalkdakldsadlkadklsad");
mp.reset();
String fileName = "android.resource://" + getPackageName() + "/raw/oryx1001";
MediaController videoMediaController = new MediaController(MainActivity.this);
mVideoView.setVideoURI(Uri.parse(fileName));
mVideoView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
return true;
}
});
videoMediaController.setVisibility(View.GONE);
videoMediaController.setMediaPlayer(mVideoView);
mVideoView.setMediaController(videoMediaController);
mVideoView.requestFocus();
mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
// Close the progress bar and play the video
public void onPrepared(MediaPlayer mp) {
mVideoView.start();
}
});
}
});
simply my code 3gp file not working. it works on android oreo but not on lolipop device or samsung s6. is it api thing, or device thing for codecs supported? i tried everything mp4, 3gp nothin working.
E/MediaPlayer: Error (-38,0)
D/VideoView: Error: -38,0
/MediaPlayer: Error (1,-38)
You need to call mediaPlayer.start() in the onPrepared method by using a listener. You are getting this error because you are calling mediaPlayer.start() before it has reached the prepared state.
You have set setOnPreparedListener
mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
// Close the progress bar and play the video
public void onPrepared(MediaPlayer mp) {
mVideoView.start();
}
});
but you start wrong object mVideoView.start(); you should call
mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
// Close the progress bar and play the video
public void onPrepared(MediaPlayer mp) {
mp.start();//Change is hare ..
}
});
I'm trying to return the current state of the media player because I want to check that the media player has not loaded a song yet so I can provide a popup to choose an audio file.
Code in other class
public Sound(int buttonID, Activity _activity) {
super();
this.activity = _activity;
button = (Button) activity.findViewById(buttonID);
mp = new MediaPlayer();
}
Code to check if an audio file is loaded
sound.button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if(//no audio file loaded){
Intent intent = new Intent(MainActivity.this, Pop.class);
startActivityForResult(intent, PICK_AUDIO_REQUEST);
}
else if(sound.mp.isPlaying()) {
sound.mp.pause();
}
else{
sound.mp.seekTo(0);
sound.mp.start();
}
}
});
Using the answer, this is the code I came up with:
sound.button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
sound.mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
isPrepared = true;
}
});
if(!isPrepared){
Intent intent = new Intent(MainActivity.this, Pop.class);
startActivityForResult(intent, PICK_AUDIO_REQUEST);
}
else if(sound.mp.isPlaying()) {
sound.mp.pause();
}
else{
sound.mp.seekTo(0);
sound.mp.start();
}
}
});
Perhaps the following could help...
MediaPlayer.setOnBufferingUpdateListener(...);
public void onBufferingUpdate(MediaPlayer mp, int percent)
{
//while MediaPlayer's buffer been update
}
MediaPlayer.setOnPreparedListener(...);
public void onPrepared(MediaPlayer mp)
{
//while MediaPlayer is ready to play
}
MediaPlayer.setOnCompletionListener(...);
public void onCompletion(MediaPlayer mp)
{
//while MediaPlayer played to the end
}
MediaPlayer.setOnErrorListener(...);
public boolean onError(MediaPlayer mp, int what, int extra)
{
//while MediaPlayer has error ocurred
}
Also, your class must implement OnAudioFocusChangeListener, and create the following method
public boolean requestAudioFocus()
{}
public boolean abandonAudioFocus()
{}
public void onAudioFocusChange(int focusChange)
{}
You may considered to put your MediaPlayer into a Service class.
I'm afraid that there is no such method. You have to check it yourself. It's not too hard to follow MeidaManager state with the MediaPlayer's StateDiagram. The easiest way is to declare a boolean flag isPrepared / isReadyToPlay and set it to true in onPrepared() callback of the OnPreparedListener.
In my activity I have got a VideoView which should show a MediaController on touch. If the user touches quickly on Controller while VideoView is not following, after that user presses back button, then my app will be stuck.
setContentView(R.layout.activity_play_video_fullscreen);
videoView = (VideoView) findViewById(R.id.video_view);
urlString = getIntent().getStringExtra(EXTRA_URL);
videoView.setVideoURI(Uri.parse(urlString));
videoView.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
// video ready to play - hide progress bar
ProgressBar pb = (ProgressBar)findViewById(R.id.progress_bar);
pb.setVisibility(ProgressBar.INVISIBLE);
}
});
videoView.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
// video finished - terminate this activity
AxUtils.axLog(AxUtils.eDbgLogError, AxUtils.eDbgLogGroupDialer, String.format("PlayVideoFullsreenActivity.videoView.onCompletion(): Fullscreen video playback completed.\n"));
finish();
}
});
// install our own error handler
videoView.setOnErrorListener(new OnErrorListener() {
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
AxUtils.axLog(AxUtils.eDbgLogError, AxUtils.eDbgLogGroupDialer, String.format("PlayVideoFullsreenActivity.videoView.onError(): Playback failed. what=%d(%s) extra=%d(%s)\n",
what, what_toString(what), extra, extra_toString(extra)));
String reason;
if (what == MediaPlayer.MEDIA_ERROR_SERVER_DIED) {
reason = "Server connection lost.";
}
else {
reason = extra_toString(extra);
}
String message = String.format("Playback Failed. %s", reason);
Toast.makeText(PlayVideoFullscreenActivity.this.getApplicationContext(), message, Toast.LENGTH_SHORT).show();
finish();
return true;
}
});
// add playback controls
mediaController = new MediaController(this);
mediaController.setAnchorView(videoView.getRootView());
videoView.setMediaController(mediaController);
In your preparedListeners, disable and enable your media controllers. It should solve your issue.
Good luck.
I've developed an app which takes an advantage of the native Android's MediaPlayer. The source code of my class making use of Media Player is below.
The problem is that only on some devices after some miliseconds of playback (I hear only voice, the screen remains black) I keep getting error(100,0) which according to the documentation says
public static final int MEDIA_ERROR_SERVER_DIED
Media server died. In this case, the application must release the MediaPlayer object and instantiate a new one.
On forums I've found out that I need to reset the player every time I get it... but I get it after just a short moment and then it dies forever. I cannot reset the player every second since playback is useless. I cannot get why some devices have this problem and others not. The one that I know has Android OS > 4.0.
Of course, first init() and then showVideo() are getting called. The last onError with code 100 is then called. What's a potential solution to make the streams run continuously and not break?
public class NativePlayer extends Player implements OnBufferingUpdateListener,
OnCompletionListener, OnErrorListener, OnInfoListener {
private VideoView videoview;
private PlayerListener listener;
private MainActivity context;
private final Logger logger = LoggerFactory.getLogger(NativePlayer.class);
#Override
public void init(MainActivity activity) {
this.videoview = (VideoView) activity.findViewById(R.id.video);
context = activity;
}
#Override
public void showVideo(final String url, final PlayerListener _listener) {
listener = _listener;
videoview.setVisibility(View.VISIBLE);
try {
Uri video = Uri.parse(url);
videoview.setVideoURI(video);
} catch (Exception e) {
logger.error("Error playing video", e);
listener.onVideoError();
return;
}
videoview.setOnCompletionListener(this);
videoview.setOnErrorListener(this);
videoview.requestFocus();
videoview.setOnPreparedListener(new OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
videoview.start();
if (listener != null) {
listener.onVideoStarted();
}
}
});
}
#Override
public void onStop() {
stop();
}
private void stop() {
if (videoview == null) {
return;
}
if (videoview.isPlaying()) {
videoview.stopPlayback();
}
}
#Override
public void onDestroy() {
}
#Override
public void onCompletion(MediaPlayer mp) {
stop();
}
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
if (listener != null) {
listener.onVideoError();
}
return false;
}
#Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
if (listener != null) {
listener.onInfo(what, extra);
}
return false;
}
#Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
if (listener != null) {
listener.onBufferingUpdate(percent);
}
}
}
I had same problem (error 100, mediaplayer died, etc.).
I resolve it by using .stopPlayback(), and starting stream again.
Below is my part of code:
private void startWatchVideo(final string video_link) {
videoViewVA.setMediaController(new MediaController(this));
videoViewVA.setVideoURI(Uri.parse(video_link));
videoViewVA.requestFocus();
videoViewVA.setOnPreparedListener(new OnPreparedListener() {
public void onPrepared(MediaPlayer media) {
media.start();
}
});
videoViewVA.setOnErrorListener(new OnErrorListener() {
#Override
public boolean onError(MediaPlayer media, int what, int extra) {
if (what == 100)
{
videoViewVA.stopPlayback();
startWatchVideo(video_link);
}
return true;
}
});
}
On practice it looks like video is just slows down
Does anyone know if it's possible to detect when a VideoView is buffering?
I want to show a ProgressDialog when the video is buffering.
So far I tried using a OnPreparedListener, but that only works when the video is first loaded. If a video is playing and the user moves the scrub bar to a different point the video is still "prepared" even though it is buffering.
I also tried (I know this is awful) an AsyncThread that just busy waits on isPlaying():
private class BufferTask extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void...voids) {
final VideoView videoView = (VideoView)findViewById(R.id.video);
while (!videoView.isPlaying()) { }
return null;
}
protected void onPostExecute(Void v) {
// Hide the dialog here...
}
}
This doesn't work because as soon as you call start() a VideoView seems to be considered playing even though it is buffering.
The only solution I can think of is building a custom VideoView type class so I can access its MediaPlayer instance.
Any ideas? Thanks for reading.
Since API level 17, you can now access the InfoListener from the MediaPlayer:
final MediaPlayer.OnInfoListener onInfoToPlayStateListener = new MediaPlayer.OnInfoListener() {
#Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
switch (what) {
case MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START: {
mProgressBar.setVisibility(View.GONE);
return true;
}
case MediaPlayer.MEDIA_INFO_BUFFERING_START: {
mProgressBar.setVisibility(View.VISIBLE);
return true;
}
case MediaPlayer.MEDIA_INFO_BUFFERING_END: {
mProgressBar.setVisibility(View.GONE);
return true;
}
}
return false;
}
});
mVideoView.setOnInfoListener(onInfoToPlayStateListener);
I came with the following hack in order to not implement a custom VideoView. The idea is to check every 1 second if the current position is the same as 1 second before. If it is, the video is buffering. If not, the video is really playing.
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
public void run() {
int duration = videoView.getCurrentPosition();
if (old_duration == duration && videoView.isPlaying()) {
videoMessage.setVisibility(View.VISIBLE);
} else {
videoMessage.setVisibility(View.GONE);
}
old_duration = duration;
handler.postDelayed(runnable, 1000);
}
};
handler.postDelayed(runnable, 0);
videoMessage is just a TextView with the text "Buffering..." placed in the center of my VideoView.
Following code will show a buffering dialog every time the VideoView is buffering.
final ProgressDialog bufferingDialog;
bufferingDialog = ProgressDialog.show(context,
"Buffering", "Please wait", true, true);
VideoView videoView;
videoView = (VideoView) findViewById(R.id.video_view);
videoView.setVideoPath(path);
videoView.setMediaController(new MediaController(context));
videoView.requestFocus();
videoView.start();
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mp.setOnInfoListener(new MediaPlayer.OnInfoListener() {
#Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
if (what == MediaPlayer.MEDIA_INFO_BUFFERING_START)
bufferingDialog.show();
if (what == MediaPlayer.MEDIA_INFO_BUFFERING_END)
bufferingDialog.dismiss();
return false;
}
});
}
});
videoView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
bufferingDialog.dismiss();
return false;
}
});
VideoView showing Progress while Buffering.
Below code worked for me:
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(final MediaPlayer mp) {
mp.start();
mp.setOnInfoListener(new MediaPlayer.OnInfoListener() {
#Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
switch (what) {
case MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START: {
progressBar.setVisibility(View.GONE);
return true;
}
case MediaPlayer.MEDIA_INFO_BUFFERING_START: {
progressBar.setVisibility(View.VISIBLE);
return true;
}
case MediaPlayer.MEDIA_INFO_BUFFERING_END: {
progressBar.setVisibility(View.GONE);
return true;
}
}
return false;
}
});
}
});
I'm working on something similar, and couldn't come up with a great solution. Some interesting solutions were posted here that you should check out if you haven't seen them.
Anyway, I came up with the following hack that was hinted at in the above thread and works ok for now.
#Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
float temp = ((float)mp.getCurrentPosition() / (float)mp.getDuration())*100;
if(Math.abs(percent - temp) < 1) {
buffer_fail++;
if(buffer_fail == 15) {
//buffer failed
}
}
}
This worked for me
boolean b_start = true;
boolean b_end = true;
final MediaPlayer.OnInfoListener onInfoToPlayStateListener = new MediaPlayer.OnInfoListener() {
#Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
switch (what) {
case MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START: {
dialog1.setVisibility(View.GONE);
b_end = false;
b_start = false;
}
case MediaPlayer.MEDIA_INFO_BUFFERING_START: {
if (b_start){
dialog1.setVisibility(View.VISIBLE);
}
b_start = true;
}
case MediaPlayer.MEDIA_INFO_BUFFERING_END: {
if(b_end){
dialog1.setVisibility(View.VISIBLE);
}
b_end = true;
}
}
return false;
}
};
videoView.setOnInfoListener(onInfoToPlayStateListener);