我正在开发一个可以在Android中录制通话的应用程序。我已经阅读了很多讨论呼叫录音问题的主题。我知道并非所有Android手机都可以录制通话。但我想知道如何在Play Market上录制最受欢迎的应用程序,例如https://play.google.com/store/apps/details?id=com.appstar.callrecorder或https://play.google.com/store/apps/details?id=polis.app.callrecorder。我认为你不是在MediaRecorder课上使用它来完成这项工作,而是还有别的东西。因为我已经开发了自己的应用程序,但我只能录制我的声音。但是这两个应用程序正在记录我的声音和我呼唤的男人的声音。他们是怎么做到的?我知道我们无法访问设备扬声器来录制声音。你能给我一些关于如何录制语音电话的想法吗?这是我在我的应用程序中使用的代码:
public class CallRecorderService extends Service {
private MediaRecorder mRecorder;
private boolean isRecording = false;
private PhoneStateListener phoneStateListener = new PhoneStateListener() {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
switch (state) {
case TelephonyManager.CALL_STATE_IDLE:
stopRecording();
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
startRecording(incomingNumber);
break;
case TelephonyManager.CALL_STATE_RINGING:
break;
default:
break;
}
}
};
@Override
public void onCreate() {
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
super.onCreate();
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
private void startRecording(String number) {
try {
String savePath = Environment.getExternalStorageDirectory().getAbsolutePath();
savePath += "/Recorded";
File file = new File(savePath);
if (!file.exists()) {
file.mkdir();
}
savePath += "/record_" + System.currentTimeMillis() + ".amr";
mRecorder = new MediaRecorder();
SharedPreferences sPrefs = getSharedPreferences(Constants.PREFERENCES_NAME, Context.MODE_PRIVATE);
int inputSource = sPrefs.getInt(Constants.SOURCE_INPUT, Constants.SOURCE_VOICE_CALL);
int outputSource = sPrefs.getInt(Constants.SOURCE_OUTPUT, Constants.OUTPUT_MPEG4);
switch (inputSource) {
case Constants.SOURCE_MIC:
increaseSpeakerVolume();
break;
}
mRecorder.setAudioSource(inputSource);
mRecorder.setOutputFormat(outputSource);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mRecorder.setOutputFile(savePath);
mRecorder.prepare();
mRecorder.start();
isRecording = true;
} catch (Exception ex) {
ex.printStackTrace();
}
}
private void stopRecording(){
if (isRecording) {
isRecording = false;
mRecorder.stop();
mRecorder.release();
}
}
private void increaseSpeakerVolume(){
AudioManager audio = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
audio.adjustStreamVolume(AudioManager.STREAM_VOICE_CALL,
AudioManager.ADJUST_RAISE,
AudioManager.FLAG_SHOW_UI);
}
}
答案 0 :(得分:1)
我认为他们确实使用了MediaRecorder。也许它的主要问题在于,将数据从其中写入其他东西而不是本地存储上的文件是很棘手的。为了解决它,你可以创建一个管道。然后使用其文件描述符作为MediaRecorder的输入fd。然后管道输出可以由一些线程控制,该线程将读取音频包(格式,aac或..甚至wav中的一种),然后随意对数据做任何事情。
这是一些代码。注意,这是一个原型,可能甚至不能编译,只是为了给你一个想法。
/* 2M buffer should be enough. */
private final static int SOCKET_BUF_SIZE = 2 * 1024 * 1000;
private void openSockets() throws IOException {
receiver = new LocalSocket();
receiver.connect(new LocalSocketAddress("com.companyname.media-" + socketId));
receiver.setReceiveBufferSize(SOCKET_BUF_SIZE);
sender = lss.accept();
sender.setSendBufferSize(SOCKET_BUF_SIZE);
}
private void closeSockets() {
try {
if (sender != null) {
sender.close();
sender = null;
}
if (receiver != null) {
receiver.close();
receiver = null;
}
} catch (Exception ignore) {
}
}
public void prepare() throws IllegalStateException, IOException {
int samplingRate;
openSockets();
if (mode == MODE_TESTING) {
samplingRate = requestedSamplingRate;
} else {
samplingRate = actualSamplingRate;
}
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
try {
Field name = MediaRecorder.OutputFormat.class.getField("AAC_ADTS");
if (BuildConfig.DEBUG)
Log.d(StreamingApp.TAG, "AAC ADTS seems to be supported: AAC_ADTS=" + name.getInt(null));
mediaRecorder.setOutputFormat(name.getInt(null));
} catch (Exception e) {
throw new IOException("AAC is not supported.");
}
try {
mediaRecorder.setMaxDuration(-1);
mediaRecorder.setMaxFileSize(Integer.MAX_VALUE);
} catch (RuntimeException e) {
Log.e(StreamingApp.TAG, "setMaxDuration or setMaxFileSize failed!");
}
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
mediaRecorder.setAudioChannels(1);
mediaRecorder.setAudioSamplingRate(samplingRate);
mediaRecorder.setOutputFile(sender.getFileDescriptor());
startListenThread(receiver.getInputStream());
mediaRecorder.start();
}