Call recording - make it work on Nexus 5X (rooting or custom ROM possible)
Asked Answered
C

1

35

I'm attempting to use AudioRecord with AudioSource.VOICE_DOWNLINK on Nexus 5X, Android 7.1 (my own build from AOSP).

I'm already past the permissions stage - moved my APK to privileged apps, made an adjustment to AudioRecord in Android source to stop throwing an exception about this source.

Now I'm getting empty recording buffers during a phone call.

I know that there are a lot of call recording apps, and they work on other devices. I've also seen certain apps that can perform some hack on a rooted N5 and make it work.

I wish to achieve the same on Nexus 5X - ANY adjustment is OK for me, including changing Android version, modifying Qualcomm drivers, device configuration files, etc. - basically anything that can be achieved in a custom ROM.

I've tried messing around with platform code - hardware/qcom/audio/hal/voice.c, especially the function voice_check_and_set_incall_rec_usecase, but could not make sense out of it so far.

Also checked device/lge/bullhead/mixer_paths.xml, found there's a section related to call recording:

<!-- Incall Recording -->
<ctl name="MultiMedia1 Mixer VOC_REC_UL" value="0" />
<ctl name="MultiMedia1 Mixer VOC_REC_DL" value="0" />
<ctl name="MultiMedia8 Mixer VOC_REC_UL" value="0" />
<ctl name="MultiMedia8 Mixer VOC_REC_DL" value="0" />
<!-- Incall Recording End -->

But I also couldn't make sense out of it or how it can be helped.

Centrifugal answered 6/5, 2017 at 9:15 Comment(5)
Are you getting any expection?Camilacamile
try putting audioRecoder.record() in a try catch and check . Also post your recording code a bit.Camilacamile
There is no crash, so there is no point in try-catch.Centrifugal
the SLIMbus℠ "Serial Low-Power Inter-Chip Media Bus" is being used. the only way to get access to that audio stream is to change the way the ALSA mixer assigns the audio paths. newer versions of Android now have Incoming Call Options > Record call (4) (press and hold key 4?); however the SDK does not provide access to any of that. developer.android.com/guide/topics/media/mediaplayer.html ...explains it (per default, one can only playback trough the default audio device).Trigger
Hi Martin, I don't need the SDK - modifying AOSP is OK for me. Do you have any idea how to do what you said for Nexus 5X?Centrifugal
B
1

Not sure if it is a Nexus 5 specific issue but usually the class used to record calls is MediaRecorder. Have you tried to replace AudioRecorder by a MediaRecorder?

Based on this stack-overflow question, I think you could try the following code based on Ben blog post:

import android.media.MediaRecorder;
import android.os.Environment;

import java.io.File;

import java.io.IOException;


public class CallRecorder {

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

    /**
     * Creates a new audio recording at the given path (relative to root of SD card).
     */
    public CallRecorder(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.VOICE_CALL);
        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();
    }

}

In this sample, I've used MediaRecorder.AudioSource.VOICE_CALL but you can test other options like MediaRecorder.AudioSource.VOICE_COMMUNICATION and also the microphone just to see if there are any hardware issues on your phone.

Bandstand answered 24/5, 2017 at 15:50 Comment(4)
I need to use AudioRecord to record in real time.Centrifugal
Now I'm getting empty recording buffers during a phone call - is it because both AudioRecorder and call using the same channel???? have u tried listening to some different sources, like putting the call on speaker and then tryLaurinelaurita
I am not interested in putting the call on speaker, I need to record the call properly from AudioSource.VOICE_CALL.Centrifugal
I see. So maybe you could share you code and it would be easier to see whats going on. AudioRecorder is not so common as MediaRecorder but there is a nice sample here - note that you need to run it in a separated thread: newventuresoftware.com/blog/…Bandstand

© 2022 - 2024 — McMap. All rights reserved.