Controlling the streaming with MediaPlayer - android

i am using the below code to play song from server.
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(playUrl);
And i am calling start method from public void onPrepared(MediaPlayer mp) method.
But what happens is sometimes it's buffering 5 to 6% and starts playing and sometimes it buffers 40 or 60 or sometimes 80%.
And i am using prepareAsync () to prepare player. So, is there any way that I can play song after 5 or 6%?
thankx

try setting an update buffer listener and play the video after certain percentage.
Edited:
boolean mediaPrepared = false;
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnBufferingUpdateListener(){
void onPrepared(MediaPlayer mp){
mediaPrepared = true;
}
});
mp.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener(){
public void onBufferingUpdate(MediaPlayer mp, int percent){
if (!mediaPrepared){
mp.prepareAsync();
}
if (percent > 5){
mp.start();
}
}
});
And make sure to handle correctly the values of the mediaPrepared flag.
I'm not sure if this will work, but maybe you can use it as a hint. Good luck!

Related

E/MediaPlayer: error (1, -19)

I'm creating a simple soundboard to play sounds when a user clicks a button. Problem is, if the button is pressed enough ( usually around 10 times ) it will eventually stop playing and show the error E/MediaPlayer: error (1, -19)
what am I doing wrong? My code that plays the sound:
private void playSound(int soundID){
final MediaPlayer mp = MediaPlayer.create(this,soundID);
mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
mp.start();
}
});
}
You should use Soundpool. It's created exactly for playing short sound effects. And it's much simpler to use than MediaPlayer. MediaPlayer should only be used for playing regular/large music.
See here for example:
http://www.vogella.com/tutorials/AndroidMedia/article.html#tutorial-play-sounds-via-soundpool
Note: No need to use onTouch as in the example, you can just use onClick for simplicity.
Reason: "W/Choreographer: (let say) Frame time is 0.239384 ms in the future! Check that graphics HAL is generating vsync timestamps using the correct timebase."
i.e, there is a much gap between timestamps.
This problem can be removed by using setOnCompletionListener() within your OnClick() method like: `
#Overrid
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
// Get the {#link Word} object at the given position the user clicked on
Word word = words.get(position);
Log.v("NumbersActivity","Current word: "+word);
// Create and setup the {#link MediaPlayer} for the audio resource associated with the current word
MediaPlayer mMediaPlayer = MediaPlayer.create(NumbersActivity.this, word.getAudioResourceId());
// Start the audio file
mMediaPlayer.start();
// Keep timeStamp sync
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
mMediaPlayer.release();
}
});
}
`
private void playSound(int soundID){
final MediaPlayer mp = MediaPlayer.create(this,soundID);
mp.start();
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
mp.release();
}
});
}

Playing sounds in Android in certain order

In an Android app I am using MediaPlayer to play sound files.
This is just for personal use and will not be published.
I have several references to the sound files:
MediaPlayer dooropen = MediaPlayer.create(MainActivity.this, R.raw.dooropen);
MediaPlayer doorclose = MediaPlayer.create(MainActivity.this, R.raw.doorclose);
//...
For example the length of the dooropen sound clip is 2 seconds so after I play it I sleep for 2.5 seconds and then play the doorclose sound clip, like so
dooropen.start();
try{ Thread.sleep(2500); }catch(InterruptedException e){ }
doorclose.start();
The issue I am having is some of my sound files are not playing in the order I have them in.
There does not seem to be any reason why certain sound files do not play, because if I play them at the top of my onCreate() procedure they all play, it is only when I try and play them in a certain order.
You should implement the setOnCompletionListener() of the mediaplayer to get a callback when playback has completed and then load another audio file that needs to start playing.
See MediaPlayer Documentation about the mediaplayer state.
Yes you can use MediaPlayer along with oncompletionListener or you may try reseting the mediaplayer after one audio is completed. example code here. You may also use session id to keep track of which file was playing and which to start now.
mPlayer = new MediaPlayer();
//set other attributes here
mPlayer.setAudioSessionId(1);
mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
//check which audio session was playing and set new datasource and session
mPlayer.reset();
//set other data source here and different session id
}
});
Hope it solves your problem.
If you want to play sound in order, try this:
mp1.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mp2.start();
}
});
mp2.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mp3.start();
}
});
mp3.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mp1.start();
}
});

Android VideoView MediaPlayer OnInfoListener - events not fired

