Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to shut off the sound MediaRecorder plays when the state changes

My Android application uses MediaRecorder on a SurfaceHolder to show a live preview of what the camera is capturing. Every time the user presses the REC button on the app, the app starts to record. Every time the state of the MediaRecorder switches to/from 'start', Android automatically (?) fires off a beep. This beep sounds different from phone to phone, which makes me think that this beep is natively attached to the state change of MediaRecorder. The beep is not played if the volume of the phone is set to silent.

I google it and did some research but I couldn't find a way to turn this beep off. Is it possible? If so, how?

The app was tested on: Nexus One 2.3.4, Desire HD 2.3.3

like image 857
Rafael Ramos Avatar asked Jul 24 '11 00:07

Rafael Ramos


People also ask

How do I stop recording Javascript?

In your soundAllowed(stream) function, you can stop the recording by executing stream. getTracks()[0]. stop() assuming that you only have that media track active.

What is MediaRecorder recording?

The MediaRecorder API enables you to record audio and video from a web app. It's available now in Firefox and in Chrome for Android and desktop.

What is record audio permission?

Requesting permission to record audioTo be able to record, your app must tell the user that it will access the device's audio input. You must include this permission tag in the app's manifest file: <uses-permission android:name="android.permission.RECORD_AUDIO" />


3 Answers

Ok the accepted answer did not work for me. On a Galaxy Nexus Running 4.2.1 (Jelly Bean) when recording via MediaRecorder I needed to use AudioManager.STREAM_RING because AudiManager.STREAM_SYSTEM did not work. It would always play a "chime" sound at beginning of each recording.

Here is my solution using "STREAM_RING" and others.

// disable sound when recording.
((AudioManager)activity.getApplicationContext().getSystemService(Context.AUDIO_SERVICE)).setStreamMute(AudioManager.STREAM_ALARM,true);
((AudioManager)activity.getApplicationContext().getSystemService(Context.AUDIO_SERVICE)).setStreamMute(AudioManager.STREAM_DTMF,true);
((AudioManager)activity.getApplicationContext().getSystemService(Context.AUDIO_SERVICE)).setStreamMute(AudioManager.STREAM_MUSIC,true);
((AudioManager)activity.getApplicationContext().getSystemService(Context.AUDIO_SERVICE)).setStreamMute(AudioManager.STREAM_RING,true);
((AudioManager)activity.getApplicationContext().getSystemService(Context.AUDIO_SERVICE)).setStreamMute(AudioManager.STREAM_SYSTEM,true);
((AudioManager)activity.getApplicationContext().getSystemService(Context.AUDIO_SERVICE)).setStreamMute(AudioManager.STREAM_VOICE_CALL,true);

// re-enable sound after recording.
((AudioManager)activity.getApplicationContext().getSystemService(Context.AUDIO_SERVICE)).setStreamMute(AudioManager.STREAM_ALARM,false);
((AudioManager)activity.getApplicationContext().getSystemService(Context.AUDIO_SERVICE)).setStreamMute(AudioManager.STREAM_DTMF,false);
((AudioManager)activity.getApplicationContext().getSystemService(Context.AUDIO_SERVICE)).setStreamMute(AudioManager.STREAM_MUSIC,false);
((AudioManager)activity.getApplicationContext().getSystemService(Context.AUDIO_SERVICE)).setStreamMute(AudioManager.STREAM_RING,false);
((AudioManager)activity.getApplicationContext().getSystemService(Context.AUDIO_SERVICE)).setStreamMute(AudioManager.STREAM_SYSTEM,false);
((AudioManager)activity.getApplicationContext().getSystemService(Context.AUDIO_SERVICE)).setStreamMute(AudioManager.STREAM_VOICE_CALL,false);

Also as the documentation states be sure to re-enable audio in the onPause() method.

I hope this helps someone tearing their hair out over this problem. This disables all sound streams. You can go through and work out which ones you specifically need. I found that different versions of android use different streams for the chime when mediarecorder runs. ie, STREAM_RING works for android 4.2.1 but for ICS it doesn't work.

Edit: As my comment below mentions, I can't get the sound disabled for Android OS 2.3.3 on a Samsung Galaxy S1. Anyone have luck with this?

Darrenp's solution helps to tidy up code but in a recent update to my phone (galaxy nexus android 4.3) the volume / recording beep started up again! The solution by user1944526 definitely helps. In an effort to make it easier to understand...

Use something like ,

// class variables.
Integer oldStreamVolume;
AudioManager audioMgr;


enableSound() {
        setMuteAll(false);
        if (audioMgr != null && oldStreamVolume != null) {
            audioMgr.setStreamVolume(AudioManager.STREAM_RING, oldStreamVolume, 0); 
        }
}

disableSound() {
        audioMgr = (AudioManager)activity.getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
        oldStreamVolume = audioMgr.getStreamVolume(AudioManager.STREAM_RING);
        audioMgr.setStreamVolume(AudioManager.STREAM_RING, 0, 0);       

}

For completeness each of those functions you could also call either darrenp's solution in a function or include all of the above STREAM_ lines. but for me now, these combined are working. Hope this helps someone...

like image 132
wired00 Avatar answered Oct 28 '22 05:10

wired00


try

((AudioManager)context.getSystemService(Context.AUDIO_SERVICE)).setStreamMute(AudioManager.STREAM_SYSTEM,true);

That mute all sounds.

like image 22
esse Avatar answered Oct 28 '22 06:10

esse


Following on from @wired00's answer, the code can be simplified as follows:

private void setMuteAll(boolean mute) {
    AudioManager manager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);

    int[] streams = new int[] { AudioManager.STREAM_ALARM,
        AudioManager.STREAM_DTMF, AudioManager.STREAM_MUSIC,
        AudioManager.STREAM_RING, AudioManager.STREAM_SYSTEM,
        AudioManager.STREAM_VOICE_CALL };

    for (int stream : streams)
        manager.setStreamMute(stream, mute);
}

This works fine for now but if more streams are introduced in the future, this method may need updating. A more robust approach (though perhaps overkill) is to use reflection to get all the STREAM_* static fields:

List<Integer> streams = new ArrayList<Integer>();
Field[] fields = AudioManager.class.getFields();
for (Field field : fields) {
     if (field.getName().startsWith("STREAM_")
         && Modifier.isStatic(field.getModifiers())
         && field.getType() == int.class) {
         try {
             Integer stream = (Integer) field.get(null);
             streams.add(stream);
         } catch (IllegalArgumentException e) {
              // do nothing
         } catch (IllegalAccessException e) {
             // do nothing
        }
    }
}

Interestingly, there seem to be some streams that are not documented, namely STREAM_BLUETOOTH_SCO, STREAM_SYSTEM_ENFORCED and STREAM_TTS. I'm guessing/hoping there's no harm in muting these too!

like image 36
darrenp Avatar answered Oct 28 '22 06:10

darrenp