我试图修复我的应用程序的通话录音,因为我的银河S5更新。作为一个基础,我在这里使用google项目:示例。
这是守则的主要部分:
AudioRecorder::AudioRecorder(SampleFormat *sampleFormat,SLEngineItf slEngine) :freeQueue_(nullptr),recQueue_(nullptr),devShadowQueue_(nullptr),callback_(nullptr)
SLresult result;
sampleInfo_ = *sampleFormat;
SLAndroidDataFormat_PCM_EX format_pcm;
ConvertToSLSampleFormat(&format_pcm, &sampleInfo_);
gFp = fopen("/storage/emulated/0/file.pcm", "w");
// configure audio source
SLDataLocator_IODevice loc_dev = {SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT,
SL_DEFAULTDEVICEID_AUDIOINPUT, NULL};
SLDataSource audioSrc = {&loc_dev, NULL};
// configure audio sink
SLDataLocator_AndroidSimpleBufferQueue loc_bq = {
SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,
DEVICE_SHADOW_BUFFER_QUEUE_LEN};
SLDataSink audioSnk = {&loc_bq, &format_pcm};
// create audio recorder
// (requires the RECORD_AUDIO permission)
const SLInterfaceID id[2] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
SL_IID_ANDROIDCONFIGURATION};
const SLboolean req[2] = {SL_BOOLEAN_FALSE, SL_BOOLEAN_FALSE};
result = (*slEngine)->CreateAudioRecorder(slEngine,
&recObjectItf_,
&audioSrc,
&audioSnk,
2,
id, req);
SLASSERT(result);
// Configure the voice recognition preset which has no
// signal processing for lower latency.
SLAndroidConfigurationItf inputConfig;
result = (*recObjectItf_)->GetInterface(recObjectItf_,
SL_IID_ANDROIDCONFIGURATION,
&inputConfig);
SLuint32 presetValue = SL_ANDROID_RECORDING_PRESET_VOICE_COMMUNICATION;
result = (*inputConfig)->SetConfiguration(inputConfig,
SL_ANDROID_KEY_RECORDING_PRESET,
&presetValue,
sizeof(SLint32));
SLASSERT(result);
result = (*recObjectItf_)->Realize(recObjectItf_, SL_BOOLEAN_FALSE);
SLASSERT(result);
result = (*recObjectItf_)->GetInterface(recObjectItf_, SL_IID_RECORD, &recItf_);
SLASSERT(result);
result = (*recObjectItf_)->GetInterface(recObjectItf_, SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
&recBufQueueItf_);
SLASSERT(result);
result = (*recBufQueueItf_)->RegisterCallback(recBufQueueItf_, bqRecorderCallback, this);
SLASSERT(result);
devShadowQueue_ = new AudioQueue(DEVICE_SHADOW_BUFFER_QUEUE_LEN);
assert(devShadowQueue_);这是我的问题--这段代码不记录通话的另一面,在输出文件中,我只能听到麦克风发出的声音。我试着改变参数,但结果是一样的。有人知道我做错了什么吗?
发布于 2017-09-15 11:52:05
我找到了修复Galaxy S5通话记录的解决方案。
主要是在调用启动时调用它:循环中的status_t AudioSystem::setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs)。
首先获得所需的函数:
open_media = dlopen("/system/lib/libmedia.so", RTLD_LAZY);
set_parameters = (int (*)(int, void *)) dlsym(open_media,
"_ZN7android11AudioSystem13setParametersEiRKNS_7String8E");接下来,我们需要audio_io_handle_t和String8&对象:
audio_io_handle_t-是音频会话id增加了1,您可以从AudioRecord.getAudioSessionId获得它。String8&这是比较困难的:
// create_string = (void (*)(void *,const *)) dlsym(open_util,"_ZN7android7String8C2EPKc");//下一步调用此函数将字符串转换为必需的对象create_string(&str8,str);当我们拥有所有需要的部件时,我们可以调用setParameters函数:
//remember to call this in loop when recording is starting
set_parameters(id + 1, &str8);这是变量声明的外观:
int (*set_parameters)(int, void *);
void (*create_string)(void *, const char *);
void *str8 = 0;
const char *str = "input_source=4";@ChanchalShelar
@Peter @AkshatVajpayee
以下是我的.cpp文件的外观:
void *open_media;
void *open_util;
int (*set_parameters)(int, void *);
void (*create_string)(void *, const char *);
void *str8 = 0;
const char *str = "input_source=4";
extern "C" {
JNIEXPORT bool JNICALL
Java_com_sample_NativeAudio_init(JNIEnv *env, jclass);
JNIEXPORT int JNICALL
Java_com_sample_NativeAudio_setParameters(JNIEnv *env, jclass, int id);
}
void get_string8() {
create_string = (void (*)(void *, const char *)) dlsym(open_util, "_ZN7android7String8C2EPKc");
if (!create_string) {
LOGD("There is no create_string function");
} else {
LOGD("create_string function OK");
}
create_string(&str8, str);
if (!str8) {
LOGD("Filed to create str8");
} else {
LOGD("create str8 success");
}
}
JNIEXPORT int JNICALL Java_com_sample_NativeAudio_setParameters(JNIEnv *env,
jclass type, int id) {
if (set_parameters) {
return set_parameters(id + 1, &str8);
}
return 0;
}
JNIEXPORT bool JNICALL Java_com_sample_NativeAudio_init(JNIEnv *env, jclass type) {
open_util = dlopen("/system/lib/libutils.so", RTLD_LAZY);
if (open_util) {
get_string8();
} else {
return false;
}
open_media = dlopen("/system/lib/libmedia.so", RTLD_LAZY);
if (open_media) {
set_parameters = (int (*)(int, void *)) dlsym(open_media,
"_ZN7android11AudioSystem13setParametersEiRKNS_7String8E");
} else {
return false;
}
return true;
}发布于 2017-10-18 07:03:04
你需要使用ndk。下面是需要完成的功能的示例。
负载libmedia.so和libutils.so
int load(JNIEnv *env, jobject thiz) {
void *handleLibMedia;
void *handleLibUtils;
int result = -1;
lspr func = NULL;
pthread_t newthread = (pthread_t) thiz;
handleLibMedia = dlopen("libmedia.so", RTLD_NOW | RTLD_GLOBAL);
if (handleLibMedia != NULL) {
func = dlsym(handleLibMedia, "_ZN7android11AudioSystem13setParametersEiRKNS_7String8E");
if (func != NULL) {
result = 0;
}
audioSetParameters = (lasp) func;
} else {
result = -1;
}
handleLibUtils = dlopen("libutils.so", RTLD_NOW | RTLD_GLOBAL);
if (handleLibUtils != NULL) {
fstr = dlsym(handleLibUtils, "_ZN7android7String8C2EPKc");
if (fstr == NULL) {
result = -1;
}
} else {
result = -1;
}
cmd = CM_D;
int resultTh = pthread_create(&newthread, NULL, taskAudioSetParam, NULL);
return result;}函数setParameters
int setParam(jint i, jint as) {
pthread_mutex_lock(&mt);
audioSession = (int) (as + 1);
kvp = "input_source=4";
kvps = toString8(kvp);
cmd = (int) i;
pthread_cond_signal(&cnd);
pthread_mutex_unlock(&mt);
return 0;}任务AudioSetParameters
void *taskAudioSetParam(void *threadid) {
while (1) {
pthread_mutex_lock(&mt);
if (cmd == CM_D) {
pthread_cond_wait(&cnd, &mt);
} else if (audioSetParameters != NULL) {
audioSetParameters(audioSession, kvps);
}
pthread_mutex_unlock(&mt);
}
}有一个库和一个使用https://github.com/ViktorDegtyarev/CallRecLib的示例
https://stackoverflow.com/questions/41615189
复制相似问题