Mediaplayer with two audio tracks - android

I have a problem with mediaplayer.
int inlevel=0;
int ingame=1;
MediaPlayer[] music = new MediaPlayer[2];
music[inlevel] = MediaPlayer.create(ctx, R.raw.jazz);
music[ingame] = MediaPlayer.create(ctx, R.raw.funky);
music[inlevel].start();
When the game begins I call a function for fadeout the music inlevel
fadeout();
music[inlevel].pause();
music[ingame].setVolume(volume, volume);
music[ingame].start();**
When the game finishs:
music[ingame].pause();
music[ingame].seekTo(0);
music[inlevel].start();
I don't need the music in level restart from the begin. I need that only for the music ingame.
Everything works good. I have only a problem the second time the game starts. Never happens at the first time.
At the begin of music in game(**), there is a very short piece of the music inlevel. Maybe it is the buffer of Mediaplayer.
I tried with two istance of Mediaplayer, but no sound.
Any solution? Thanks.

Related

MediaPlayer audio playing stops when app enters in background (OREO)

I have a manager class with an array of MediaPlayer instances which is the manager for playing audio on my app. Until now, it worked perfectly in background and keep playing the audio when the device is blocked.
Now, starting with Oreo devices, the audio playing stops. Is there an easy way of forcing the device to keep alive the MediaPlayer instance which is playing the audio? I mean a simple way without using services or without creating custom bars on the notification bar of the device, which are the options I found for now here in Stack Overflow. Probably must be a simpler way.
This is the code I used to play an audio until now:
MediaPlayer mPlayer = new MediaPlayer();
AssetFileDescriptor fileDescriptor = ApplicationContextProvider.getContext().getAssets().openFd(res.getUrl());
long start = fileDescriptor.getStartOffset();
long end = fileDescriptor.getLength();
mPlayer.setDataSource(fileDescriptor.getFileDescriptor(), start, end);
mPlayer.prepareAsync();
mPlayer.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
mPlayer.setLooping(loop);
fileDescriptor.close();
Use foreground Serive. For details on why the service will no longer work watch
https://www.youtube.com/watch?v=Pumf_4yjTMc
It clearly says that background services will be stopped. For tutorial on Foreground Services watch:
https://www.youtube.com/watch?v=FbpD5RZtbCc
Remember you would also need to learn the notification channels starting Oreo. This guy has introduced that too.

Focus on background Music when in a call

I am developing an app. I need to play the music when i am in a call. But i am facing with the problem that whenever i try to play the music in a call it is not that much loud as it is when there is no call.
Is there any way to control the background music when in a call. My music volume becomes softer when i am in a call but it becomes louder as soon as i end the call.
final AudioManager mAudioManager = (AudioManager) ctx
.getSystemService(AUDIO_SERVICE);
final int originalVolume = mAudioManager
.getStreamVolume(AudioManager.STREAM_MUSIC);
mAudioManager
.setStreamVolume(
AudioManager.STREAM_MUSIC,
mAudioManager
.getStreamMaxVolume(AudioManager.STREAM_MUSIC),
0);
mp = new MediaPlayer();
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
mAudioManager.setMode(AudioManager.MODE_NORMAL);
Class audioSystemClass = Class
.forName("android.media.AudioSystem");
Method setForceUse = audioSystemClass.getMethod(
"setForceUse", int.class, int.class);
// First 1 == FOR_MEDIA, second 1 == FORCE_SPEAKER. To go
// back to the default
// behavior, use FORCE_NONE (0).
setForceUse.invoke(null, 1, 1);
this is my code.
I see that you're trying to use the "force music streams to the loudspeaker"-method I posted in an answer to another question.
The problem is that during voice calls, music streams will follow the voice call's routing and ignore the FOR_MEDIA force flag. So what you perceive as lower volume is most likely the result of the music being played from the earpiece instead of from the loudspeaker.
To my knowledge, there's no way of routing the music to the loudspeaker during an ongoing call without also routing the voice call to the loudspeaker (i.e. using setSpeakerPhoneOn).
Depending on how your phone manufacturer/carrier implemented Android AudioPolicyService, some implementation lowers STREAM_MUSIC volume when MODE_IN_CALL/MODE_IN_COMMUNICATION is in session.
I have not tried this, but a likely workable solution is to use STREAM_VOICE_CALL instead of STREAM_MUSIC. Your audio stream should then play along with the in call audio stream just fine.

Binding MediaPlayer to be played at a specific time

