How can I create a microphone app on Android? - android

I want to create a microphone app on Android that will receive sound through the microphone and play through the speakerphone but I don't know exactly what classes and services I should use.

The core of your answer is to:
A) record and store, as stated here.
MediaRecorder recorder = new MediaRecorder();
String status = Environment.getExternalStorageState();
if(status.equals("mounted")){
String path = Environment.getExternalStorageDirectory().toString()+"/YOURFOLDER"; // your custom path
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); // notice that this is the audio format, and you might want to change it to [other available audio formats][2]
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(path);
recorder.prepare();
// To start recording
recorder.start();
// To stop recording
recorder.stop();
recorder.release();
} else {
// Handle the situation
}
[Other available audio formats | 2]
B) Get recordings, as stated partially here. You should then show them.
try {
String path = Environment.getExternalStorageDirectory().toString()+"/YOURFOLDER"; // your custom path
File directory = new File(path);
File[] files = directory.listFiles();
} catch {
// Handle errors (or maybe no files in the directory)
}
C) Play recordings, as stated partially here.
MediaPlayer mp = new MediaPlayer();
mp.setDataSource(Environment.getExternalStorageDirectory().toString()+"/YOURFOLDER"+"/yourfilename.formatextension"; // your custom pathare to use the file format and directory you used when saving
mp.prepare();
mp.start();
Hope this answer helps!

Related

Android - record sound and check sound volume

I am trying to find out if my device is recording audio correctly (Volume of recorded audio is not too low and actually the recorded file has sound). The way I tried doing it is:
start recording --> play sound --> stop recording --> get file recorded max volume
The code I used to record sound:
public void playSound() {
File myDataPath = new File(getActivity().getFilesDir().getAbsolutePath()
+ File.separator + ".CheckAudio");
if (!myDataPath.exists())
myDataPath.mkdirs();
recordFile = myDataPath + File.separator + "Recording_" + new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date()) + ".mp3";
am.setStreamVolume(AudioManager.STREAM_RING, am.getStreamMaxVolume(AudioManager.STREAM_RING), 0);
am.setStreamVolume(AudioManager.STREAM_NOTIFICATION, am.getStreamMaxVolume(AudioManager.STREAM_NOTIFICATION), 0);
Uri defaultRingtoneUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
try {
md = new MediaRecorder();
md.setAudioSource(MediaRecorder.AudioSource.MIC);
md.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
md.setOutputFile(recordFile);
md.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
md.prepare();
md.start();
} catch (IllegalStateException | IOException e) {
recording = false;
removeItem("Unable to record audio, please try again."); // (Show toast)
return;
}
mediaPlayer = new MediaPlayer();
try {
mediaPlayer.setDataSource(getActivity(), defaultRingtoneUri);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_NOTIFICATION);
mediaPlayer.prepare();
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
md.stop();
md.release();
mediaPlayer.release();
mediaPlayer = null;
// get recordfile volume
}
});
mediaPlayer.start();
} catch (IOException e) {
e.printStackTrace();
removeItem("Unable to play audio");
sound = false;
}
}
However, I can't find out how to analyze the mp3 file created and check if it is not empty (from sound), is there a library or another way?
I hope you guys understood what I am trying to achieve as my English is pretty bad, Thanks.
EDIT:(Some more explaination)
If you play sound (ringtone or something) while recording sound from microphone, the decibels recorded should be around 90 decibels. meaning the sound playing working and also the microphone, but if the decibels recorded around 30 means only microphone is working, and playing sound not, if the decibels are around zero then the microphone is not working.
You can use a visualiser to visualise real time if recording sound is getting too low or too loud.
I have build a project which visualise recording sound strength via bar graph . Higher the bar louder the recorded sound lower the bar low decibels .
This project also have inapp player which allow user to play all his recordings. The inbuilt player also visualise playback sound data.
I am suggesting this because I thought this is what you are trying to achieve in
start recording --> play sound --> stop recording --> get file recorded max volume.
Instead of getting max volume each time you can rely on visualiser to keep an eye on recorder if recording file is getting recorded above acceptable decibals.
You can find source code on github
https://github.com/hiteshsahu/Android-Audio-Recorder-Visualization-Master

