Am trying to write an app that reads from the microphone and where I, in the same app, write the results/buffer myself to my own file (in a separate thread). Believe me I have Googled till my fingers were numb. But I am having a problem with the whole "callback" part.
Whether it's the onPeriodicNotification or onMarkerReached part, I just can't seem to get it right. Not looking for anyone to write it for me, but if I could just find the proper shell online, I could do it myself.
So if anyone knows of a good example, please.
Made a simple Sound Manager in which you can record sound :
public class SoundManager {
private static final String TAG = SoundManager.class.getSimpleName();
public boolean isRecording = false;
private MediaRecorder recorder;
private String audioFileName = "sound";
private Context mContext;
private String storePath;
public SoundManager(Context context) {
this.mContext = context;
}
public void onRecord(boolean toStart) {
if (toStart) {
try {
startRecording();
isRecording = true;
} catch (IOException e) {
Log.d("Tag", e.toString());
}
} else {
stopRecording();
}
}
private void startRecording() throws IOException {
stopRecording();
audioFileName = UUID.randomUUID().toString();
storePath = new File(mContext.getExternalFilesDir(null), "/images/"+ audioFileName+".3gp").getAbsolutePath();
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
recorder.setOutputFile(storePath);
recorder.prepare();
recorder.start();
}
private void stopRecording() {
if (isRecording && recorder != null) {
try {
recorder.stop();
recorder.release();
} catch (RuntimeException e) {
recorder.release();
Log.d(TAG, e.toString());
}
recorder = null;
isRecording = false;
}
}
public File getAudioOutputPath() {
return new File(storePath);
}
}
Uses:
Start Record : soundManager.onRecord(true);
Stop Record : soundManager.onRecord(false);
get sound file path : soundManager.getAudioOutputPath();
Add audio permission in your Manifest:
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
`
Related
I can only record my voice from this code, not against the turns.
And I used MediaRecorder.AudioSource.VOICE_CALL instead of MediaRecorder.AudioSource.MIC
But still I am getting my voice only.
Here is my code
public class RecorderService extends IntentService {
private Context mContext;
private MediaRecorder recorder;
static final String TAGS = "RecorderService";
private String phoneNumber;
public RecorderService() {
super("RecorderService");
}
#Override
protected void onHandleIntent(Intent intent) {
}
#Override
public int onStartCommand(#Nullable Intent intent, int flags, int startId) {
Log.e(TAGS, "Started!");
mContext = getApplicationContext();
phoneNumber = intent.getStringExtra("number");
Log.e(TAGS, "Calling Number : " + phoneNumber);
recorder = new MediaRecorder();
startRecording();
return START_NOT_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.e(TAGS, "Stopped!");
stopRecording();
}
private void startRecording() {
Log.e(TAGS, "Recording Started");
File file = new File(Environment.getExternalStorageDirectory()
+ File.separator
+ "My Records"
+ File.separator);
recorder.reset();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
recorder.setOutputFile(file.getAbsolutePath() + "record.mp3");
try {
recorder.prepare();
} catch (IOException e) {
e.printStackTrace();
}
recorder.start();
}
private void stopRecording() {
Log.e(TAGS, "Recording Stopped");
if (recorder != null) {
recorder.stop();
recorder.reset();
recorder.release();
recorder = null;
}
}
}
Any suggestions!
You can't. Not unless you're a system app (which you need to be installing your own custom OS or be root to get). VOICE_CALL requires the CAPTURE_AUDIO_OUTPUT permission which is a system permission- normal apps can't use it.
How do the other apps on the Play store do it? They use the mic, and hope the output of the call is loud enough to pick it up.
I know that some of the devices/country disable this option to recording the current phone call.
But there are more then one application on google store that make the phone call recording enable ( i know because i try more them one app on my device and its working fine ) - so this is possible mission on my device ( galaxy s7 ).
But still i wrote all the method that doing the recording action - and still i get an exception on recording and i don't know why and how to fix it.
(* recording from any other AudioSource - work fine )
The permission:
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAPTURE_AUDIO_OUTPUT"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
The code:
public class TraceActionRecording
{
private static final String AUDIO_RECORDER_FILE_EXT_3GP = ".3gp";
private static final String AUDIO_RECORDER_FILE_EXT_MP4 = ".mp4";
private static final String AUDIO_RECORDER_FOLDER = "AudioRecorder";
private MediaRecorder recorder = null;
private String fileNameGenerator()
{
// method that return unique file name ( and file path )
}
public void startRecording()
{
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL);
recorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(fileNameGenerator());
try
{
recorder.prepare();
recorder.start();
}
catch (IllegalStateException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace(); // get the exception here - exception about fail to recoding
}
}
public void stopRecording()
{
if (null != recorder)
{
recorder.stop();
recorder.reset();
recorder.release();
recorder = null;
}
}
}
I am creating a background audio recorder using Service class. When I start recording it works fine but when I stop it, it throws IllegalStateException on onStop().
Here is my Service Class Code:
public class AudioRecorderService extends Service {
MediaRecorder mAudioRecorder;
String fileName = null;
public AudioRecorderService() {
}
#Override
public void onCreate() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
setupRecorder();
Toast.makeText(this, "Recording Started", Toast.LENGTH_LONG).show();
return START_STICKY;
}
private void setupRecorder(){
fileName = Environment.getDataDirectory().getAbsolutePath() + "/" + "test.mp4";
mAudioRecorder = new MediaRecorder();
mAudioRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mAudioRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mAudioRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
mAudioRecorder.setAudioEncodingBitRate(256);
mAudioRecorder.setAudioChannels(1);
mAudioRecorder.setAudioSamplingRate(44100);
mAudioRecorder.setOutputFile(fileName);
try {
mAudioRecorder.prepare();
mAudioRecorder.start();
} catch (IOException e) {
e.printStackTrace();
}
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
if (mAudioRecorder != null) {
mAudioRecorder.stop();
mAudioRecorder.reset();
mAudioRecorder.release();
}
Toast.makeText(this, "Recording Done", Toast.LENGTH_LONG).show();
}
}
I am unable to figure out what's wrong with the code. Please can anyone help????
While starting and stopping it should be in this order. Incase of any errors notification is necessary
MediaRecorder recorder = null;
private void startRecording(File file) {
if (recorder != null) {
recorder.release();
}
recorder = new MediaRecorder();
recorder.setAudioSource(AudioSource.MIC);
recorder.setOutputFormat(OutputFormat.THREE_GPP);
recorder.setAudioEncoder(AudioEncoder.AMR_WB);
recorder.setOutputFile(file.getAbsolutePath());
try {
recorder.prepare();
recorder.start();
} catch (IOException e) {
Log.e("Error", "io problems while preparing [" +
file.getAbsolutePath() + "]: " + e.getMessage());
}
}
Now java.lang.IllegalStateException
Happens when you do not follow the order above, miss some important steps or when prepare() failed, but you continue anyway. The latter is where it is most likely to go wrong. You should only call start() when prepare() did exit without exceptions. Otherwise you will get an IllegalStateException. Since it is a RuntimeException you might not catch it and your app will force close.
While stopping follow this order
private void stopRecording() {
if (recorder != null) {
recorder.stop();
recorder.release();
recorder = null;
}
}
and last but not the lease in Manifest , the permission
<uses-permission
android:name="android.permission.RECORD_AUDIO" />
You are getting error because of mAudioRecorder.reset();
#Override
public void onDestroy() {
if (mAudioRecorder != null) {
mAudioRecorder.stop();
// here is error
mAudioRecorder.reset();
mAudioRecorder.release();
}
Toast.makeText(this, "Recording Done", Toast.LENGTH_LONG).show();
}
Update it.:
#Override
public void onDestroy() {
if (mAudioRecorder != null) {
mAudioRecorder.stop();
mAudioRecorder.release();
}
Toast.makeText(this, "Recording Done", Toast.LENGTH_LONG).show();
}
Refer official site : https://developer.android.com/guide/topics/media/audio-capture.html
I have added these 2 permissions on AndroidManifest.xml and it won't crash anymore.
P/S: The App will ask for your permission for recording the audio when upon starting it.
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
I'm starting a Service for recording voice with mice. It runs successfully because it shows notification and toast in OnCreate of service. But the control never reach on the mediaRecorder.prepare try block and it don't even show my toast in the catch block.
Here is my AudioRecorder Service
public class ServiceBgAudioRecorder extends Service {
public static boolean isRecording = false;
public static MediaRecorder mediaRecorder;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
Toast.makeText(this,"Oncreate of service",Toast.LENGTH_LONG).show();
startRecording();
}
private void startRecording() {
Notification notification = new Notification.Builder(this)
.setContentTitle("Background Audio Recorder" )
.setContentText("Audio recording is started")
.setSmallIcon(R.drawable.appicon)
.build();
startForeground(1234, notification);
mediaRecorder = new MediaRecorder();
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setOutputFile(AppUtilities.getOutputMediaFile(AppUtilities.MEDIA_TYPE_3GP).getAbsolutePath());
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
try {
mediaRecorder.prepare();
mediaRecorder.start();
Toast.makeText(this,"Audio Recording is started",Toast.LENGTH_LONG);
isRecording = true;
} catch (IOException e) {
Toast.makeText(this,"Can't start Audio Recording",Toast.LENGTH_LONG);
}
}
private void stopRecording() {
mediaRecorder.release();
mediaRecorder = null;
isRecording = false;
}
#Override
public void onDestroy() {
stopRecording();
}
}
I don't know why the control is not reaching in try/catch block.
You need to display the toast ?
append show() method to the makeText().
Toast.makeText(getActivity(),"Audio Recording is started",Toast.LENGTH_LONG).show();
I am trying to Record a Video, But It's getting crash at Media Record starts and Media Record Prepare .please Help Me... Here Is My Code...
private boolean startRecording() {
camera.unlock();
try {
mediaRecorder = new MediaRecorder();
mediaRecorder.setOnErrorListener(new MediaRecorder.OnErrorListener() {
#Override
public void onError(MediaRecorder mr, int what, int extra) {
Log.i(TAG, "Error");
}
});
second=0;
minute=0;
recordCountTimer = new CountDownTimer(Long.MAX_VALUE,1000) {
#Override
public void onTick(long millisUntilFinished) {
second++;
if(second>=60){
second=0;
minute++;
}
recordCount.setText(String.format("%02d:%02d",minute,second));
}
#Override
public void onFinish() {
finish();
}
}.start();
mediaRecorder.setCamera(camera);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
Log.d(TAG, "A");
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
Log.e(TAG, "B");
mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
defaultVideoPath= FileManger.getOutputMediaFile(MEDIA_TYPE_VIDEO).getAbsolutePath();
// uriVid = Uri.parse(FileManger.getOutputMediaFile(MEDIA_TYPE_VIDEO).getAbsolutePath());
// defaultVideoPath = getRealPathFromUri(uriVid);
mediaRecorder.setOutputFile(defaultVideoPath);
mediaRecorder.setVideoSize(recordingCameraSurface.getWidth(), recordingCameraSurface.getHeight());
mediaRecorder.setVideoFrameRate(20);
Log.v(TAG, "C");
mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());
mediaRecorder.setMaxFileSize(50000);
mediaRecorder.prepare();
Log.w(TAG, "D");
mediaRecorder.start();
Log.e(TAG, "E");
} catch (IOException e) {
releaseMediaRecorder();
return false;
}catch (IllegalStateException t){
releaseMediaRecorder();
return false;
}
return true;
}
It's giving like
RECORDER_OK﹕ B
MediaRecorder﹕ setOutputFormat called in an invalid state: 4
and Here I am Going to next Activity:
Intent intent = new Intent(RecordBuyPage.this,CheckAndSaveActivity.class);
intent.putExtra("VIDEOFILEPATH", defaultVideoPath);
startActivity(intent);
and in the next Activity i am getting the path null like:
player.setDataSource(getIntent().getStringExtra("VIDEOFILEPATH"));
I think My Order Of Calling Media Recorder Is Correct But it also getting trouble at:
mediarecoreder.prepare().
Please Give Some Valid Solution, I tried a lot From Stack overflow, but it's not working.... I think Video Is Not Recording, because when I passed it through intent it's taking null...
I hope you followed this link of sample code(Media Recorder)
https://github.com/googlesamples/android-MediaRecorder
and it has some bugs in it to record media in portrait mode so to fix this issue please follow this link
and in this link you will get your media path where it stored and you can easily pass it to another activity. Have a look I hope it helps you.
to get the path of media on stop capturing you can do this on your CaptureClick method
Log.d("Video file path", CameraHelper.getOutputMediaFile(
CameraHelper.MEDIA_TYPE_VIDEO).toString());
and complete button OnClickListener
public void onCaptureClick(View view) {
if (isRecording) {
// BEGIN_INCLUDE(stop_release_media_recorder)
// stop recording and release camera
mMediaRecorder.stop(); // stop the recording
releaseMediaRecorder(); // release the MediaRecorder object
mCamera.lock(); // take camera access back from MediaRecorder
// inform the user that recording has stopped
setCaptureButtonText("Capture");
isRecording = false;
releaseCamera();
Log.d("Video file path", CameraHelper.getOutputMediaFile(
CameraHelper.MEDIA_TYPE_VIDEO).toString());
// END_INCLUDE(stop_release_media_recorder)
} else {
// BEGIN_INCLUDE(prepare_start_media_recorder)
new MediaPrepareTask().execute(null, null, null);
// END_INCLUDE(prepare_start_media_recorder)
}
}
Please follow these two links provided above, it might solve your issue.
try this
public class VideoCapture extends Activity implements OnClickListener
,SurfaceHolder.Callback {
MediaRecorder recorder;
SurfaceHolder holder;
boolean recording = false;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
recorder = new MediaRecorder();
initRecorder();
setContentView(R.layout.main);
SurfaceView cameraView = (SurfaceView) findViewById(R.id.CameraView);
holder = cameraView.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
cameraView.setClickable(true);
cameraView.setOnClickListener(this);
}
private void initRecorder() {
recorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
CamcorderProfile cpHigh = CamcorderProfile
.get(CamcorderProfile.QUALITY_HIGH);
recorder.setProfile(cpHigh);
recorder.setOutputFile("/sdcard/videocapture_example.mp4");
recorder.setMaxDuration(50000); // 50 seconds
recorder.setMaxFileSize(5000000); // Approximately 5 megabytes
}
private void prepareRecorder() {
recorder.setPreviewDisplay(holder.getSurface());
try {
recorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
finish();
} catch (IOException e) {
e.printStackTrace();
finish();
}
}
public void onClick(View v) {
if (recording) {
recorder.stop();
recording = false;
// Let's initRecorder so we can record again
initRecorder();
prepareRecorder();
} else {
recording = true;
recorder.start();
}
}
public void surfaceCreated(SurfaceHolder holder) {
prepareRecorder();
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
public void surfaceDestroyed(SurfaceHolder holder) {
if (recording) {
recorder.stop();
recording = false;
}
recorder.release();
finish();
}
}
Include Permissions in Manifest file :
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />