android - Why MediaPlayer delayes in playing mp3 audio? - java

I made a small app to practice audio playing in android using MediaPlayer, the app works great but there is a small delay of 1 second after clicking the play button and it's noticeable, I noticed this happens only when starting the audio file, when paused it resumes immediately with no delay,I googled around and seen people suggests using SoundPool instead of MediaPlayer but SoundPool is recommended for short audio clips while my app is playing a full song, what's the cause of this delay? is there a fix or work around this issue?
Here's my code:
private MediaPlayer mMediaPlayer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mMediaPlayer = MediaPlayer.create(this,R.raw.this_is_america);
Button btnPlay = findViewById(R.id.btnPlay);
Button btnPause = findViewById(R.id.btnPause);
Button btnStop = findViewById(R.id.btnStop);
btnPlay.setOnClickListener(this);
btnPause.setOnClickListener(this);
btnStop.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnPlay:
Toast.makeText(getApplicationContext(), "Playing song",
Toast.LENGTH_SHORT).show();
mMediaPlayer.start();
break;
case R.id.btnPause:
Toast.makeText(getApplicationContext(), "Pausing song",
Toast.LENGTH_SHORT).show();
mMediaPlayer.pause();
break;
case R.id.btnStop:
Toast.makeText(getApplicationContext(), "Song stopped",
Toast.LENGTH_SHORT).show();
mMediaPlayer.reset();
mMediaPlayer = MediaPlayer.create(this,R.raw.this_is_america);
break;
}
}
Update: Turned out to be the mp3 audio file had silent pause at the beginning , tried another song and it works fine no noticeable delays , thank you greeble31 for suggesting to check that.

Your song has a silent pause at the beginning ;)
As #Lucefer mentioned, the Android platform has some small unavoidable latency due to the implementation of the audio stack. Or, at least it did a few years back, not sure what the current state of affairs is. At any rate, this delay is generally far too small (~10ms) to notice at the beginning of an audio file; it has more to do with response times for apps that simulate musical instruments and the like.

There is an audio latency issue in the Android operating system. There is a few milliseconds delay while audio recording and audio playing. You can learn more about this by navigating below URLs. And this latency is related to the device types.
https://developer.android.com/ndk/guides/audio/audio-latency
https://source.android.com/devices/audio/latency/measurements
You can use a native toolkit or native program (C, C++ ndk base) to minimize this latency. But you cannot do reduce it to 0Seconds. only minimize the latency.
There is https://superpowered.com/superpowered-android-media-server . You can get support from this but as I know you need to pay for it. I didn't try it. Therefore i don't know how much it reduced the latency.
If you want to remove silent part from your mp3. you can use ffmpeg wrapper for it. Go to https://github.com/WritingMinds/ffmpeg-android-java link there is a working ffmpeg wrapper for Android. you can easily use it.
using FFMPEG with silencedetect to remove audio silence you can find relevant FFmpeg command for it by navigating to this.
in the wrapper you don't need ffmpeg part. You need to replace it from -y. You can get those details when navigate to that wrapper

Related

MediaPlayer plays my MP3 files but really quiet

I have an old Android app, targeted for SDK16, which played my own MP3 sounds loud and clear:
MediaPlayer mp;
setVolumeControlStream(AudioManager.STREAM_MUSIC);
if (mp != null) {
mp.reset();
mp.release();
}
mp = MediaPlayer.create(this, R.raw.red_click);
mp.setVolume(1.0f, 1.0f);
mp.start();
I haven't done any Android coding for a few years, and now I started to work on my old project again, but now targeted to SDK23. I didn't change my code from the one above. Now my sounds are still playing in the app, but really really quiet.
I tried to search for an answer but couldn't find any: what has changed in MP implementation from SDL16, and how should I play my files now such that I get the full volume for them?

Android Radio App that streams my mp3 from a dropbox server