Illegal State Exception on Media Recorder

I want to use Media Recorder to record and save an audio file to the sd card. The debugger has shown that the line recorder.start() raises an IllegalStateException. The code is taken from the android dev website and the only change is to the file name and path.
When I reach the error in the debugging menu, I am shown the View class which says:
Source not found.
The source attachment does not contain the source for the file View.class.
You can change the source attachment by clicking Change Attached Source below:
canRecord is a boolean set initially to true, which dictates which method is called in an onClick function. That functionality is working.
#SuppressLint("SimpleDateFormat")
private void record(){
SimpleDateFormat timeStampFormat = new SimpleDateFormat("MM/dd/yyyy");
String audio_path = Environment.getExternalStorageDirectory() + "/resources/resources/WI1/";
String fileName = username +"-"+ timeStampFormat.format(new Date())+".mp4";
audio_button.setText("Recording");
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setOutputFile(audio_path+fileName);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
try {
recorder.prepare();
} catch (IOException e) {
Toast.makeText(this, "Can't record audio at this time", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
canRecord = false;
recorder.start();
} // record
This is the stop recording function, although it has never reached this point.
private void stopRecording(){
audio_button.setText("Attach Audio");
recorder.stop();
recorder.release();
}
Finally, I have added the following permissions to the manifest:
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
How can I solve this? Thanks!
May be there is problem in filename you are giving to the recorder.Try this:
String audio_path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/resources/resources/WI1/";
String fileName = audiopath+"-"+ timeStampFormat.format(new Date())+".mp4";
May it helps..
I am using libgdx(multiplatform open source game engine) and i had a similar problem when i was trying to use androids code instead of the libgdx code for recording.Turned out i needed to dispose of my libgdx recorder code or just delete it all.So perhaps you have another recorder interfering somewhere

How to Store the Recorded Audio Files in a Folder

Can anyone please explain how to store the recorded Audio files in a separate folder?
I am using default recorder for recording audio files
Intent = new Intent (MediaStore.Audio.Media.RECORD_SOUND_ACTION);
startActivityForResult(intent, 2);
and I am getting the absolute audio path:
absolutepath audiopath is : /mnt/sdcard/recording1225555579.3gpp
You can try by specifying the path yourself.
private void beginrec() throws IllegalStateException, IOException{
ditchMediaRecorder();
recorder=new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile("/sdcard/voice/"); //like this
recorder.prepare();
recorder.start();
}

Android Record Audio issue

I found the code to record audio, but I always get:
The method setOutputFile(FileDescriptor) in the type MediaRecorder is not applicable for the arguments (Uri)
So how would I need to describe the filepath that it works?
// Prepare recorder source and type
MediaRecorder recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
// File to which audio should be recorded
File outputFile = getFileStreamPath("output.amr");
Uri target = Uri.parse(outputFile.getAbsolutePath());
recorder.setOutputFile(target);
// Get ready!
recorder.prepare();
// Start recording
recorder.start();
// Stop and tidy up
recorder.stop();
recorder.release();
You're trying to pass in an Uri as parameter to the method which doesn't expect that.
Just replace recorder.setOutputFile(target) with:
recorder.setOutputFile(outputFile.getAbsolutePath());
That should work since string parameter is allowed.

Streaming AAC audio with Android

As I understand it, Android will only play AAC format audio if it's encoded as MPEG-4 or 3GPP.
I'm able to play AAC audio encoded as M4A when it's local to the app, but it fails when obtaining it from a server.
The following works, as the m4a file is held locally in the res/raw directory.
MediaPlayer mp = MediaPlayer.create(this, R.raw.*file*);
mp.start();
The following doesn't work. (But does with MP3's).
Uri uri = Uri.parse("http://*example.com*/blah.m4a");
MediaPlayer mp = MediaPlayer.create(this, uri);
mp.start();
Can anyone shed any light on why it fails when the m4a audio file is not local?
Here's (some of) the error...
ERROR/PlayerDriver(542): Command PLAYER_INIT completed with an error or info UNKNOWN PVMFStatus
ERROR/MediaPlayer(769): error (200, -32)
WARN/PlayerDriver(542): PVMFInfoErrorHandlingComplete
DEBUG/MediaPlayer(769): create failed:
DEBUG/MediaPlayer(769): java.io.IOException: Prepare failed.: status=0xC8
DEBUG/MediaPlayer(769): at android.media.MediaPlayer.prepare(Native Method)
DEBUG/MediaPlayer(769): at android.media.MediaPlayer.create(MediaPlayer.java:530)
DEBUG/MediaPlayer(769): at android.media.MediaPlayer.create(MediaPlayer.java:507)
...
I'm targeting SDK 1.6.
This work-around allows you to play M4A files from the net (and AAC files in other containers such as MP4 & 3GP). It simply downloads the file and plays from the cache.
private File mediaFile;
private void playAudio(String mediaUrl) {
try {
URLConnection cn = new URL(mediaUrl).openConnection();
InputStream is = cn.getInputStream();
// create file to store audio
mediaFile = new File(this.getCacheDir(),"mediafile");
FileOutputStream fos = new FileOutputStream(mediaFile);
byte buf[] = new byte[16 * 1024];
Log.i("FileOutputStream", "Download");
// write to file until complete
do {
int numread = is.read(buf);
if (numread <= 0)
break;
fos.write(buf, 0, numread);
} while (true);
fos.flush();
fos.close();
Log.i("FileOutputStream", "Saved");
MediaPlayer mp = new MediaPlayer();
// create listener to tidy up after playback complete
MediaPlayer.OnCompletionListener listener = new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
// free up media player
mp.release();
Log.i("MediaPlayer.OnCompletionListener", "MediaPlayer Released");
}
};
mp.setOnCompletionListener(listener);
FileInputStream fis = new FileInputStream(mediaFile);
// set mediaplayer data source to file descriptor of input stream
mp.setDataSource(fis.getFD());
mp.prepare();
Log.i("MediaPlayer", "Start Player");
mp.start();
} catch (Exception e) {
e.printStackTrace();
}
}
I tried it too but I could not find out the solution!
At the last Google I/O I saw something that helped me a lot. It is Extending from MediaPlayer and improve a lot of things! Take a look.
EXOPLAYER CAN HELP YOU A LOT
Check this part of the example:
private static final int BUFFER_SEGMENT_SIZE = 64 * 1024;
private static final int BUFFER_SEGMENT_COUNT = 256;
...
// String with the url of the radio you want to play
String url = getRadioUrl();
Uri radioUri = Uri.parse(url);
// Settings for exoPlayer
Allocator allocator = new DefaultAllocator(BUFFER_SEGMENT_SIZE);
String userAgent = Util.getUserAgent(context, "ExoPlayerDemo");
DataSource dataSource = new DefaultUriDataSource(context, null, userAgent);
ExtractorSampleSource sampleSource = new ExtractorSampleSource(
radioUri, dataSource, allocator, BUFFER_SEGMENT_SIZE * BUFFER_SEGMENT_COUNT);
audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource);
// Prepare ExoPlayer
exoPlayer.prepare(audioRenderer);
EXOPLAYER- I can play anything from streamings (video and audio)!
LET ME KNOW IF YOU NEED HELP TO IMPLEMENT IT! :)
This is a wild shot in the dark, but I have seen similar behavior with the flash player where it actually ignores the file name and only relies on the MIME type sent by the server. Any idea what headers are being sent down from example.com? You might want to try wrapping your blah.m4a in a page that can set the headers and then stream the binary data. Give these types a shot and the community would appreciate a confirmation of what works:
audio/mpeg
audio/mp4a
audio/mp4a-latm
audio/aac
audio/x-aac
I found that if you record the audio file on Android with the following properties, you are then able to play it on your server. It also plays well in the HTML Audio Element, however only on Firefox at the moment. This may change in the future.
Android (JAVA):
mediaRecorder = new MediaRecorder();
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.HE_AAC);
mediaRecorder.setAudioSamplingRate(44100);
mediaRecorder.setAudioChannels(1);
mediaRecorder.setOutputFile(filePath);
HTML:
<audio id="audioMediaControl" controls src="yourfile.m4a"> Your browser does not support the audio element. </audio>
try --
1) MP.prepareAsync()
2) onPrepared() { mp.start() }

Categories

Resources