13

Let's suppose that we have the following scenario: something is playing on an android device (an mp3 par example, but it could be anything that use the audio part of an android device). From an application (android application :) ), I would like to intercept the audio stream to analyze it, to record it, etc. From this application (let's say "the analyzer") I don't want to start an mp3 or something, all I want is to have access to the audio stream of android.

Any advice is appreciated, it could a Java or C++ solution.

user386555
  • 131
  • 1
  • 1
  • 3
  • I'm pretty sure this isn't possible unless the device has been rooted. The closes you can get is to hope the microphone is sensitive enough to pick up the output, and hope the user hasn't got earphones plugged in! – Dave Jul 08 '10 at 14:19
  • 1
    The "logical" direction to look at would be AudioManager.setRouting - http://developer.android.com/reference/android/media/AudioManager.html#setRouting(int, int, int)) . That points out two problems: one, it's deprecated in favor of specific function calls, and two, it already had a predefined, limited list of outputs. – MSalters Jul 08 '10 at 14:50
  • 1
    This is not permitted on a secured (typical consumer) device, by design, though you can get infrequent low-quality FFT's for purposes of building a graphic visualizer. To get at the actual audio from other apps, you'd need to either install your own fork of android adapted to your goals, or else "hack" an existing installation by "rooting" it and changing or intercepting system components. – Chris Stratton Feb 01 '14 at 20:28
  • @user386555 is this what you were looking for? http://stackoverflow.com/questions/3571814/accessing-the-android-media-stream-for-audio-visualization – gaurav Jun 19 '16 at 19:22

2 Answers2

1

http://developer.android.com/reference/android/media/MediaRecorder.html

    public class AudioRecorder {

    final MediaRecorder recorder = new MediaRecorder();
    final String path;

    /**
     * Creates a new audio recording at the given path (relative to root of SD
     * card).
     */
    public AudioRecorder(String path) {
        this.path = sanitizePath(path);
    }

    private String sanitizePath(String path) {
        if (!path.startsWith("/")) {
            path = "/" + path;
        }
        if (!path.contains(".")) {
            path += ".3gp";
        }
        return Environment.getExternalStorageDirectory().getAbsolutePath()
                + path;
    }

    /**
     * Starts a new recording.
     */
    public void start() throws IOException {
        String state = android.os.Environment.getExternalStorageState();
        if (!state.equals(android.os.Environment.MEDIA_MOUNTED)) {
            throw new IOException("SD Card is not mounted.  It is " + state
                    + ".");
        }

        // make sure the directory we plan to store the recording in exists
        File directory = new File(path).getParentFile();
        if (!directory.exists() && !directory.mkdirs()) {
            throw new IOException("Path to file could not be created.");
        }

        recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        recorder.setOutputFile(path);
        recorder.prepare();
        recorder.start();
    }

    /**
     * Stops a recording that has been previously started.
     */
    public void stop() throws IOException {
        recorder.stop();
        recorder.release();
    }
}
ldav1s
  • 15,885
  • 2
  • 53
  • 56
androidworkz
  • 2,902
  • 1
  • 19
  • 19
  • 5
    Thank you very much for your answer, but with your suggestion I can only access the microphone audio source. How can I access the audio stream that is sent to speaker phone or headphones when another application play a mp3 par example? Or how can I access the audio stream without limiting my options to microphone? – user386555 Jul 08 '10 at 13:23
  • 3
    Yes, I tried MediaRecorder.AudioSource.DEFAULT, but it only give me the microphone audio stream. – user386555 Jul 08 '10 at 21:20
  • I found this today... I am not sure if it will help you or not http://github.com/esnyder/callrecorder/tree/f0073c0a0aa42b64ae7bbc4a906dcae6b38cd14c Prior to API v4 the possible audio source for recording audio on the handset was limited to the microphone; in order to do call recording people resorted to putting the phone in speakerphone mode and just accepting the crappy recording quality. API v4 introduced 3 new sources: VOICE_UPLINK VOICE_DOWNLINK VOICE_CALL – androidworkz Jul 23 '10 at 17:40
  • 1
    This android-API approach is not a solution to the goal of the question, and cannot be adapted to one, because the goal is something which Android is intentionally designed *not to enable*. – Chris Stratton Feb 01 '14 at 20:32
1

Consider using the AudioPlaybackCapture API that was introduced in Android 10 if you want to get the audio stream for a particular app.

rmtheis
  • 5,992
  • 12
  • 61
  • 78