When using MediaPlayer, I noticed that whenever my phone stucks, the MediaPlayer glitches and then continues playing from the position in the audio it glitched.
This is bad for my implementation since I want the audio to be played at a specific time.
If I have a song of 1000 millisecond length, I want is the ability to set MediaPlayer to start playing at some specific time t, and then exactly stop at at time t+1000.
This means that I actually need two things:
1) Start MediaPlayer at a specific time with a very small delay.
2) Making MediaPlayer glitches ignore the audio they glitched on and continue playing in order to finish the song on time.
The delay of the functions is very important to me and I need the audio to be played exactly(~) at the time it was supposed to be played.
Thanks!
You will need to use possibly mp.getDuration(); and/or mp.getCurrentPosition(); although it's impossible to know exactly what you mean by "I need the audio to be played exactly(~) at the time it was supposed to be played."
Something like this should get you started:
int a = (mp.getCurrentPosition() + b);
Thanks for the answer Mike. but unfortunately this won't help me. Let's say that I asked MediaPlayer to start playing a song of length 3:45 at 00:00. At 01:00 I started using the phone's resources, due to the heavy usage my phone glitched making MediaPlayer pause for 2 seconds.
Time:
00:00-01:00 - I heard the audio at 00:00-01:00
01:00-01:02 - I heard silence because the phone glitched
01:02-03:47 - I heard the audio at 01:00-03:45 with 2 second time skew
Now from what I understood MediaPlayer is a bad choice of usage on this problem domain, since MediaPlayer provides a high level API.I am currently experimenting with the
AudioTrack class which should provide me with what I need:
//Creating a new audio track
AudioTrack audioTrack = new AudioTrack(...)
//Get start time
long start = System.currentTimeMillis();
// loop until finished
for (...) {
// Get time in song
long now = System.currentTimeMillis();
long nowInSong = now - start;
// get a buffer from the song at time nowInSong with a length of 1 second
byte[] b = getAudioBuffer(nowInSong);
// play 1 second of music
audioTrack.write(b, 0, b.length);
// remove any unplayed data
audioTrack.flush();
}
Now if I glitch I only glitch for 1 second and then I correct myself by playing the right audio at the right time!
NOTE
I haven't tested this code but it seems like the right way to do it. If it will actually work I will update this post again.
P.S. seeking in MediaPlayer is:
1. A heavy operation that will surely delay my music (every millisecond counts here)
2. Is not thread safe and cannot be used from multiple threads (seeks, starts etc...)

Reload data source in android media player

I'm having a hard time with media player in android. Basically I try to play a song from my sd card which is downloading (some sort of streaming). So after the song was downloaded (20%) the song starts to play and if I leave it like this it works fine until the end. But if I try to seek at the end (over 20%) obviously it won't work because my seek position is over EOF file so I made this code inside a method
MediaPlayer mp = new MediaPlayer();
mp.setDataSource(sFilePath);
mp.prepare();
int offset = (progress * mp.getDuration()) / 100;
if (sCompleted) return;
sLastSeek = offset;
if (offset > sMediaPlayer.getDuration()) {
sMediaPlayer.reset();
sMediaPlayer.setDataSource(sFilePath);
sMediaPlayer.prepare();
} else {
sMediaPlayer.seekTo(offset);
}
Where sMediaPlayer is my mediaPlayer, and sFilePath is the file path. In theory the case I presented should be covered but when I seek over the file length the player is reseted (as the code says) but is not playing and this is very awkward and is over my powers.
Maybe the mediaPlayer stopt because it reaches the end of the song. Either start it again, refresh the file in steady intervals (say every 5 secs), or just use onCompletionListener. In the last case, when the file ends, you can reload the file and continue playing... mp.getCurrentPosition() to get where it left off playing.
I also noticed you refer to sMediaPlayer, but your MediaPlayer is defined as mp.

Android Media Player - Getting the number of times a video played in SetLooping

I am Playing the video in loop using set Looping(true) option and i will stop the media player after a particular event happened. It is working fine. But i want to know the number of times that my video got played in the loop.
MediaPlayer doesn't provide that information, you need to make it loop yourself and count how many times it has restarted. To do this, something in your app will need to extend OnCompletionListener and do something like
int count = 0;
public void onCompletion(MediaPlayer mediaPlayer) {
count++;
mediaplayer.seekTo(0);
mediaplayer.start();
}
And you need to set mediaPlayer.setLooping(false)

Categories

Resources