I have a dropbox media server that has a collection of mp3 files that I want to stream onto an android application.
I know that using the "MediaPlayer" is the best way to go in the API.
How my main concern is how do I automate the process, where music is being played one after another? As if it was like an internet radio app?
Could someone please point me in the correct location for guides or display example code would be great thank you in advance.
Place the music files names in an arraylist (e.g songs) then implement onCompletionListener then set it to your media player. Inside the listener restart the media player to play the next item.
myMediaPlayer.setOnCompletionListener(this);
public void onCompletion(MediaPlayer arg0) {
arg0.release();
if (counter < songs.size()) {
counter++;
arg0 = MediaPlayer.create(getApplicationContext(), songs.get(counter);
arg0.setOnCompletionListener(this);
arg0.start();
}
}
If the server gives apps audio files;put the files in a queue and play them using mediaplayer or another audio player.
Get first song from server and start playing it, meanwhile continue downloading other songs one by one.

capture audio from google recognizer intent [duplicate]

I am working on application that will record the voice of the user and save the file on the SD card and then allow the user to listen to the audio again.
I am able to allow the user to record his voice using the RecognizerIntent, but I cant figure out how to save the audio file and allow the user to hear the audio. I would appreciate it if someone could help me out. I have displayed my code below:
// Setting up the onClickListener for Audio Button
attachVoice = (Button) findViewById(R.id.AttachVoice_questionandanswer);
attachVoice.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Intent voiceIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
voiceIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
voiceIntent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Please Speak");
startActivityForResult(voiceIntent, VOICE_REQUEST);
}
});
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == VOICE_REQUEST && resultCode == RESULT_OK){
}
There is an example of how to do audio capture using MediaRecorder in the Android Developer Documentation.
I would recommend saving the files on the SD Card and then have your gallery code check the SD card to see which files to display. You can get the directory of the SD Card using the Environment.getExternalStorageDirectory() method. It would be best to save your files in a subdirectory of the SD Card root directory.
Make sure you give your applications the Permissions it will need. At the very least it will need RECORD_AUDIO and WRITE_EXTERNAL_STORAGE.
Also you have to see these tutorials:
http://www.androiddevblog.net/android/android-audio-recording-part-1
http://www.androiddevblog.net/android/android-audio-recording-part-2
If you really want to record audio via the speech recognition API then you could use the RecognitionService.Callback which has a method
void bufferReceived(byte[] buffer)
This gives you access to the recorded audio buffer as speech is being recorded and recognized. (No information is provided about the sample rate though.) You can then save the obtained buffers into a file for a later playback. I think keyboard apps use this call to display the waveform of the recorded speech. You have to implement the UI yourself.
The bare RecognizerIntent.ACTION_RECOGNIZE_SPEECH just returns a set of words/phrases without any audio.

Playing Ogg Sound in Android

In my application, I am trying to play a sound file in ogg format, stored in raw folder in res directory of my application. When I press the button that calls below function, it just freezes with the button pressed and does not respond. In the end, I have to terminate the application from Eclipse. Nothing about an error or exception in Logcat.
In debugging mode, it enters create function and never comes back. What am I doing wrong?
private void playbeep()
{
mPlayer = MediaPlayer.create(this, R.raw.beep);
mPlayer.start();
mPlayer.release();
}
You start and release the MediaPlayer at the same time. Try taking this out and see if it works.
mPlayer.release();
Also, check my post here to make sure you have the MediaPlayer set up correctly. If all else fails, try your audio file in a different format.

Android: Playing sound over Sco Bluetooth headset

For the past few days I have been trying to play any sound over my sco bluetooth headset from my android phone. My final goal with this project is to eventually make a garage door opener, but first I need to be able to play sound over the headset.
Here is the basis of the current code I'm using:
==Manifest==
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
==Code==
audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
audioManager.setMode(AudioManager.MODE_IN_CALL);
audioManager.startBluetoothSco();
audioManager.setBluetoothScoOn(true);
short[] soundData = new short [8000*20];
for (int iii = 0; iii < 20*8000; iii++) {
soundData[iii] = 32767;
iii++;
soundData[iii] = -32768;
}
audioTrack = new AudioTrack(AudioManager.STREAM_VOICE_CALL,
8000, AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT, soundData.length
* Short.SIZE, AudioTrack.MODE_STATIC);
audioTrack.write(soundData, 0, soundData.length);
audioTrack.play();
Before I run this, I pair my bluetooth headset to my phone and have it connected. I have verified it works by calling my voicemail. When I run my code however, no sound comes from anywhere.
Here are the effects of the different lines of code:
When I'm just running my app:
audioManager.setMode(AudioManager.MODE_IN_CALL);
This line makes all of my sound stop working no matter what I do, so it is typically commented out.
audioManager.startBluetoothSco();
audioManager.setBluetoothScoOn(true);
These two lines make the sound stop coming out of the front speaker and make my headset click and hiss like it's turned on but there's no output.
AudioManager.STREAM_VOICE_CALL
This is part of my call to the AudioTrack constructor, but it makes quite a difference. Since this is set to STREAM_VOICE_CALL the sound comes out of the front speaker, if I set this to STREAM_MUSIC, the sound comes out the back speaker instead.
When I open my app during a call:
audioManager.setMode(AudioManager.MODE_IN_CALL);
During a call, this line has no effect because MODE_IN_CALL was already set. But what's different however is that my sound is mixed with the phone call, whereas normally it doesn't play at all.
audioManager.startBluetoothSco();
audioManager.setBluetoothScoOn(true);
These, with their counterpart off halves, control where the audio is coming from. If I turn these off, my sound and the telephone call come from the front speaker, with these on, the telephone call comes from my headset and my sound is lost.
As to why my code is not working, I honestly have no idea. I believe I have fulfilled the checklist for using startBluetoothSco().
Even if a SCO connection is established, the following restrictions
apply on audio output streams so that they can be routed to SCO headset:
- the stream type must be STREAM_VOICE_CALL - the format must be mono -
the sampling must be 16kHz or 8kHz
So, does anyone have an idea of what I am doing wrong? There was one time that I managed to get my sound to play through the headset, but it was only a short tone when I forgot to stop() my AudioTrack so I have to assume it was a glitch.
I found the solution on this page.
You have to call audioManager.setMode(AudioManager.MODE_IN_CALL); only after the socket is connected, i.e., you received AudioManager.SCO_AUDIO_STATE_CONNECTED. I could hear the TTS on my Spica running android 2.2.2.
Edit:
Here is my (old) implementation:
public class BluetoothNotificationReceiver
extends BroadcastReceiver
{
/**
*
*/
public BluetoothNotificationReceiver(Handler h)
{
super();
bnrHandler = h;
}
/* (non-Javadoc)
* #see android.content.BroadcastReceiver#onReceive(android.content.Context, android.content.Intent)
*/
#Override
public void onReceive(Context arg0, Intent arg1)
{
String action = arg1.getAction();
if (action.equalsIgnoreCase(AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED))
{
int l_state = arg1.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -1);
Log.d("bnr", "Audio SCO: " + AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED);
switch(l_state)
{
case AudioManager.SCO_AUDIO_STATE_CONNECTED:
{
Log.i("bnr", "SCO_AUDIO_STATE_CONNECTED");
}
break;
case AudioManager.SCO_AUDIO_STATE_DISCONNECTED:
{
Log.e("bnr", "SCO_AUDIO_STATE_DISCONNECTED");
}
break;
default: Log.e("bnr", "unknown state received:"+l_state);
}
}
else
Log.e("bnr", "onReceive:action="+action);
}
}
I don't know if it is still working with the new APIs.
Try setting the audiomanager to AudioManager.MODE_NORMAL. Thos worked for me.
Add to manifest:
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH" />
I actually managed to fix this. The problem was that my pitch that I played over the headset was too high of a frequency. I fixed it by simply doubling up the code that creates the audio file so that it goes HIGH HIGH LOW LOW instead of HIGH LOW HIGH LOW.

Categories

Resources