I am having an odd issue where my audio file sometimes plays and sometimes does not play.
The catch is that when it decides to not play, the LogCat gives me this message:
Should have subtitle controller already set
This is my code to play the sound:
public void sound(){
//store the sound file name
String filename=f_fruit_ar.m4a;
//All sounds stored in assets folder
try{
AssetFileDescriptor afd = getAssets().openFd(filename);
MediaPlayer player = new MediaPlayer();
player.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
player.prepare();
player.start();
}
});
}
catch (Exception e) {
e.printStackTrace();
}
}
I think the problem is your not releasing the resources once player is finished playing you need to release the resources.
EXAMPLE:
public void sound(){
//store the sound file name
String filename=f_fruit_ar.m4a;
//All sounds stored in assets folder
try{
AssetFileDescriptor afd = getAssets().openFd(filename);
MediaPlayer player = new MediaPlayer();
player.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
player.prepare();
player.start();
player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
player.release();
}
});
}
catch (Exception e) {
e.printStackTrace();
}
}
Related
I an trying to play the mp3 file from asset folder but its getDuration method always return zero
try {
AssetFileDescriptor afd = getAssets().openFd("music.mp3");
mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
afd.close();
pause.setBackgroundResource(R.drawable.play);
finalTime = mediaPlayer.getDuration();
} catch (IOException e) {
e.printStackTrace();
}
Your mediaPlayer does not seems to be prepared, which can be done with mediaPlayer.prepare(); call, before calling getDuration.
I need the method that my app run multiple mp3s. Each mp3 must play after previous mp3.
I created method that play sound
void PlaySentence(String path){
try {
AssetFileDescriptor afd = getAssets().openFd(path);
player = new MediaPlayer();
player.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
player.prepare();
player.start();
}
catch (Exception ex)
{
if (BuildConfig.DEBUG)
Log.d(TAGName, ex.getMessage());
}
}
Then I call that function in OnCreate. I used while loop for playing all mp3 files. But sound mixed to each other. If I use loops and isPlaying method the application didn't respond.
while (currentMp3<totalMp3) {
if (!player.isPlaying()) {
PlaySentence();
}
}
Also I use below method for avoid of mixing sounds. It work for one mp3
player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
PlaySentence();
}
});
What is the best solution to do that?
You should use setOnCompletionListener, but declare your player as a class member, initalize it in onCreate, and don't create a new one for each mp3. PlaySentence should be something as:
void PlaySentence(String path){
try {
AssetFileDescriptor afd = getAssets().openFd(path);
player.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
player.prepare();
player.start();
}
catch (Exception ex)
{
if (BuildConfig.DEBUG)
Log.d(TAGName, ex.getMessage());
}
}
I am trying to play an mp3 music file when certain activity starts.
The "onCreate" method of the activity is the following code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_waiting_group_answer);
startSound();
}
and the "startSound" method is the following method:
private void startSound() {
AssetFileDescriptor afd = null;
try {
afd = getAssets().openFd("exploit_music.mp3");
player = new MediaPlayer();
player.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(),
afd.getLength());
// player.prepare();
player.start();
isPlaying = true;
} catch (IOException e) {
System.out.println("BUMMER");
}
}
When I tried to DEBUG the code, no exception was thrown, and the file (at the assets folder) was found.
Someone has an idea what should I do to make it work?
Thanks in advance!
According to MediaPlayer, the method prepare() should be called before the start() method. In the "State Diagram" image, it is described quite clearly.
For your question, just remove the // before the prepare(), implements the MediaPlayer.onPreparedListener to call the player.start(), and use player.setOnPreparedListener() to set the listener.
private void startSound() {
AssetFileDescriptor afd = null;
try {
afd = getAssets().openFd("exploit_music.mp3");
player = new MediaPlayer();
player.setOnPreparedListener(this);
player.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(),
afd.getLength());
player.prepare();
} catch (IOException e) {
System.out.println("BUMMER");
}
}
and in your activity
public class YourActivity extends Activity implements MediaPlayer.onPreparedListener{
#Override
public void onPrepared(Mediaplayer arg0){
arg0.start();
isPlaying = true;
}
}
Could be that your player was not prepared when you started it. In debug mode, there is time for it to be prepared.
Try to call start when the player is prepared:
private void startSound() {
AssetFileDescriptor afd = null;
try {
afd = getAssets().openFd("exploit_music.mp3");
player = new MediaPlayer();
player.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(),
afd.getLength());
player.setOnPreparedListener(new MediaPlayer.OnPreparedListener(){
public void onPrepared(MediaPlayer p1){
p1.start();
isPlaying = true;
}
}
);
} catch (IOException e) {
System.out.println("BUMMER");
}
}
I already have a .wav file in my directory.
at the same time i need to play it together with a mp3 file.
I used,
String recordedFile = "/storage/sdcard0/PINOYKARAOKE/1373597371359.wav";
MediaPlayer recordedSong = new MediaPlayer();
try{
recordedSong = MediaPlayer.create(ctx, Uri.fromFile(recordedFile));
recordedSong.prepare();
recordedSong.start();
}
catch(Exception e){
}
error:
creation failed and it throws IOException
Try to create raw folder and put your file there, use this
public void number(int num, Context ctx) {
AssetManager am;
try {
am = ctx.getAssets();
AssetFileDescriptor afd = am.openFd("android.resource://"+getPackageName+"/"+R.raw.your_file_name);
player = new MediaPlayer();
player.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(),
afd.getLength());
player.prepare();
player.start();
player.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
mp.release();
}
});
player.setLooping(false);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I've tried #aangwi answer but got FileNodeFoundException
final AssetFileDescriptor afd = myactivity.getResources().openRawResourceFd(R.raw.your_file);
final FileDescriptor fileDescriptor = afd.getFileDescriptor();
MediaPlayer player = new MediaPlayer();
try {
player.setDataSource(fileDescriptor, afd.getStartOffset(),
afd.getLength());
player.setLooping(false);
player.prepare();
player.start();
} catch (IOException ex) {
LOGGER.error(ex.getLocalizedMessage(), ex);
}
This works for me (Kotlin):
val mediaPlayer = MediaPlayer.create(
context,
R.raw.sound)
mediaPlayer.start()
I have a lot of short .mp3 files that I want to play one after the other.. I tried to use onCompletion event and start the next mp3, though this causes a brief gap between the 2 mp3s..
Here is the code:
void StartSound() {
mediaplayer = MediaPlayer.create(this, Uri.parse(FILE_PATH + counter + ".mp3"));
try {
mediaplayer.start();
mediaplayer.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
counter++;
try {
mp.reset();
mp.setDataSource(FILE_PATH + counter + ".mp3");
mp.prepare();
} catch (Exception e) {
e.printStackTrace();
}
mp.start();
}
});
} catch (Exception e) {
}
}
Is there a work around to this issue?
There's a workaround, but whether it's worth the trouble is up to you.
The basic idea is to decode the MP3 files to a PCM buffer, stitch them together in a byte array, and play with an AudioTrack. Seamless MP3 playback doesn't really exist with MediaPlayer. This could be a pain in the ass, though, and memory problems are likely if you're talking about full songs. For short clips, it may work, but SoundPool might be the better option.
If you're just trying to narrow the gap a bit, you can try preparing the following MediaPlayer objects before onCompletionListener. Instead of waiting to be done, prepare the next two so you can start playback faster. Then when you hit onCompletion, you can just flip which object you're using and start(). Crude double buffering, in a way.
Try this:
public class MainActivity extends Activity
{
private int[] tracks = {R.raw.explosion,R.raw.pianothingy_one,R.raw.car_horn_x};
int mCompleted = 0;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MediaPlayer mp = MediaPlayer.create(this, tracks[0]);
mp.setOnCompletionListener(new OnCompletionListener()
{
#Override
public void onCompletion(MediaPlayer mp)
{
mCompleted++;
mp.reset();
if (mCompleted < tracks.length)
{
try
{
AssetFileDescriptor afd = getResources().openRawResourceFd(tracks[mCompleted]);
if (afd != null)
{
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
afd.close();
mp.prepare();
mp.start();
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
else if (mCompleted>=tracks.length)
{
mCompleted =0;
try
{
AssetFileDescriptor afd = getResources().openRawResourceFd(tracks[mCompleted]);
if (afd != null)
{
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
afd.close();
mp.prepare();
mp.start();
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
else
{
mCompleted=0;
mp.release();
mp = null;
}
}
});
mp.start();