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.
Related
I am developing an android application which will play live radio audio stream. I have implemented android media player for this purpose which constantly receives the audio data from a remote source.
The play button will show a buffering ProgressDialog to the user on click of it and will start the media player. I am successful in doing all so, but the only problem that I face is that I want to notify the user if the media player is unable to load audio content from the streaming server. Is there a timeout or some sort of an error that I can catch? Nothing is currently being thrown, if media player is unable to load audio content form server:
My code looks like:
public class MainActivity extends AppCompatActivity
{
Button playbtn_flat,stopbtn_flat;
static MediaPlayer mPlayer;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
playbtn_flat = (Button) findViewById(R.id.play_button);
stopbtn_flat = (Button) findViewById(R.id.stop_button);
playbtn_flat.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
listen_live("http://192.168.**.***:port/mountpoint");
}
});
stopbtn_flat.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
if (mPlayer != null && mPlayer.isPlaying()) {
mPlayer.stop();
}
}
});
}
void listen_live(String stream_ip) {
try {
final ProgressDialog progressDialog = ProgressDialog.show(MainActivity.this, "Please Wait...", "Buffering");
mPlayer = new MediaPlayer();
final MediaPlayer.OnPreparedListener onPreparedListener = new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
if (progressDialog != null && progressDialog.isShowing()) {
progressDialog.dismiss();
}
mp.start();
}
};
final MediaPlayer.OnErrorListener onErrorListener = new MediaPlayer.OnErrorListener() {
#Override
public boolean onError(MediaPlayer mp, int what, int extra)
{
Log.e("abc", String.format("Error(%s%s)", what, extra));
return false;
}
};
final Handler onPreparedHandle = new Handler() {
#Override
public void handleMessage(Message msg) {
mPlayer.setOnErrorListener(onErrorListener); // set onErrorListener
mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
onPreparedListener.onPrepared(mPlayer);
}
};
final String url = stream_ip;
new Thread() {
#Override
public void run() {
mPlayer = MediaPlayer.create(MainActivity.this, Uri.parse(url)); // create new instance of MediaPlayer and prepare it
onPreparedHandle.sendMessage(onPreparedHandle.obtainMessage()); // send message to main thread
}
}.start();
} catch (Exception e) {
Log.e("abc ", e.toString());
}
}
}
I want to set looping conditions and for the VideoView. This is what I am trying to achieve.
Video Starts and finishes if Edit Text is not selected.
If Video Start and EditText is selected then Video is set to looping.
If the user types into the EditText and presses button submit then looping set to false and the activity closes after video completes.
If EditText loses selection the video activity finishes on complete.
Here is the code but it's not working for me
mVideoView.setVideoPath(phone);
mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener()
{
#Override
public void onPrepared(final MediaPlayer mp) {
mVideoView.start();
if (mVideoView.isPlaying()) {
mp.setLooping(false);
}
}
}
);
CommentBox.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
mVideoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mp.setLooping(true);
}
});
}
}
});
mVideoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener()
{
#Override
public void onCompletion(MediaPlayer mp1) {
finish();
}
}
);
Problem is you have not called mediaplayer.start() after you set loop in onCompletionListener().
I executed the below code and it works fine here
Solution:
Create public bundle type of variable
b=new Bundle();
b.putBoolean("repeat", false);
v.setVideoURI(Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.ak));
v.requestFocus();
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (txt.getText().toString().length() > 0) {
b.putBoolean("repeat", false);
}
}
});
txt.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean has) {
if (has) {
b.putBoolean("repeat", true);
}
}
});
v.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
if (b.getBoolean("repeat") == true) {
mediaPlayer.setLooping(true);
mediaPlayer.start();
Toast.makeText(getApplicationContext(),String.valueOf(b.getBoolean("repeat")),Toast.LENGTH_LONG).show();
} else {
mediaPlayer.setLooping(false);
mediaPlayer.stop();
Toast.makeText(getApplicationContext(),String.valueOf(b.getBoolean("repeat")),Toast.LENGTH_LONG).show();
}
}
});
v.start();
In my code, I have a start/stop button.I am trying to play an audio clip from the raw folder. On completion of an audio clip, the start/stop button has to change from stop mode to start mode. I don't want to loop the audio. For this,I have called OnCompletionListener. However, the listener is called only once. If the media player is reset and created again, OnCompletionListener is no longer called.
public void playsong(View view) {
if (mySound != null)
{
if (!pause) {mySound.start();
btnStartStop.setBackgroundResource(R.drawable.button);
pause = true;
} else {
if (mySound.isPlaying()) {
mySound.stop();
do_it();
}
}
}
}
mySound.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mySound) {
do_it();
}
});
public void do_it() {
mySound.reset();
mySound = MediaPlayer.create(this, R.raw.a);
pause = false;
btnStartStop.setBackgroundResource(R.drawable.button2);
}
Try this code ?
In this example oncompletionlistner is called everytime
btnDemo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(objPlayer!=null){
if(objPlayer.isPlaying())
stopPlaying(objPlayer);
}
objPlayer = MediaPlayer.create(getApplicationContext(),R.raw.demoaudio);
if(objPlayer.isPlaying())
objPlayer.pause();
else
objPlayer.start();
Log.d("null", "Media Player started!");
if(objPlayer.isLooping() != true){
Log.d("null", "Problem in Playing Audio");
}
objPlayer.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
objPlayer.release();
objPlayer = null;
};
});
}
});
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
}
}
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