In my application I get multiple paths from the user (1 to an image, 1 to an audio track, and 1 to a video) and store them in a database. When another Activity is started to view the files, there isn't a guarantee the files will still be at those paths or even exist at all, since the user chose them and may have deleted/moved them. Therefore, I need to be able to check if the files at those paths are valid.
My original plan was to simply catch any Exceptions thrown when constructing + setting up each object.
Here's what I'm using to view each:
Image - a Drawable
Audio - a MediaPlayer
Video - a VideoView
I would have handled each Exception by showing a dialog to the user
However, no Exceptions are thrown and instead I get different error messages
The VideoView shows its own dialog saying "Sorry, this video cannot be played"
The others go to LogCat:
04-10 23:34:43.174: ERROR/PlayerDriver(30): Command PLAYER_SET_DATA_SOURCE completed with an error or info PVMFErrNotSupported
04-10 23:34:43.174: ERROR/MediaPlayer(271): error (1, -4)
04-10 23:34:43.365: ERROR/MediaPlayer(271): Error (1,-4)
Any thoughts on how to get the state of MediaPlayer and VideoView or some other way to check the paths?
Thanks!
You can set OnErrorListener for VideoView and for MediaPlayer. If an error occurs - your listener will be called. Also, you can check both audio and video using MediaPlayer or using VideoView since it contains MediaPlayer to handle both anyway.
BTW, I think that the listener of VideoView is actually set in the MediaPlayer object within the VideoView
Related
I tried to play a local mp4 video file on my TV Box. I found a weird issue with MediaPlayer's playback speed. Here're my logs:
19:30:09.346 E/MediaPlayerManager: currentMediaPlayer's duration = 16021
19:30:09.715 E/MediaPlayerManager: setOnInfoListener - MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START
19:30:27.982 E/MediaPlayerManager: onComplete
The media duration was 16s, but it took about 18s to complete the video's playback. There's always a 2s delay before the onComplete listener got called. Does anyone have a solution for this?
After some experiments, I found out the issue was the large SurfaceView. If I replaced it with a TextureView or create the SurfaceView with smaller size, there's no extra delays.
P/s: I knew ExoPlayer, but for some specific reason, I could not use it.
I have started to learn android for 3 months and I have some problems with MediaPlayer.setDataSource
I want to get path of mp3 file in my raw directory, which is used for Media Player.
I have tried many ways but the app's still not working, even though the program doesn't crash or show problems. I have tried many solutions from other posts but it's still not working.
Here is my code:
String path = "android.resource://com.example.acer.appdemo/raw/emer2";
bleeding1.setDataSource(path);
bleeding1.prepareAsync();
bleeding1.start();
textView.setText(getString(R.string.Firstaid2));
count = 2;
The reason why I choose this, because I want to make a program that change audio every time I swipe left or right. So I want the program setDataSource again each time I swipe left or right, and the code above is one of my cases (The audio doesn't start everytimes I put a new path).
You have to reset the MediaPlayer (call bleeding1.reset()) before you can set a new data source.
See https://developer.android.com/reference/android/media/MediaPlayer.html for a helpful lifecyle diagram.
When I call getCurrentMillis in android media player it throws IllegalStateException and I see the following in the logs:
E/MediaPlayer: error (1, -12)
I have checked that the video is being correctly prepared.
It also causes OnErrorListener.onError to be called with args 1 and -12.
In the end I found that this was caused by trying to play a video which was only 48px wide. Since I had cropped the video in ffmpeg from a larger one I was able to use a bigger crop. When I increased the width to 64px, the error no longer occurred.
Maybe media player has an undocumented minimum allowed size or maybe the narrower crop was in violation of the H264 spec or something. Hope this helps someone.
hi ive been working on my app and have found a hurdle in an activity i just cant seem to overcome. the activity is essentially a large novelty piano with 8 keys that play sounds there are 6 buttons along the side that change the picture of the notes and the notes themselves, this i accomplished :-) now i would like to add a background song to each different set of notes (instruments) only when i do the app crashes i have set the mediaplayer at the top (globally?) using MediaPlayer mp; MediaPlayer mp2; etc and im using this in my code to check if any music is playing, stop it, release it, and then play the piece i want,
if(mp!=null&&mp.isPlaying()){
mp.stop();
mp.release();
}
if(mp2!=null&&mp2.isPlaying()){
mp2.stop();
mp2.release();
}
if(mp3!=null&&mp3.isPlaying()){
mp3.stop();
mp3.release();
}
mp3 = MediaPlayer.create(MusicActivity.this, R.raw.snaps);
mp3.setLooping(true);
mp3.start();
this again works but going from one to another and then back crashes the app. is there something else i should be doing? or is just an out of memory error?
EDIT--
Thanks to ranjk89 for his help
changed to soundpools but they wont stop ranjk89 suggests referring to the stream id and not the sound id looking for a little more clarification if possible i have
farmback =0;
drumback =0;
at the top then its loaded in oncreate using
drumback = sp.load(this, R.raw.snaps,1);
farmback = sp.load(this, R.raw.oldmacdonaldbeta,1);
and then way down, in the same method i change the button icons, not the same method i change all my other sounds for my notes i call
sp.stop(drumback);
sp.play(farmback, 1, 1, 0, -1, 1);
in one and
sp.stop(farmback);
sp.play(drumback, 1, 1, 0, -1, 1);
in another but there are 6 different instruments in total that all need a different backing track which should stop when the instrument is changed and play the one associated to it so something like
if (sp !=null && sp.isplaying()){
sp.stop();
sp.play(dumback);
}
but obviously this is not possible any help appreciated
My Initial reaction is, you shouldn't be using multiple MediaPlayer at all in the first place.
I would suggest you to use SoundPool as you can load all the media(audio) initially, once they are all loaded you can play them at will. Plus you won't have multiple players which would downsize the complexity of your code.
But if you do want to use Media player,
See this. But be aware that once you release you will not be able to reuse that instance of MediaPlayer. Even if you are using multiple MediaPlayers, do not call release on them unless you are sure you don't want to use them any more. Use stop()/prepare() combination.
For application doing too much work on the Main Thread,
If you either use a SoundPool or only one MediaPlayer and still bump in to the same issue, Use AsyncTask. Android dev site has a very good tutorial on this
I'm making an Android game-app in which you start as a little fish, and you need to eat smaller fish.
Each time you eat a smaller fish (by swimming against them), a sound plays. This is the code for playing the sound:
mp = MediaPlayer.create(GobbleFishGame.this, R.raw.bite);
if (!mPlaySound) {
return;
}
mp.start();
MPRelease();
This works well for the first few fishes. But after having eaten some fishes (the amount varies, but it's around 8-11 fishes), the game suddenly stops and I get the "Activity GobbleFish (in application GobbleFish) is not responding." error. I think it has something to do with too much resources being allocated to the MediaPlayer, therefore I've created a sub which releases mp's resources, and then creating a new MediaPlayer mp (this sub is called every time a fish is eaten). This is the code for the sub:
private void MPRelease(){
MPReleaseCount += 1;
if(MPReleaseCount==5){
mp.release();
mp = new MediaPlayer();
//mp = MediaPlayer.create(GobbleFishGame.this, R.raw.bite);
//mp.reset();
MPReleaseCount=0;
}
}
When MPReleaseCount is 5, mp gets released and recreated (so after 5 fishes are eaten).
I hoped that this would work, but it doesn't. I still have the problem that after some fishes are eaten (last time was 17 fishes, so MPRelease should have been called 3 times already), I get the "is not responding" error and I have to Force Close or Wait.
Can anyone tell me how I could do this to release the resources? Because I think that's the issue. I can't really tell if that's the issue because I don't get any error message in my LogCat in Eclipse. I did get this error report after Force Closing the app because of a "is not responding" error:
ANR in (my activity)
Reason: keyDispatchingTimedOut
Thanks in advance.
Don't release and create the MediaPlayer everytime you used it. Create it once with your audiosource and call a seekTo(0) in an OnCompletionListener(). Then play it again.
Also have a look at SoundPool http://developer.android.com/reference/android/media/SoundPool.html which is made for usecases like yours where you have to play the same audio multiple times. It stores the audio and plays it on demand. You also have a lower audio latency than with MediaPLayer.