this following source code snippet is given:
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
mediaPlayer.setOnInfoListener(new MediaPlayer.OnInfoListener() {
#Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
if (what == MediaPlayer.MEDIA_INFO_BUFFERING_END){
activity.dismissDialog(DialogID.DIALOG_LOADING);
return true;
}
return false;
}
});
}
});
I am streaming HLS streams with Android 3.x+ devices and trying to hide a loading dialog once the buffering is completed.
The video streaming works, but the info events are never fired.
Any ideas?
I know its too late, But posting it for the users still seeking for the solution (This worked for me):
progressDialog.show();
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
mediaPlayer.setOnInfoListener(new MediaPlayer.OnInfoListener() {
#Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
if (what == MediaPlayer.MEDIA_INFO_BUFFERING_END){
progressDialog.dismiss();
return true;
} else if(what == MediaPlayer.MEDIA_INFO_BUFFERING_START){
progressDialog.show();
}
return false;
}
});
progressDialog.dismiss();
videoView.start();
}
});
You're right, the events are never fired. This is a known HLS bug that I don't think Google will fix.
This applies to the onInfo and the buffering events.
See https://code.google.com/p/android/issues/detail?id=42767 and https://code.google.com/p/googletv-issues/issues/detail?id=2
Sorry!
Not fully sure as to what the OP is asking, but here are some very untimely bits of information.
I wouldn't rely on onPrepared. I find it to be unreliable.
I have found the two most useful pieces of information for HLS streaming through the MediaPlayer are the duration of the video and the progress position of the video. You get both of these by listening to progress updates.
When the duration is greater than zero, you know the video is truly prepared and can be manipulate (scrub). When progress position changes, you know the video is done buffering and has commenced playback. This last item only works when the video is playing of course. The MediaPlayer tends to relay inaccurate information.
These pieces of information are mostly accurate and can usually be relied upon to be "fairly" timely. This timeliness varies from device to device.
onPrepared is called when the MediaPlayer is prepared to start buffering, not when the video is completely buffered. However, it is completely natural to dismiss the loading dialog from within the onPrepared method.
Also MEDIA_INFO_BUFFERING_END is used when MediaPlayer is resuming playback after filling buffers, so I do not think it should be something to use to dismiss the dialog. So this should work:
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
activity.dismissDialog(DialogID.DIALOG_LOADING);
}
});
You can able to set OnPreparedListener on videoView because its your object but if you checkout source of VideoView you will find that mMediaPlayer is its private member so any change that you do from external will not be applied to it.
As per your requirement you need buffering status so you can have thread or handler or some thing so you can update your UI to get buffer status there is one method
int percent = videoView.getBufferPercentage();
if(percent == 100){
// buffering done
}
You no need to go through setOnInfoListener
by overriding setOnPreparedListener method is enough. as in the api show
public void setOnPreparedListener (MediaPlayer.OnPreparedListener l)
Register a callback to be invoked when the media file is loaded and
ready to go.
so, you can dismiss your dialog inside setOnPreparedListener method is enough
like this
vv.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
handler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(MainActivity.this, "finish11", Toast.LENGTH_LONG).show();
}
});
}
});
If you want to show loading each time it's buffering (initial time or subsequent buffer underruns) just ensure to show it again:
// at the beginning
show
boolean onInfo(int what, int extra) {
switch (what) {
case MEDIA_INFO_BUFFERING_END:
"hide";
break;
case MEDIA_INFO_BUFFERING_START
"show":
}
}
So this event sequence will do as desired:
- whenever you start (setVideoURI or start): show
- onPrepared: just plug the info listener
- onInfo BUFFERING_END hide (it's playing)
- onInfo BUFFERING_START show (it's buffering again)
- onInfo BUFFERING_END hide (it's playing)
Update:
This is assuming the info events work. Of course.

Play remote video over slow network

Uri uri = Uri.parse(URLPath);
vv.setVideoURI(uri);
vv.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
//play next one
}
});
vv.setOnErrorListener(new OnErrorListener() {
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
return false;
}
});
Above code is for playing remote video with VideoView(vv).
It works while on high speed network.
But if low speed network is used such as 3G, playback will fail often, and outside the activity. t seems streaming is slower than user playback. The error code is (1,-1004).
What can I do to replace outside activity with pause and wait for streaming?
You can use Surface View for video streaming...this would work...
This link may help you Click Here

android MediaPlayer Looping

I am trying to play a looping Ogg file, I tried enabling setLooping(true) but that had no effect so I tried onCompletionListener and that's not working either, could someone clarify what I am doing wrong?
musicPlayer = MediaPlayer.create(mContext, R.raw.overworld);
musicPlayer.setVolume(musicVolume, musicVolume);
// musicPlayer.setLooping(true);
musicPlayer.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
musicPlayer.stop();
musicPlayer.seekTo(0);
musicPlayer.start();
Log.d("Sound Manager", "Song Completed");
}
});
Following is my play function,
public void playSong(int id) {
try {
stopSong();
musicPlayer = MediaPlayer.create(mContext, id);
musicPlayer.start();
} catch(Exception e) {
// Ignored
}
}
It's known that MediaPlayer is having problems with ogg files.
You could preferrably switch to another file format.
The other thing is, I would go on trying with setLooping(boolean) as it's most likely using the same scheme and its much more clearly.
Calling seekTo() if the MediaPlayer Object is stopped causes the MediaPlayer to be in an invalid state. You can call pause() instead but I wouldn't call any of these method, why not just seeking? I would guess if you remove the musicPlayer.stop() it will work.
remove ....
musicPlayer.stop();
from
onCompletion(MediaPlayer mp)
onCompletionListener() is not called if your MediaPlayer is set to looping, BUT if you don't have it set to looping, you can always just use a completion listener like so
#Override
public void onCompletion(MediaPlayer mp) {
if(!mp.isPlaying()) {
mp.start();
}
mp.seekTo(0);
}
You also shouldn't call stop() because that stops playback completely, and it doesn't make sense to seek in a video/song that you are not playing.

Categories

Resources